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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/29fc2df4-a803-d2d1-7a49-246b39c94960.png)

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

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

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

# 1. 仕組み

![Rancher_Pipeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/d4e25132-8427-7fe7-3787-b4e3229722d5.png)

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

Rancher Pipeline は、下記３つのコンテナで構成されています。 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】

![ScreenShot 2019-11-22 13.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/bb8fd75d-2448-2972-77d1-e79879a1cdbd.png)

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

![github-key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/afc2f611-bfe4-3f82-2d5c-211b0d174a69.png)

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

<img width="1264" alt="ScreenShot 2019-11-22 13.05.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/6f7af5d3-9d4f-7cf1-2223-ff0028415af6.png">

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

<img width="1250" alt="ScreenShot 2019-11-22 13.19.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/1371f0cb-d6c6-9e67-8c00-cb857f029be5.png">

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

<img width="1283" alt="ScreenShot 2019-11-22 13.20.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/2a40777a-7d23-fd2d-08fb-a0fffaa008d4.png">

# 3. Rancher Pipeline の設定＆実行

## 3-1. Pipeline の設定

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

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

<img width="1339" alt="ScreenShot 2019-11-22 13.56.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/8c1c8c54-d8bf-6610-594b-80fdac53e592.png">

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

* Stage1: Clone（デフォルトで存在）
* Stage2: Build
    * Step1 : Build and Publish
* Stage3: Deploy
    * Step1 : Deploy YAML 


▼ Build and Publish （ Dockerfile のビルド）
<img width="988" alt="ScreenShot 2019-11-22 14.58.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/dcc7ddf8-f62c-b4d1-711d-4443b7914079.png">

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

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

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

▼ Deploy YAML （ Kubernetes の YAML の指定）

<img width="988" alt="ScreenShot 2019-11-22 14.58.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/9ed9e296-35f7-dffa-83c8-0092fc55d7f7.png">

## 3-2. Pipeline の実行

▼ Pipelineの全体像
<img width="1313" alt="ScreenShot 2019-11-22 15.49.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/4d6ba629-1773-8c1c-999d-32d072a75962.png">

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

<img width="752" alt="ScreenShot 2019-11-22 14.59.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/a8b19427-13ae-5f07-2ae7-362ab36f93d9.png">

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

<img width="1271" alt="ScreenShot 2019-11-22 15.14.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/e5af6d84-6054-bd34-617b-1fe9a93d2408.png">

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

<img width="1255" alt="ScreenShot 2019-11-22 15.54.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92726/6a2a6e45-09dd-7fd3-d97d-4ddaea8ce6fd.png">

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

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

* [rancher-pipeline-demo@GitHub](https://github.com/maro-kt/rancher-pipeline-demo)

# 4. ハマった点

## 4-1. imagePullSecrets の指定が必要

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

```yaml

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がない」とエラーとなり、ビルドに失敗する。

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

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

```text
.
├── 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を使ってコンテナライフをお楽しみください。