はじめに
こんにちは。計測プラットフォーム開発本部SREブロックの纐纈です。今年の4月に入社し、ZOZOMATやZOZOGLASSの運用改善に取り組んでいます。また、今年の夏US向けにZOZOFITをリリースしましたが、そちらの機能追加にも今後関わっていく予定です。
計測システムでは最近Argo Rolloutsを導入してカナリアリリース、自動ロールバックを実現しました。本記事では、その具体的な導入方法と効果についてお伝えします。
Argo Rollouts導入前のリリースの問題
Argo Rollouts導入前までは、以下の手順でロールバックしていました。
- リリース担当者が異常を検知
- リリースPRをリバートする
- リバートPRをマージする
- Argo CDが変更を検知し、アプリケーションを旧バージョンに戻す
私達のチームではArgoCDを導入しており、KubernetesリソースをGitHubで管理しています。このため、ロールバックは、アプリケーションのイメージタグを変更するリリースPRをリバートすることで完了します。しかしながら、旧バージョンのPodが起動し、トラフィックが流れるまでの間、ユーザー影響は避けられません。
こうした理由からユーザ影響を最小限に抑えるため、リリース戦略を見直す必要がありました。
上記の課題を解決するため、弊チームではカナリアリリースを導入することにしました。
カナリアリリースの導入
まずカナリアリリースについて簡単に説明します。カナリアリリースは、リリースの手法の1つです。初めからリリースするバージョンを全体に公開するのではなく、公開する対象を一部のユーザーだけに絞りつつテストを行い、定められた基準を満たした場合のみ全体に公開するリリース方法のことを指します。これによって、ユーザーのトラフィックありきのテストを本番環境で行いつつ、障害発生時にもユーザーへの影響を最小限にしながら自動ロールバックを実現できるようになります。
また段階的なリリース方法としてカナリアリリースとよく比較されるのが、Blue/Greenデプロイです。Blue/Greenではなくカナリアリリースを選択した理由は、実際にユーザートラフィックが流れる点にあります。カナリアリリースでは実際にユーザートラフィックが流れている状態でテストを行うため、Podの立ち上げ時にはわからない問題も対応できます。計測システムでは、ZOZOTOWNのAPIサーバーと接続して認証するため、実際にトラフィックを流してのテストを行う必要がありました。
導入後の効果
Argo Rolloutsを導入してカナリアリリースを実現してからは、より安心安全にリリースできるようになりました。リリース担当者の心理的負荷が減っただけでなく、エラー検知した際もPodが瞬時に入れ替わるため、障害による影響範囲を最小限に抑えられます。これによって、本番リリース直後のアラートに怯える必要性が大幅に緩和されました。
また副次的な効果として、今回ステージング環境にも同様にArgo Rolloutsを入れたため、エラーを伴う変更が本番環境でリリースするまでに発見できるという効果もありました。ステージング環境ではユーザーのトラフィックは流れていませんが、暖機運転と共に動作確認用の処理がPod起動時に走るため、エラーがあればこの動作確認で発見できます。
この時点でエラーを伴う変更を検知して自動ロールバックが走ったため、ユーザー影響を出す前にステージング環境で食い止めることができました。
カナリアリリースでの1つデメリットとして、Podが徐々に入れ替わって段階的にテストを行うため、全体的なリリース時間が伸びてしまうという特徴があります。例えばリリース後に動作確認やチェックを行う場合、リリース担当者が全てのPodが入れ替わるまで待つ必要があり、これはリリース担当者のリリースに費やす時間的制約を増やしてしまいます。そのため、できる限りリリース後の作業は自動化できると、よりカナリアリリースの恩恵を受けられるようになるかと思います。
ツールの選定
カナリアリリースの特徴や効果については一通り説明できたと思うので、なぜ今回Argo Rolloutsを選んだのかについて説明していきます。カナリアリリースは通常のKubernetesリソースであるDeploymentではサポートされておらず、外部ツールを使う必要があります。カナリアリリースをサポートする外部ツールはArgo Rollouts以外にも、SpinnakerやFlaggerのようなものがあります。Flaggerについては社内の他チームで採用され、ブログ記事も公開されているので、気になる方はこちらの記事をご参照ください。
今回計測システム部でArgo Rolloutsを選んだ理由は3つあります。
まず、計測システムでは既にArgoCDの導入が済んでおりArgo Rolloutsとの親和性が高かったこと。これはArgoCDのWeb UI上でArgo Rolloutsの操作ができる、Slack通知用のトークンなどを共通して使えるなどの利点があります。
次に、Argo Rollouts以外のツールで必要となるIstioのようなサービスメッシュがまだ導入されていないこと。現在計測システムでは、サービスメッシュは使われておりません。そのため、カナリアリリースのためにサービスメッシュを導入すると、工数も増えるため導入のハードルが上がりました。
最後に、必要最小限の機能であるDatadogやCloudWatchの連携ができること。今回考慮したツールの中ではどれもサポートされていましたが、もしArgo Rolloutsがサポートしていなければ、選定されることはありませんでした。
Argo Rolloutsについて
Argo RolloutsはBlue/Greenやカナリアリリースのようなプログレッシブデリバリーをサポートしている、Kubernetesコントローラーです。CRDs(Custom Resource Definitions)でもあります。監視ツールと連携させて自動ロールバックや段階的リリースを行なったり、Ingressコントローラーやサービスメッシュと連携させて限定公開時のトラフィック制御ができます。
連携できる監視ツールはDatadog、CloudWatch、Prometheusなどがあります。事前に定めた基準から外れたメトリクスを検知した場合、自動でロールバック、基準内だった場合は段階的にリリースします。また、このリリースの段階やテスト項目などはKubernetesのマニフェストで定めることができます。
限定公開時のトラフィックの制御については、ALB IngressコントローラーやIstio、nginxなどと連携できます。連携する場合パーセント単位で制御できますが、連携しない場合でもPod数単位での段階的な切り替えが可能です。
カナリアリリース用にArgo Rolloutsで必要なリソースは、RolloutとAnalysis Templateの2つです。
RolloutはArgo Rolloutsのカスタムリソースで、Deploymentリソースの項目に追加してカナリアリリースやBlue/Greenデプロイ用のフィールドが追加されています。DeploymentのExtensionだと考えてもらえれば良いです。Deploymentに含まれているフィールドに関しては対応されている他、カナリアリリースやBlue/Greenデプロイの細かい設定ができます。また、既存のDeploymentを参照して設定を読み込むこともできます。
Analysis Templateでは、Datadogなどの監視ツールで取得するメトリクスとテスト内容が記述できます。テスト内容は、頻度や取得したメトリクスのテスト条件、ロールバックまでの許容エラー数などが記載できます。
DeploymentからRolloutへの移行
Argo Rolloutsを導入すると、PodをRolloutリソースで管理することになります。新規プロジェクトで導入するのであれば、最初からDeploymentではなくRolloutリソースを作成すれば良いです。一方、既存のプロジェクトで導入する場合はDeploymentリソースから移行する必要があります。
今回弊チームでは、DeploymentからRolloutへ障害なく移行できたのでその方法を説明していきたいと思います。
Argo Rollouts導入前の計測システムでは、DeploymentでPodの設定、HPA(Horizontal Pod Autoscaler)でPod数を管理していました。
- 既存のDeploymentを参照するRolloutリソースを作成して、Podを立ち上げる
- HPAの対象をDeploymentからRolloutに変更する
- Deploymentの spec.replicas を0にする
以上のステップに切り分けてリリースすることで、移行は完了します。詳しく見ると、以下のようになります。
続きはこちら