PipeCDを使ったGitOpsによる継続的デリバリー
構築したGitOpsによるソフトウェアデリバリーの動作確認
Hello Appリポジトリで何かしら変更をするとv0.0.1-xxxというようなタグでDockerイメージが作成されます。Hello App Configリポジトリのdev/deployment.yamlのタグを書き換えてみましょう。しばらくするとdev環境に変更されたバージョンがデプロイされます。
また、Hello AppリポジトリのRELEASEファイルをv0.0.1からv0.0.2に変更してください。GitHubリリースが作成され、v0.0.2というタグでDockerイメージが作成されます。
prod/deployment.yamlファイルで指定されているイメージをv0.0.1からv0.0.2へ変更してください。しばらくするとデプロイが始まりますが、prod環境では承認が必要なので途中で止まります。PipeCDのWeb UIのメニューから、Deployments画面を開くと以下のような表示がされていると思います。
prod環境へのデプロイがRUNNINGになっているので、こちらをクリックします。デプロイの詳細画面が開きます。
WAIT_APPROVALステージで停止していますので、こちらをクリックすると承認するためのダイアログが出てきます。APPROVEを選択してください。デプロイが始まり変更した設定とprod環境のアプリケーションの状態が同期されます。
prod環境でもPodsの数を変更するだけだと、WAIT_APPROVALステージを経ずにすぐデプロイされます。これをQuick Syncと呼びます。このようにPipeCDでは変更に応じてデプロイの戦略が変わります。
以上でGitOpsによる継続的デリバリーが実現されました。
PipeCD Event Watcherによるイメージタグ更新の自動化
この節は発展的な内容なので読み飛ばしても構いません。ただ、GitOpsは「Gitリポジトリ」「デプロイ処理」「Gitリポジトリのバージョン更新」という3つの部分からなり、この節で行うことは重要な1つでもあります。
これまでに次のようなソフトウェアデリバリーが構築されました。
Hello AppリポジトリでPRを出しマージされるとDockerイメージが作成されます。問題となるのは作成されたイメージのタグの更新が手動ということです。開発者体験を向上し、アプリケーションの変更を迅速にユーザー側へ反映するために、このタグの更新を自動化しましょう。これにはPipeCDのEvent Watcher機能を利用します。この機能を使うと次のようなフローになります。
GitHub ActionsでDockerイメージを作成した後にPipeCDのコントロールプレーンにイベントを登録します。このイベントはコントロールプレーンを通してPipedエージェントが受信します。その後、監視するHello App ConfigリポジトリのDockerイメージタグを最新のものに書き換えてコミットします。Deploy keyにSSH鍵を登録する時、Allow write accessにチェックを入れたのはこのためです。
コミット後は監視するリポジトリが変更されたので、Pipedエージェントはデプロイを始めます。
API Keyの発行
GitHub ActionsからPipeCDコントロールプレーンにイベントを登録するためにAPIキーを発行します。PipeCDのWeb UIのメニューから、Settings画面を開いてください。API Keyタブの+ ADDを押して以下の設定でAPI Keyを発行します。
| Name | Role |
|---|---|
| hello app event watcher | Read/Write |
GENERATEボタンで出てくるAPI Keyは後で使うのでメモをしておいてください。
ngrokのインストール
PipeCDコントロールプレーンはローカルで実行されているので、GitHub ActionsからAPIを叩くためにはngrokを使います[注8]。ngrokはローカルで動くサービスを外部に公開することができるサービスです。ngrokのインストールとアカウント登録と認証(ngrok tcpコマンドに必要)を済ませて、以下のコマンドを実行してください。どちらのコマンドもEvent Watcherを試す間は起動し続けてください。
$ kubectl -n pipecd port-forward svc/pipecd 8080 $ ngrok tcp 8080
実行するとxxx.tcp.ngrok.io:yyyのような外部に公開されるドメインが表示されます。こちらも後で使うのでメモをしておいてください。
[注8] ngrokはローカルマシンのサービスをインターネットに公開するので、セキュリティ上のリスクを承知した上でお使いください。
Event Watcherの設定
Hello App ConfigリポジトリでEvent Watcherの設定ファイルを作成します。リポジトリのルートに.pipeディレクトリを作成します。以下の内容で.pipe/event-watcher.yamlを作成してください。
apiVersion: pipecd.dev/v1beta1
kind: EventWatcher
spec:
events:
- name: dev-image-update
replacements:
- file: dev/deployment.yaml
yamlField: $.spec.template.spec.containers[0].image
- name: prod-image-update
replacements:
- file: prod/deployment.yaml
yamlField: $.spec.template.spec.containers[0].image
作成後コミットしてGitHubのリポジトリを更新してください。この設定によりPipedエージェントはdev-image-updateとprod-image-updateという名前のイベントを受信したら、replacementsで指定されたファイルのフィールドを受信したデータに置き換えます。
Pipedの設定
Pipedエージェントの設定を変更します。manifestリポジトリのquickstart/piped-values.yamlにeventWatcherの設定を追加します。次のように編集してください。
args:
insecure: true
config:
data: |
apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
projectID: quickstart
pipedID: YOUR_PIPED_ID
pipedKeyFile: /etc/piped-secret/piped-key
git:
sshKeyFile: /etc/piped-secret/ssh-key
apiAddress: pipecd.pipecd.svc.cluster.local:8080
webAddress: http://localhost:8080
syncInterval: 1m
repositories:
- repoId: hello-app-config
remote: git@github.com:<あなたのGitHubアカウント名>/hello-app-config.git
branch: main
# 以下を追加
eventWatcher:
gitRepos:
- repoId: hello-app-config
この設定でPipedエージェントがEvent WatcherをHello App Configリポジトリに対して使えるようになります。以下のコマンドで変更を適用してください。
$ helm -n piped upgrade piped ./manifests/piped \ --values ./quickstart/piped-values.yaml \ --set secret.pipedKey.data=<Piped Key> \ --set-file secret.sshKey.data=<作成したSSH秘密鍵ファイルへのパス>
GitHub Actionsの設定
Hello AppリポジトリでGitHub Actionsの設定ファイルを変更します。
ビルドとテスト関連の設定が記述された.github/workflows/build.yamlの最後の行に以下を追加してください。
register-event:
if: ${{ github.event_name != 'pull_request' }}
needs: docker-build
runs-on: ubuntu-latest
steps:
- run: echo ${{ needs.docker-build.outputs.tags }}
- uses: docker://gcr.io/pipecd/pipectl:v0.16.0
with:
args: event register --insecure --address=${{ secrets.PIPECD_API_ADDRESS }} --api-key=${{ secrets.PIPECD_API_KEY }} --name=dev-image-update --data=${{ needs.docker-build.outputs.tags }}
変更によりbuild.yamlのDiffは以下のようになります。
GitHubリリース作成関連の設定が記述された.github/workflows/gh-release.yamlの最後の行に以下を追加してください。
register-event:
if: ${{ github.event_name != 'pull_request' }}
needs: docker-build
runs-on: ubuntu-latest
steps:
- run: echo ${{ needs.docker-build.outputs.tags }}
- uses: docker://gcr.io/pipecd/pipectl:v0.16.0
with:
args: event register --insecure --address=${{ secrets.PIPECD_API_ADDRESS }} --api-key=${{ secrets.PIPECD_API_KEY }} --name=dev-image-update --data=${{ needs.docker-build.outputs.tags }}
- uses: docker://gcr.io/pipecd/pipectl:v0.16.0
with:
args: event register --insecure --address=${{ secrets.PIPECD_API_ADDRESS }} --api-key=${{ secrets.PIPECD_API_KEY }} --name=prod-image-update --data=${{ needs.docker-build.outputs.tags }}
変更によりgh-release.yamlのDiffは以下のようになります。
ここで指定されているsecrets.PIPECD_API_ADDRESSとsecrets.PIPECD_API_KEYはGitHub Secretsです。GitHubリポジトリのSettingsからSecretsタブを開きNew repository secretボタンを押して以下の2つのシークレットを作成してください。
| Name | Value |
|---|---|
| PIPECD_API_ADDRESS |
ngrokにより作成されたドメイン(例:xxx.tcp.ngrok.io:yyy ※tcp://は入れない) |
| PIPECD_API_KEY | PipeCD Web UIで作成したAPI Key |
以上でイメージタグの自動更新がされるようになりました。Hello Appリポジトリでアプリケーションに変更を加えたり、RELEASEのバージョンを上げてみたりしてください。しばらくするとHello App Configリポジトリで指定しているDockerイメージタグが自動で更新されます[注9]。
以上で継続的インテグレーションから継続的デリバリーがスムーズに繋がり、アプリケーションの変更をスムーズにユーザーへ反映することができるようになりました。
[注9] なかなか更新されない場合はPipedエージェンの設定により更新間隔を早めることができます。
