「IDOLY PRIDE」におけるArgoRolloutsを使ったBlue/Greenデプロイ
はじめに
この記事はKubernetes Advent Calendar 2023の24日目の記事です。
株式会社QualiArtsで「IDOLY PRIDE(以降、アイプラ)」のバックエンドエンジニアチームのリーダーをしている末吉です。 主にゲームAPIの開発やインフラの運用、チームメンバーの進捗管理や開発スケジュールの策定等を担当しています。
アイプラでは、APIサーバーのコンピューティングにGoogle CloudのGoogle Kubernetes Engine(以降、GKE)を使用しており、リリース戦略としてBlue/Greenデプロイを選択しています。
こちらのBlue/GreenデプロイをArgoRolloutsを導入することによって実現しています。
本記事では、ArgoRolloutsを使ったBlue/Greenデプロイの仕組みや、アイプラでどのように導入したかを紹介できたらと思います。
求められるリリース戦略
アイプラではゲーム性の観点から、ユーザーによって挙動が変わらないリリース戦略 が求められます。
ローリングアップデートの場合、古いアプリケーションを順次置き換えるため無駄なリソースが発生しません。 その反面、古いアプリケーションと新しいアプリケーションが混在する状態になるため、上記の要件に対してあまり適していません。
カナリアリリースの場合、一部のユーザーにだけ新しいアプリケーションをリリースすることができるので、障害が起きてしまった時の影響範囲を抑えることができます。 しかし、こちらもユーザーの挙動が変わってしまうのであまり適していません。
Blue/Greenデプロイの場合、古いアプリケーションと新しいアプリケーションを別々にデプロイすることができるので、全ユーザーが同じタイミングで新しいアプリケーションに切り替わります。 一時的に使用するリソースが2倍に増えてしまうというデメリットがありますが、上記の要件を満たします。 そのため、アイプラではデプロイ戦略としてBlue/Greenデプロイを採用しています。
ArgoRolloutsとは
ArgoRolloutsは、Argoプロジェクトで提供されているKubernetesのカスタムコントローラーです。
Kubernetes標準では困難なBlue/Greenデプロイなどの高度なデプロイ戦略を簡単に実現することができます。
ArgoRolloutsの動作イメージ
下記の図のように、例えばv1.0.0というバージョンのアプリケーションがデプ ロイされているとします。 ActiveServiceとPreviewServiceという2つのServiceが存在し、ユーザーは常にActiveServiceを見ています。 この時は、ActiveServiceもPreviewServiceもv1.0.0のアプリケーションを向いています。
次に、v2.0.0というバージョンのアプリケーションをデプロイします。 そのままv1.0.0のアプリケーションが置き換わるのではなく、新しくv2.0.0のアプリケーションが立ち上がります。 このタイミングで、PreviewServiceはv2.0.0のアプリケーションに向き先を変更します。
PreviewServiceからv2.0.0への疎通が確認できたら、ActiveServiceの向き先をv2.0.0に向けます。 ActiveServiceの向き先が変わることで、ユーザーは最新のアプリケーションにアクセスできるようになります。
最後に不要となったv1.0.0のアプリケーションが削除されます。
導入方法
ここからは導入方法について紹介します。
ArgoRolloutsの導入
ArgoRolloutsをマニフェストで管理する方法ですが、アイプラでは公式のマニフェストファイルをダウンロードしてGitHubのリポジトリにコミットしています。
下記はv1.6.2のマニフェストのリンクになります。
https://raw.githubusercontent.com/argoproj/argo-rollouts/v1.6.2/manifests/install.yaml
Service,Rolloutの用意
ArgoRolloutsのセットアップが完了したら、次はアプリケーションのマニフェストを用意します。
annotationsの部分は、GKEのIngressを使用する場合の例です。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
labels:
app.kubernetes.io/instance: sample-app
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.global-static-ip-name: sample
name: sample-ingress
spec:
rules:
- host: sample.com
http:
paths:
- backend:
service:
name: sample-active-svc
port:
number: 8080
pathType: ImplementationSpecific
ActiveServiceとPreviewServiceの2つを用意します。
apiVersion: v1
kind: Service
metadata:
name: sample-active-svc
spec:
type: NodePort
selector:
app: sample-app
ports:
- name: http
protocol: TCP
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: sample-preview-svc
spec:
type: NodePort
selector:
app: sample-app
ports:
- name: http
protocol: TCP
port: 8080
最後にRolloutリソースです。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: sample-app
labels:
app: sample-app
~~~~
strategy:
blueGreen:
activeService: sample-active-svc
previewService: sample-preview-svc
previewReplicaCount: 1
autoPromotionEnabled: false
scaleDownDelaySeconds: 30
Rolloutリソースのマニフェストファイルですが、Deploymentリソースと異なる箇所はstrategyの部分だけなので、こちらを重点的に説明します。
previewReplicaCountは、新しいバージョンのRolloutを作成した時にPreviewServiceにデプロイされるPodの数です。この数を増やしておく と事前にPodがスケールした状態になるため、ActiveServiceの向き先を切り替える時間が短縮されます。
autoPromotionEnabledは、ActiveServiceの自動切り替えを有効にするかどうかです。こちらをtrueにすると、PreviewServiceにデプロイされたPodが全てReadyになった時点で、自動的にActiveServiceの向き先が切り替わります。 こちらは開発環境など、手動でActiveServiceへの切り替えを行うことが煩雑な場合にtrueにすると良いでしょう。
scaleDownDelaySecondsは、ActiveServiceの向き先切り替え後に古いRolloutを削除するまでの時間です。この時間を長く設定しておく事で、向き先切り替え後に問題が発生した場合でも即座にロールバックする事が可能になります。
Blue/Greenデプロイの挙動
ここからは実際のBlue/Greenデプロイの挙動を見ていきましょう。
アイプラではCDツールにArgoプロジェクトから出ているArgoCDを利用しているので、そちらを前提とした挙動になります。
マニフェストファイルを管理しているGitHubリポジトリに変更を加えると、ArgoCDが自動的に同期/クラスタへの反映を行い、下記のような状態になります。
Resumeを押すことで、ActiveServiceの向き先切り替えを実行できます。
向き先切り替え後、古いRolloutが削除されます。
おわりに
本記事では、アイプラでどのようにBlue/Greenデプロイを実現しているかを紹介しました。
ArgoRolloutsを導入することによって、ユーザーによって挙動が変わる事がないBlue/Greenデプロイを簡単に実装する事ができました。
本記事が皆さまの運用に少しでもお役に立てば幸いです。