Jenkins-Xで別のクラスタにデプロイにできるか試してみた

October 04, 2020

デフォルトで作成したJenkins-Xの環境は、同じクラスタ上のstaging、production環境(名前空間)にデプロイされますが、例えばproductionだけは別のクラスタにデプロイしたい場合、どうすれば良いのかを調べてみました。結論からいうとできましたが、いろいろ苦労したのでその辺りの話をメモしておきます。

別のクラスタにデプロイする方法の手順は公式のここに書いてありましたが、この手順通りにやってもうまくいきませんでした。

まず、別のクラスタにデプロイするには、そのための環境を準備する必要があります。このページでは既存の環境(staging、production)をeditする様に書いてありましたが、この様な問題があり、結局editで変更することができませんでした。そのため、今回は別途、開発環境でjx create env –remoteを実行してデプロイ先のための新しい環境(git repository)を作ることにしました。

そして次に、デプロイ先のクラスタに、Environment Controllerをインストールしますが、事前にjxとIngress Controllerをインストールしておく必要はあります(jx bootの実行は不要)。Environment Controllerのインストールはjx create addon envctlというコマンドでできますが、いろいろオプションを指定する必要があります。最終的には、下記の様なオプションでインストールしました。

jx create addon envctl \
  --set image.repository=gcr.io/jenkinsxio/builder-maven,image.tag=2.0.959-299 \
  --source-url https://github.com/myname/environment-jx-pro.git \
  --docker-registry my.registry.com \
  --docker-registry-org dockerorg \
  --cluster-rbac true \
  --namespace jx-pro \
  --token gittoken \
  --user gituser \
  --webhook-url https://hook-jx.mysite.com

ビルドに用いるイメージ(gcr.io/jenkinsio/builder-maven)のタグを変更していますが、これはビルド中に「500 Internal Error: failed to marshal payload writing data」というエラーが出てしまうのを回避するための対策です。source-urlは上で作成したデプロイ用環境のGitリポジトリを指定します。webhook-urlはgithubからEnvironment Controllerを叩いてもらうためのURLです。そのほかのオプションについては、こちらが参考になると思います。なお、Ingressリソースは下記のようなものをマニュアルで追加しました。

kind: Ingress
metadata:
  name: ingress-conf-for-hook
  namespace: jx
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "0" 
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - hook-jx.mysite.com
    secretName: mysite-cert
  rules:
  - host: hook-jx.mysite.com
    http:
      paths:
      - path: /
        backend:
          serviceName: environment-controller
          servicePort: 80

Environment Controllerをインストールするとpodが2つ起動します。一つはEnvironment Controllerそのもので、もう一つはtekton pipelines controllerです。kubectl get podで確認すると下記の様に表示されるはずです。

NAME                                                                       READY   STATUS      RESTARTS   AGE
environment-controller-7976dc65c9-7ddbw                                    1/1     Running     0          19h
tekton-pipelines-controller-544c7cbcbd-mmjbp                               1/1     Running     0          27h

以上でデプロイ先のクラスタの準備が整いました。次は、ChartMuseumの設定を変更します。デフォルトでインストールしたJenkins-Xの開発環境では、様々なサービスを含んでいますが、その中にはChartMuseumというHelmチャートのリポジトリをホスティングするためのサービスも含まれていると思います。デプロイ先からこのChartMuseumにアクセスできるようにネットワーク関連を設定しても良いのですが、私の場合は開発環境をローカルのクラスタに導入しており、外部からアクセスさせるためにポートを開けるのはセキュリティ的に不安がありましたので、別途ChartMuseumを他のVPSに立ち上げて、そこで運用することにしました。その上で、こちらを参考に開発環境のjx-requirements.ymlに下記を追加して、外部のChartMuseumを使用する様に変更しました。

cluster: 
  chartRepository: <external chartmuseum url>

また、デプロイ先の環境のリポジトリにあるjenkins-x.ymlもこのChartリポジトリを参照するように変更する必要があります。

pipelineConfig:
  env:
  - name: CHART_REPOSITORY
    value: http://chartmuseum.jx.1.2.3.4.nip.io

ここまでやってようやく、jx promoteコマンドでデプロイできるようになりました。マルチクラスタ関連のドキュメントが少なくて何度もつまづきましたが、ここまでできるとデプロイがほぼ自動的に行われるのでやっぱりKubernetesは良いですね。