オンプレKubernetes(Rancher)環境でCD環境を組んでみた

CD環境を構成したい!

と、突然書いてみたわけですが、経緯を少し振り返ってみます。
経緯なんてどうでもいいという場合は読み飛ばしてください。

こちらで紹介したように、弊宅のオンプレ環境ではKubernetesのクラスタが動いています。
こちらのブログやポートフォリオが乗っている本番環境には、Rancherを使用していますが、更新のたびにデプロイ処理を行っていました。
また、コードはGithubで管理していますので、GithubへPush後、コンテナイメージを作成しローカルのコンテナレジストリにPushしたのち、Rancher側でのPodの更新が必要な状態でした。

そこで、今回は、GithubへPushした後の、コンテナイメージの作成・レジストリへのPush・デプロイまでを自動化してみます。

構成

ざっくり図にしてみると、こんな感じになりました。

Github上のmasterブランチへの変更の検知には、Webhookを使用しています。
当然、Webhookを使用していますので、Rancher自体にグローバルから到達可能である必要があります。
(Githubとの連携作業は、ローカルIPアドレスのみでも行うことが出来ますが、Webhookが機能しなくなります。その場合、Githubのリポジトリ設定からWebhookの宛先を修正してください。)
筆者は、少し変なことをしてWebhookのみグローバルからRancherに到達可能にしています。

コンテナイメージのビルドなどのフローは、Rancher自体が持つPipelineと呼ばれる仕組みを利用し、設定を行っています。
この設定は、RancherのWebGUI上から行うことが出来ます。
作成された設定ファイルは、(今回の場合はGithubに)pushされます。
なお、Pipelineの仕組み自体に、DockerRegistryをホストする機能がありますが、今回はすでにオンプレ環境でレジストリが存在するため、そちらを使用するようにしました。
もちろん、DockerHubなどのレジストリも設定可能です。
このPipelineとしての設定を記したファイルは、.rancher-pipeline.ymlとして保存されます。

デプロイでは、ワークロードの設定を記述したYAMLファイルを用意しておく必要があります。
すでにワークロードがデプロイされている場合には、Rancher上からこのYAMLファイルを取得する事が可能です。
しかし、デプロイ自体には不必要な情報が多く含まれているため、編集を行う必要があります。
内容自体は、当たり前ですが通常デプロイする際に記述するYAMLファイルと同様です。

なお、Kubernetesでは、コンテナイメージのタグが同一のまま(latestなど)configを更新しても、Podは更新されません。
そのため、 ${CICD_EXECUTION_SEQUENCE} などの変数を使用してコンテナイメージのタグを変化させる必要がある点、注意が必要です。
このタグは、クラスタにapplyされる前に置換が行われるため、クラスタにデプロイする際に使用するYAMLファイルにも記述することが出来ます。
つまり、コンテナイメージをビルドする際のタグと、クラスタへのデプロイに使用するYAMLファイル上のイメージタグに変数を使用することで、Podの更新を行うことが出来ます。

Rancher公式のサンプルをいくつか列挙しておきます。
pipeline-example-php
pipeline-example-maven
pipeline-example-go

例えば、ポートフォリオ.rancher-pipeline.ymlはこのような形になっています。
(レジストリのURLが混ざっているため、一部伏せています。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stages:
- name: DockerBuild
steps:
- publishImageConfig:
dockerfilePath: ./Dockerfile
buildContext: .
tag: <レジストリのアドレスやパス>/production/portfolio:${CICD_EXECUTION_SEQUENCE}
pushRemote: true
registry: <Rancher上で登録したRegistryの名称>
when:
event: {}
- name: Deploy
steps:
- applyYamlConfig:
path: ./deployment.yaml
timeout: 60
notification: {}

.rancher-pipeline.ymlにあるように、フローに失敗した場合や成功した場合に通知を行うこともできるようです。
これにより、デプロイまでのフローを自動化することが出来ました。

余談

そもそも自動化しようとしたきっかけは、業務でGithub Actionsを使用した自動化作業を行ったことでした。
そこで、手元でも本題にあるフローを自動化しようと思い立ったわけです。。
(結局Github Actionsを使用することなく構築しましたが…)

CI/CDについては今後、勉強して行きたいと思います。