CodeReady Workspacesをカスタマイズして便利に開発してみよう その2

みなさんこんにちは、レッドハットでソリューションアーキテクトをしている暮林といいます。

CodeReady Workspacesの便利なカスタマイズ方法の第二回目のご紹介です。

第一回目はこちら。 rheb.hatenablog.com

今回のテーマはワークスペースの標準化です。

CodeReadyWork 2.8 変更点

標準化のお話に入る前に、CodeReadyWorkspaces2.8がGAしいくつかアップデートがあったため変更点についてご紹介しようと思います。

下記のリンクが変更点の一覧です。(要ログイン)

access.redhat.com

注目すべき変更点

  1. 新しいCodeReady Workspacesのダッシュボード
  2. ダッシュボードを使用したプライベートリポジトリーからのファクトリのOpenShift OAuthフローのサポート
  3. ファクトリーURLを簡略化
  4. devfileを使わずにスタートしたワークスペースに対するプラグインの自動リコメンデーション
  5. Lombokプロジェクトのサポート
  6. VS Code エクステンションのサイドカーファイルシステムへのアクセスへのサポート
  7. Devfileからシングルルートモードとマルチルートモードを切り替え可能に
  8. 制限されたIBM Z環境におけるインストールのサポート

個人的に注目すべき点は太字で強調したマルチルートモードの切り替えが追加された点です。 マルチルートモードというのはエディタから複数のフォルダを開いた状態のことををいいます。

VSCodeエクステンションの多くはマルチルートモードを必要としますが、デフォルトでCodeReadyWorkspacesはシングルルートモードで起動します。これをdevfileから切り替えられるようにしたというものです。利用できるVSCodeプラグインが増えてより便利になりそうですね。

CodeReadyWorkspacesのレジストリについて理解する

CodeReadyWorkspacesには2つのレジストリがありそれぞれ役割が異なります。

devfileレジストリー

ワークスペースのテンプレートを保管しておくレジストリーです。 第一回では自分用のdevfileを修正してコンテナを追加しましたが、修正済みのdevfileをレジストリーに登録しておくことでほかのユーザーも同じスタック(設定のようなもの)でワークスペースを起動できるようになります。下記の画像はデフォルトのスタック一覧ですが、devfileレジストリーを変更することでここの一覧を変更できます。

f:id:Tatsuyak9i:20210519104207p:plain
デフォルトのスタック一覧

プラグインレジストリー

デスクトップ版のVSCodeは自由にエクステンションをダウンロードして追加することができますが、CodeReadyWorkspacesでは利用したいプラグインをプラグインレジストリーに保管しておいて、これをdevfile経由で指定することで利用することができるようになります。2.8ではUIが変更されて、下記のようにワークスペース内のUIからプラグインを指定できるようになりました。プラグインレジストリーを変更することで、下記の画像の左側にあるプラグイン一覧に表示されるプラグインを変更することができます。

f:id:Tatsuyak9i:20210519104729p:plain
プラグイン一覧

今回はdevfileレジストリーのカスタマイズ方法を実際に試していきます。 (プラグインレジストリーの方が興味がある方多いかもしれませんが、次回にご期待ください!)

前提

第一回のしばりのまま行きたいところですが、CodeReadyWorkspacesのインスタンスに対する変更とレジストリのビルドが必要なため、下記のような条件が必要となります。 標準化担当は一般開発者に比べて強い権限が必要です。

  1. openshiftプロジェクトへの変更権限
  2. CodeReadyWorkspacesのインスタンスへの変更権限
  3. OpenShift ImageRegistry Operatorの変更権限
  4. podman(またはdockerかbuildah)が実行可能なラップトップ(またはサーバーなど)

1~3は実質cluster-adminが必要ということです。 この中で若干厳しいのはpodmanの実行環境だと思います。podmanはレジストリーイメージの構築に利用します。 実はdevfileレジストリーだけであればOpenShiftのビルド機能を使うことでなんとか逃れられるのですが、プラグインレジストリーではさらにnpmとnodejsを必要とするのでOpenShiftのビルド機能ではかなり苦しくなります。

プラグインレジストリーのビルドのためにも、レジストリービルド用の仮想マシンのようなもを準備しておくことをお勧めします。ビルドだけなので使い捨てでも構いません。

レジストリーのカスタマイズの公式のマニュアルは下記のページにあります。

access.redhat.com

STEP1 ワークスペース内で動かすイメージの準備

レジストリのカスタマイズの前提としては、第一回でご紹介したようにワークスペースにあたらしいコンテナを追加したいというケースを想定します。 なおかつ準備したもの以外の選択肢を削除するものとします。これから作成するdevfileだけを選択可能にするということです。標準化の第一歩です。

OpenShiftの内部レジストリはアクセス制限がかかっていますが、「openshift」というproject(namespace)に登録されているイメージは、クラスター内からなら自由に使えます。 ということで、前回の手順をopenshift projectの中で実施してイメージを作成しておいてください。

STEP2 カスタマイズするdevfileの準備

この辺りは公式手順のままですが、cloneのプロトコルgit(ssh)のままだと困る方が多いと思うので、httpに変えた手順をのせておきます。

git clone https://github.com/redhat-developer/codeready-workspaces.git
cd codeready-workspaces
git checkout crw-2.8-rhel-8

ここでデフォルトの中身を少しのぞいてみましょう。 dependencies/che-devfile-registry/devfiles/の中を覗いてみると、どうやらワークスペースを選択するときの一覧に対応していそうなディレクトリがみえます。

ls -l dependencies/che-devfile-registry/devfiles/
total 0
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java11-maven-microprofile-bootable
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java11-maven-microprofile-xp2
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 00_java8-maven-eap
drwxrwxr-x. 2 ec2-user ec2-user 97 May 10 04:54 02_java8-maven-fuse
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_camelk
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-gradle
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-lombok
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-quarkus
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-vertx
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java11-maven-vertx-http-booster
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 03_java8-maven-spring-boot-http-booster
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-configmap
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-mongo
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 04_nodejs-simple
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_cpp
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_dotnet
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_go
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_php-cake
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_php-di
drwxrwxr-x. 2 ec2-user ec2-user 43 May 10 04:54 05_python

カスタマイズ元は 03_java11-maven-quarkus になります。これ以外をどけてしまいます。

cd dependencies/che-devfile-registry/
mv devfiles devfiles_old
mkdir  devfiles_old/03_java11-maven-quarkus/ devfiles/

あとはdevfile.yamlをカスタマイズします。第一回で紹介した方法と同じですが、コンテナイメージを置いているプロジェクトがopenshiftにかわっていることに注意してください。

  - mountSources: true
    command:
      - tail
    args:
      - '-f'
      - /dev/null
    memoryLimit: 512Mi
    type: dockerimage
    alias: toolbox
    image: 'image-registry.openshift-image-registry.svc:5000/openshift/my-toolbox'

STEP3 devfileレジストリーのビルドとプッシュ

いよいよビルドですが、ビルドしたイメージをOpenShiftの内部レジストリにプッシュするために、内部レジストリをクラスターの外に公開しないといけません。 (docker.ioやquai.ioや別のプライベートリポジトリに公開してから内部レジストリにimportする手もあります)

手順は下記のマニュアルそのままです。

access.redhat.com

前提に書いたとおりのcluster-adminに近い権限を持ったユーザーでcliからOpenShiftクラスターにログインしておいてください。 そのあとは、公式マニュアルの通りpodman loginまで実行してください。Operatorにoc patchしてからrouteが作成されてまで少しかかるので注意してください。

oc login ~~~~
oc patch configs.imageregistry.operator.openshift.io/cluster --patch '{"spec":{"defaultRoute":true}}' --type=merge
HOST=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
podman login -u $(oc whoami) -p $(oc whoami -t) --tls-verify=false $HOST

podmanビルドをするスクリプトを実行します。 --organizationにあたるところが、次の手順でプッシュする時のプロジェクト名にあたるので、CodeReadyWorkspaces本体が動いているプロジェクト名を指定しておきます。

 ./build.sh --organization openshift-workspaces \
           --registry $HOST \
           --tag 1.0

STEP 38: COMMIT default-route-openshift-image-registry.apps.xxxxxxxxxxx/openshift-workspaces/devfileregistry-rhel8:1.0

~~~


ビルドが成功したらイメージをプッシュします。 プッシュするイメージ名は、STEP38で出力されたものを使います。

podman push default-route-openshift-image-registry.apps.xxxxxxxxxxx/openshift-workspaces/devfileregistry-rhel8:1.0

Getting image source signatures
Copying blob 54a71df94483 skipped: already exists
Copying blob 27567a77cb0c skipped: already exists
Copying blob 123257361dae skipped: already exists
Copying blob dce1930497b5 skipped: already exists
Copying blob 17b23f8c2a0f skipped: already exists
Copying blob c9e02f9d3afe skipped: already exists
Copying blob 5756f433aebc skipped: already exists
Copying blob 373b8d0281c1 skipped: already exists
Copying blob bdabcafc9438 skipped: already exists
Copying blob 121b74199690 skipped: already exists
Copying blob 780fcde908cf skipped: already exists
Copying blob 9f39e0b6c7e2 skipped: already exists
Copying blob 946d7c6db7ba [--------------------------------------] 0.0b / 0.0b
Copying config 897558c499 done
Writing manifest to image destination
Storing signatures

STEP4 カスタムdevfileレジストリーの起動

公式手順ではcliから oc new-app していますが、あえてGUIからやってみましょう。 DeveloperViewから+追加を選んでコンテナーイメージを選びます。

f:id:Tatsuyak9i:20210519154104p:plain
コンテナーイメージを選択

イメージのところで「Image stream tag from internal registry」を選択すると先ほどプッシュしたイメージが選択できるはずです。 リソースはDeploymentのままでもかまいませんが、DeploymentConfigの方が若干便利で個人的には好きです。(ロールアウト操作がある)

f:id:Tatsuyak9i:20210519154208p:plain
設定

ルーティングの設定はセキュアにしておいたほうがよいでしょう。

f:id:Tatsuyak9i:20210519154937p:plain

DeveloperViewにもどったら起動したアプリケーションの右上の矢印を押して、動作確認とURLのメモを行いましょう。 動作確認としては白地のテキストが画面が出力されればOKでしょう。

f:id:Tatsuyak9i:20210519154553p:plain

STEP5 CodeReadyWorkspacesのインスタンスの設定変更

ここまで来たらもう少しです。 Operatorからたどっていって、CodeReadyWorkspacesのインスタンスの設定を書き換えます。

f:id:Tatsuyak9i:20210519155452p:plain

f:id:Tatsuyak9i:20210519155548p:plain

serverセクションの後ろにcustomChePropertiesセクションを加えます。 その中に「CHE_WORKSPACE_DEVFILEREGISTRYINTERNALURL」と「CHE_WORKSPACE_DEVFILEREGISTRY__URL」を追加し先ほどメモしたURLを設定します。

f:id:Tatsuyak9i:20210519162321p:plain

  server:
    cheLogLevel: INFO
    customCheProperties:
      CHE_LIMITS_USER_WORKSPACES_RUN_COUNT: '5'
      CHE_LIMITS_WORKSPACE_IDLE_TIMEOUT: '-1'
      CHE_WORKSPACE_DEVFILE__REGISTRY__INTERNAL__URL: 'https://devfileregistry-rhel8-openshift-workspaces.xxxxxxxxxxxxxx'
      CHE_WORKSPACE_DEVFILE__REGISTRY__URL: 'https://devfileregistry-rhel8-openshift-workspaces.xxxxxxxxxxxxxx'

ちなみにここで設定している「CHE_LIMITS_USER_WORKSPACES_RUN_COUNT」はユーザー当たり起動できるワークスペース数で、「CHE_LIMITS_WORKSPACE_IDLE_TIMEOUT」はアイドルタイムアウトでワークスペースが終了されるまでのリミット時間です。割と最初にユーザーから文句が出る箇所だと思いますが、気軽に増やすとクラスターのリソースがすぐなくなってしまうので、よく考えた方がよいかと思います。

この設定を終えればあとはOperatorが勝手にConfigMapの書き換えと、CodeReadyWorkspacesの再起動をしてくれます。 公式の手順では直接ConfigMapを更新していますがおそらくこれはUpstreamのEclipse cheの手順がそのままになっているように思います。試しにやってみたとろ、秒でOperatorさんにもとに戻されました…。

再度CodeReadyWorkspacesのURLを開きなおすと、このようにすっきりしていると思います。 f:id:Tatsuyak9i:20210519163105p:plain

まとめ

ここまでいかがだったでしょうか。なかなかヘビーな手順です。 しかし一度やってしてしまえば二度目からはさほど難しくはありません。

こうなってくるアイコンやディスクリプションも書き換えたくなりませんか。 devfileをもっとカスタマイズして、オンボーディング資料格納したGitリポジトリを指定しておけば、CodeReadyWorkspacesへの初回ログインからメンバーの本格参画までがスムーズになりそうですね。

標準化というのは人を縛る(低い方に合わせる)ために行うのではなく、みなが高い生産性を出すことができるような方向性で考えることが、組織や企業をよりよくしていくためのコツだと思います。

次回はプラグインレジストリーのカスタマイズを行います。実は現時点でもトライ済みなのですが、公式手順通りではカスタマイズできていない気配を感じるため(詳細未確認)、前途多難かもしれません。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。