Argo Rollouts を使った Kubernetes へのプログレッシブデリバリー(カナリアリリース)
Kubernetes における CI(継続的インテグレーション)/ CD(継続的デリバリー)は一般的になりつつあり、1日に数回などより頻繁なリリースを実現することが可能になりました。一般的には、新たにアプリケーションをローリングアップデート方式でデプロイすることが多いですが、この方法では全てのユーザーに対して一斉に新バージョンが適用されるため、万が一問題が発生した場合の影響範囲が大きくなります。
プログレッシブデリバリーとは、新しい機能を段階的に公開していく手法です。これにより、影響範囲を細かく制御することができ、問題が発生した際に迅速に対応することが可能です。代表的な方法としてカナリアリリースがあります。カナリアリリースでは、新バージョンを一部のユーザーにだけ提供し、問題がなければ段階的に全ユーザーに展開します。これにより、ユーザーへの影響を最小限に抑えながら、確実なリリースが可能です。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F39888dcf-36b6-2bc1-b33d-ffa464439f55.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=41be6f01c5eb47a793800cb21ccd2004)
Argo Rollouts は、Kubernetes でプログレッシブデリバリーを実現するためのオープンソースツールです。Argo Rollouts を使うと、カナリアリリースやブルーグリーンデプロイメントなど、さまざまなデプロイ方法を簡単に設定できます。また、問題が発生した際には自動でロールバックする機能もあります。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2Fc954f6a4-2070-d436-d2f9-64ccf19bd54b.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=e07d99b539f7cf91e61477127029950f)
Argo Rollouts を活用することで、安全で効率的なリリースプロセスを構築し、Kubernetes 環境の信頼性を高めることができます。
Argo Rollouts と CircleCI のリリース機能(CircleCI Releases)の統合
一般的に、Argo Rollouts を活用しながら CI/CD パイプラインを構築していく場合には以下のツールを組み合わせていく必要があります。
- CircleCI などの CI ツール(テスト、Dockerイメージのビルド、Amazon ECRなどのレジストリへのプッシュ)
- ArgoCD などの Kubernetes に特化したCDツール
- Argo Rollouts などの Kubernetes に特化したプログレッシブデリバリーツール
CI と CD ツールを明確に分けることによるメリットもありますが、同時にこれら複数のツールを使い分けることによって一貫性が失われてしまい、可視性・管理が複雑になってしまいがちです。
この課題を解決するために、CircleCI では独自のリリース機能 (CircleCI Releases) を提供し始めました。
Amazon EKSをはじめとしたKubernetesクラスターと CircleCI を接続し、CircleCI ダッシュボードからリリースを管理・操作することができます。
また、Argo Rollouts とネイティブで連携することができ、CircleCI ダッシュボードから Argo Rollouts によるカナリアリリースの状況の可視化・操作を行うことができます。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2Ffd240bd8-bdb1-c6c1-1a9e-d79ff2bb2182.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a3eb2f07282a33f379ebf71018675f08)
CircleCI Releases の登場により、CI(ビルド・テスト)からCD(デプロイ・カナリアリリース)までを統合されたワークフローにすることが可能になり、可視性・一貫性・生産性を向上させることができます。
次の章では AWS が提供する Amazon EKS クラスターに対するプログレッシブデリバリーを Argo Rollouts と CircleCI Releases によってどう実現するかについて解説します。
Amazon EKS クラスター に CircleCI Releases をセットアップする
CircleCI Releases は、Kubernetes クラスターに専用のエージェント(Release Agent)をインストールすることによって、リリースを管理・操作することができるアーキテクチャになっています。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F67cf35d5-d225-2832-c363-383a1b466c0f.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ced0c6897417a2fdc0b51826d78be823)
実際に Amazon EKS クラスターに CircleCI Releases を使ったリリース環境をセットアップします。
CircleCI Releases ページの「Environments」タブから「Create Environment Integration」を選択し進みます。そして、今回作成するリリース環境(Environment)の Name、 Description を記入し、Type を「Kubernetes Cluster」を選択した上で次に進みます。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2Fc8145ab2-a74e-a653-5770-33b0c4947fe2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=56f72bb7a5592f62b3e9357893f74272)
次に Amazon EKS クラスターに Release Agent をインストールします。
インストールには以下が必要になります。
- Kubernetes クラスター(今回は Amazon EKSクラスター)
- Helm
- Argo Rollouts
Argo Rollouts のインストール方法については公式ドキュメント(英語)を参考にしてください。
次に、CircleCI Helm レポジトリを追加し、ローカル Helm レポジトリキャッシュを更新して、最新バージョンであることを確認します。
helm repo add release-agent
https://circleci-public.github.io/cci-k8s-release-agent
helm repo update
以下の Helm コマンドで Release Agent をインストールします。
helm upgrade --install circleci-release-agent-system
release-agent/circleci-release-agent \ --set
tokenSecret.token=[YOUR_CCI_INTEGRATION_TOKEN]
--create-namespace \ --namespace
circleci-release-agent-system \ --set
managedNamespaces="{namespace1,namespace2}"
チュートリアルの中でこのコマンド内にある YOUR_CCI_INTEGRATION_TOKEN
は自動生成されますが、手動で生成する際には、各 Environments のページから「Create Integration Token」を選択して作成します。
また、default 以外で CircleCI Releases で監視したい namespace があれば、managedNamespaces
に追加します。
インストールが成功すると、Release Agent のステータスが「ONLINE」になります
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F1cd05075-3625-59e6-050c-dc27d62939ac.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ce7aa8fcec46b8dd2d475e61ad208249)
最新の情報は以下のドキュメントを参考にしてください。
Set up a release environment - CircleCI
CircleCI Kubernetes Release Agent Helm Chart | cci-k8s-release-agent
Amazon EKS にデプロイする CircleCI パイプラインを作成する
Amazon EKS クラスター に CircleCI Releases を使ったリリース環境がセットアップできたので、次にAmazon EKS にデプロイする CircleCI パイプラインを作成していきます。
パイプラインのアーキテクチャとしては以下のようになります。
① CircleCI が VCS(ソースコード管理)の変更を検知し、Docker イメージをビルド・Amazon ECR にプッシュ
② CircleCI から Amazon EKS クラスターの Rollout を更新
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F41fafffa-af2d-be08-7065-1eed17fcfc7f.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=082288ac1f9419fb99c3f6dfcf0a4190)
①と②のデプロイのステップが成功すると、③で実際に CircleCI のリリース画面からリリースを管理・操作することが可能になります。
Docker イメージをビルド・Amazon ECR にプッシュ
はじめに、CircleCI で対象のアプリケーションのDockerイメージをビルドし、Amazon ECR にプッシュするジョブ build_and_push_ecr
を作成します。
CircleCI が提供する AWS インテグレーション(CircleCI Orb)を使うと、以下の設定ファイルのようにシンプルにすることが可能です。
CircleCI Developer Hub - circleci/aws-ecr
CircleCI Developer Hub - circleci/aws-cli
build_and_push_ecr:
machine:
docker_layer_caching: true
steps:
- checkout
- aws-ecr/build_and_push_image:
auth:
- aws-cli/setup:
role_arn: ${AWS_ROLE_ARN}
repo: tadashi-demo-release-eks-app
tag: '${CIRCLE_SHA1}'
AWS への認証にはOpenID Connect を利用しており、CircleCI にAWSの永続的なキーを保持する必要がなく、よりセキュアな認証を実現することができます。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2Ffefe3a01-40be-bafd-0dbd-c6639bd80f6c.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=faad49b740466cee690e93c57d597ed3)
設定方法については下記のドキュメントを参考にしてください。
ジョブでの OpenID Connect トークンの使用 - CircleCI
CircleCI の設定ファイル (.circleci/config.yml
)においては、aws-cli/setup
パラメーターにある role_arn
を対象の IAM Role に指定することによって、自動的に OpenID Connect を使った認証に切り替わります。
CircleCI から Amazon EKS クラスターの Rollout を更新
次に、 CircleCI から Amazon EKS クラスターの Rollout を更新(Amazon ECR の最新の Docker イメージタグに変更)します
今回は以下の Argo Rollouts のKubernetes マニフェスト(Rollout) を使用していきます。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
annotations:
circleci.com/job-number: "${CIRCLE_BUILD_NUM}"
circleci.com/pipeline-id: "${CIRCLE_PIPELINE_ID}"
circleci.com/project-id: "${CIRCLE_PROJECT_ID}"
circleci.com/workflow-id: "${CIRCLE_WORKFLOW_ID}"
labels:
app: demo-app
circleci.com/component-name: demo-eks
circleci.com/version: "${CIRCLE_SHA1_SHORT}"
name: demo-eks
spec:
replicas: 4
strategy:
canary:
steps:
- setWeight: 50
- pause: {}
selector:
matchLabels:
app: demo-eks
template:
metadata:
labels:
app: demo-eks
circleci.com/component-name: demo-eks
circleci.com/version: "${CIRCLE_SHA1_SHORT}"
spec:
containers:
- image: 660990364978.dkr.ecr.ap-northeast-1.amazonaws.com/tadashi-demo-release-eks-app:$CIRCLE_SHA1
name: demo-eks
ports:
- containerPort: 3000
この Rollouts では、以下のカナリアリリース戦略をとっています。
- 50%までリリースする
- 一時停止(pause)する
この場合、100%までリリースを進行したい場合には手動コマンド、あるいはこの後紹介する CircleCI Releases ダッシュボードを使った操作が必要になります。
この他に、Datadog などのオブザーバビリティツールと連携することによって、それらのデータを元にリリースを自動判断することができます。
https://docs.datadoghq.com/ja/integrations/argo_rollouts/
先ほどの Rollout ファイルですが、CircleCI 独自の annotation や label を追記しています。
これらは、どの CircleCI の Job からトリガーされたものか(Release Trigger) CircleCI Release ダッシュボードで確認できるのに役立ちます。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F0128e2b8-d336-85b3-4878-86af0d184bb0.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=1b72cee2dd421d5714be453e29e43d17)
annotation や label の値を環境変数にしていますが、この後 CircleCI ジョブ内でこの Rollouts の変更を実行するため、その際に CircleCI ジョブ内にある環境変数から参照・置換します。
Amazon EKS クラスターに対してRollouts の更新を行う CircleCI ジョブ(deploy_eks)の設定ファイルは以下です。
deploy_eks:
docker:
- image: cimg/aws:2024.03.1
steps:
- checkout
- aws-cli/setup:
role_arn: ${AWS_ROLE_ARN}
- aws-eks/update-kubeconfig-with-authenticator:
install-aws-cli: false
aws-region: ap-northeast-1
cluster-name: cci-demo-release
- run:
name: Apply Kubernetes Manifest to EKS
command: |
export CIRCLE_SHA1_SHORT=${CIRCLE_SHA1:0:8}
envsubst < manifest/rollout.yaml | kubectl apply -f -
deploy_eks ジョブでは以下のステップを実行しています。
- aws-cli Orb を使って、OpenID Connect 認証を行う
- aws-eks Orb を使って、対象の Amazon EKS クラスターの kubeconfig の認証の更新を行う
- kubectl コマンドを使い、Kubernetes マニフェスト(Rollout)にCircleCIの環境変数を渡しつつ、新しい Dokcer イメージタグに変更する
CircleCI Releases ダッシュボード からリリースを管理・操作する
実際に CircleCI Releases ダッシュボードにおいてリリースを管理・操作する方法を紹介します。
リリースを進行する(Promote)
現在進行しているカナリアリリースを進行したい場合には、対象のリリースページにある「Promote」を選択します。
全て進行させたい場合には「Promote All」を選択します。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F15f0a9ea-25f4-2949-8ccf-079dd44ec5fc.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=d7b3130cdc2f8a3cde51384c71ca60c4)
以下の Argo Rollouts コマンドと同等の操作をしています。
kubectl argo rollouts promote <rollout-name>
リリースをキャンセルする(Cancel)
現在進行しているカナリアリリースをキャンセルする際には、対象のリリースページにある「Cancel Release」を選択します。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2Fa2b94a90-771e-1e97-5054-3a7ad490dfc2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=6d2ad5bedce97e7bd0e5a5a4d12754a8)
以下の Argo Rollouts コマンドと同等の操作をしています。
kubectl argo rollouts abort <rollout-name>
リリースバージョンをロールバックする(Restore)
現在のリリースバージョンから以前のリリースバージョンにロールバックしたい場合には、対象のリリースバージョンの「RESTORE」を選択します。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F2819936%2F8758f4c8-18ee-6b61-2e3d-969598911e91.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=804155e1a0acbfe2dda4d760f7da8ab4)
以下の Argo Rollouts コマンドと同等の操作をしています。
kubectl argo rollouts undo <rollout-name>
--to-revision=<revision_number>
その他の操作については下記のドキュメント(英語)を参照してください。
Manage releases - CircleCI
まとめ
この記事では、Argo Rollouts と CircleCI のリリース機能(CircleCI Releases)を統合することによって、Amazon EKS への安全なプログレッシブデリバリー(カナリアリリース)を実現する方法について紹介しました。
Argo Rollouts が提供しているプログレッシブデリバリー(カナリアリリース)のメリットを活用しながら、CircleCI Releases を使うことによって可視性・一貫性・生産性を向上させることができます。
CircleCI Releases は Free プランからご利用いただけます、是非お試しいただきそのメリットを体験していただければと思います。