Rancher Pipeline + GitHub + GKE でお手軽 CI/CD 環境構築


ども、トップゲートの堤です。

今回も Rancher ネタです。 Rancher には、「 Rancher Pipeline 」という機能が入っています。これは、Rancher 2.1 から実装された機能で、 Rancher 内部で CI/CD 機能が利用できます。これを利用することで、GitHub や GitLab でアップロードされた Dockerfile をビルドし、 Kubernetes クラスタにビルドしたコンテナのデプロイを自動的に行えます。 一種の GitOps 環境が手軽に構築できます。

今回は2019年11月時点で最新の Rancher 2.3 で構築。構築途中でハマった部分も含めて解説します。

1. 仕組み

  1. GitHub にコードをPush
  2. .rancher-pipeline.ymlに基づき、 Jenkins が GitHub でプッシュした Dockerfile を読み込みビルドを行い、Docker Registryにプッシュする
  3. Jenkins が Kubernetes のマニフェストファイルを読み込み、 GKE クラスタにデプロイをする
  4. ログは minio に保存される。

Rancher Pipeline は、下記3つのコンテナで構成されています。 Rancher Pipeline を有効にすると、自動的にKubernetesクラスタ上に下記3つのコンテナ(Pod)が起動します。

名前 役割
Jenkins Dockerfileのビルド、k8sマニフェストファイルを使ったデプロイを実行
minio Jenkinsのビルド、デプロイのログを保存
Docker Registry ビルドしたDockerイメージを保存

.rancher-pipeline.ymlは、 Rancher Pipeline の設定ファイル。 CircileCI などでも似たような設定ファイルがあるが、それに該当する。これは、Rancher Pipeline の UI でも簡単に作れます。ここは、後述します。

2. GitHub 連携設定

【クラスタ名】→【プロジェクト名】→【Resources】→【Pipeline】→【Configure Repositries】

https://github.com/settings/developers にアクセスして、「Client ID」と「Client Secret
」を取得します。

そして、Client ID と Client Secret を設定して <Authenticate> を押します。

すると、リポジトリの一覧が出てくるので、Pipelineを回したいリポジトリに<Enabled>を選択して、下の方にある<Done>を押します。

すると、以下のようになります。

3. Rancher Pipeline の設定&実行

3-1. Pipeline の設定

【Resourcies】→【Pipelines】→【Pipeline名】→【右メニュー:Edit Config】

Rancher Pipelineの設定ファイルである.rancher-pipeline.yml に関しては、 Rancher の GUIから簡単に作成できます。「Add Stage」や「Add Step」をボタンを押して随時設定していきます。

設定は以下の構成で設定していきます。詳細な設定はスクリーンショットを参考にしてください。

  • Stage1: Clone(デフォルトで存在)
  • Stage2: Build
    • Step1 : Build and Publish
  • Stage3: Deploy
    • Step1 : Deploy YAML

▼ Build and Publish ( Dockerfile のビルド)

上記の「Push image to remote repository」 にチェック入れると、外部のコンテナリポジトリにプッシュすることができます。 以下の4種類のレジストリに対応しています。この場合は、予め【Resources】→【Secrets】→【Registry Credentials】 にレジストリの情報を登録しておく必要があります。

  • Docker Hub
  • Quay.io
  • Artifactory
  • Custom (パスワード認証可能なコンテナレジストリ。GitLab や Harbor など)

今回は、リモートリポジトリを使わずに進めます。

▼ Deploy YAML ( Kubernetes の YAML の指定)

3-2. Pipeline の実行

▼ Pipelineの全体像

<Done>を押すと、以下の画面が出てきます。「Push the modified configuration and remote repository automatically」を選択すると、自動的に .rancher-pipeline.yml が GitHub にプッシュされます。

すると、自動的に Jenkins、Docker Registry、 Minio ポッドが起動し、Dockerfile のビルドから、 GKEへのデプロイまで自動的に行なってくれます。(その後は、3つのポッドは起動しつづけます)

無事に myapp という名前のポッドがデプロイされました👏👏👏

あとは、GitHub にプッシュするたびに、 Rancher Pipeline によって新しいコンテナイメージがビルドされて、 Kubernetes クラスタにデプロイされます。

この記事で使用した Dockerfile, Kubernetes のマニフェストファイル、.rancher-pipeline.yml に関しては以下のリポジトリに保存しています。

4. ハマった点

4-1. imagePullSecrets の指定が必要

Kubernetes の Deployment の YAML ファイルに.spec.template.spec.imagePullSecrets を指定しておかないと、 Docker registry からプルするときに認証エラーでコケる。ここの存在を知らなかったんで、探したらこういうオプションが有ることを知って、試してみたらうまくコンテナイメージのプルができるようになった。


apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: demo
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ${CICD_IMAGE}:${CICD_EXECUTION_SEQUENCE}
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
      imagePullSecrets: #←必須
            - name: pipeline-docker-registry #←必須

4-2. Dockerfile は リポジトリのルートにおいたほうが良い。

当初、以下のように docker ディレクトリ配下に Dockerfile をおいてビルドをしたのだが、Dockerfile のCOPYの部分で「./html/hoge.htmlがない」とエラーとなり、ビルドに失敗する。

.
├── README.md
├── deployment.yaml
└── docker
    ├── Dockerfile
    └── html
        └── hoge.html

いろいろ切り分けをしたところ、Dockerfile をリポジトリのルートに置くことで解消した。

.
├── Dockerfile
├── README.md
├── deployment.yaml
└── html
    └── hoge.html

社内の人に聞いたら、「 build context という概念があって、COPY/ADD は docker build コマンド実行時のカレントディレクトリからの相対パスになる」 ということだった。

5. まとめ

Rancher Pipeline は簡単に CI/CD 環境を構築ができます。そして、Rancherだけでクローズできるという点も使いやすいです。

また、GitLab や Harbor などのプライベートコンテナレジストリにもイメージをプッシュできるので、バージョン管理をしたいなどのニーズにも応えられる

個人的には、GCR(Google Container Repository)にコンテナイメージをプッシュしたいのだが、認証部分がちょっと特殊なため、Rancher Pipeline からは利用できないっぽいです。ここに対応できたら、非常にありがたいです。

それでは、引き続きRancher、GKEを使ってコンテナライフをお楽しみください。