10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログレッシブデリバリー導入 ~Argo RolloutsとIstioで実現するリリースフロー堅牢化~

Last updated at Posted at 2025-11-12

こんにちは、menu事業部エンジニアインターンの原です。7-8月の2ヶ月間、menuのマイクロサービスチームでインターンをさせていただいていました。

今回は、自分がその間に行ったタスクの一つであるプログレッシブデリバリーの導入についてご紹介したいと思います。

プログレッシブデリバリー is 何

デリバリーと名づけられているため特定の継続的デリバリーの手法のように思えますが、モダンなソフトウェアのリリースフローへの推奨されるエンジニアリングプラクティス、と形容したほうが的確かなと思います(SREのアイデアに構造的には近いかもしれません)。

ソフトウェアの要件によって取られる手法は様々なのでこれといった明確な手法は存在しませんが、カナリアリリースにオブザーバビリティの要素を判断材料とする自動ロールバックの機能を組み合わせたものがよく例としてあげられます。その他にも、フィーチャーフラグやカオスエンジニアリングなども内包する概念です。

技術構成

プログレッシブデリバリーを実現するにあたり、Argo Rollouts, Istioなどのカスタムリソースを利用しました。

Argo Rollouts

Argo Rollouts Architecture

ソフトウェアのリリース手法には様々な手法が存在しますが、menuのような常に稼働していることが要件とされるSaaSではリリースのたびにダウンタイムを生むようなことは許容できません。こういったニーズに対応するため、ダウンタイムを発生させないリリース手法としてBlue/Greenデプロイやカナリアリリースなどの手法が存在します。

Argo Rolloutsはそういったダウンタイム無しのリリース手法をKubernetesで実現するためのOSSです。Argo CDなどで有名なArgoファミリーのソフトウェアですが、Argo CDとは独立して動かすことができます。

Rollout

ブルーグリーンデプロイやカナリアリリースをKubernetes上で可能とするカスタムリソースです。デプロイの自動分析・ロールバックやトラフィック制御を行ってくれます。Deploymentの代替/進化版のリソースといった位置づけです。

AnalysisTemplate

Rolloutでデプロイ中の新しいアプリケーションバージョンが正常かどうかを検証するための分析テンプレートです。この設定を元にAnalysisRunという分析が設定したタイミングで走ります。監視するメトリクスや、どのような条件(例: エラーレートが1%未満)を満たせば成功と見なすかなどをこのリソースで定義します。

Prometheus, Datadog, New Relicなどにクエリを投げたりJobを実行したりして分析を行うことが可能です。menuではGoogle CloudのマネージドPrometheusを利用しているため、そちらからメトリクスを引き出す形で構成しました。

Istio

Istio Architecture

Istioは主に2つの用途で利用されています。

VirtualService

サービスメッシュ内のトラフィックルーティングを制御するための中心的なリソースです。トラフィックの重みづけ、タイムアウト、フォールトインジェクションなど色々できます

プログレッシブデリバリーを実装するにあたり、ヘッダベースのルーティングを行うのに利用しています。

Istio Standard Metrics

上に説明したAnalysisTemplateで分析するメトリクスとして、Istio Standard Metricsのistio_requests_totalを利用しており、レスポンスのステータスコードをもとにエラー検知を行っています。

変更前

変更前のリリースフローはシンプルです。以下の図のようにBlue/Greenを用いてダウンタイムなしのリリースを実現させています。

release-flow-1.png
release-flow-2.png
release-flow-3.png

利用ユーザーへの影響を与えないという要件を満たすリリース方式ではあるのですが、リリースに何か問題があった際の堅牢性を高めたいということで以下のような変更を加えました。

変更後

Istio VirtualServiceのヘッダベースルーティングを用いた検証リクエストを投げられる機能とメトリクスを使った自動ロールバック機能を追加しました。

想定するリリースシナリオとしては以下の通りです。

  1. 通常の状態

    release-flow-4.png

  2. 変更がマージされ、コンテナがCIによってビルドされる また、CIがマニフェストリポジトリのコンテナイメージのハッシュを書き換える

  3. Argo CDでマニフェストを同期する

  4. RolloutをPromoteする

  5. 新しいイメージハッシュのReplicaSetが立ち上がる ここでリリースは一時停止状態に入ります

    • この時点では新旧バージョン両方立ち上がっている
    • リリース検証用のカスタムヘッダの付与されたリクエストのみ新バージョンへと割り振られる
    • これを使いリリース担当者が新バージョンの挙動に問題がないかチェックすることが可能です

    release-flow-5.png

  6. リリース担当者がArgo CD上でRolloutをResumeしリリースを続行する

    • この時点で全てのトラフィックが新バージョンへと割り振られます
  7. メトリクスを利用して新バージョンの挙動が問題ないかのチェックが実行される 失敗した場合はトラフィックは再度旧バージョンへと切り戻される

    release-flow-6.png

  8. 問題なければリリース完了

    release-flow-7.png

  9. 失敗時には通常トラフィックは旧バージョンへと切り戻されます。また、新バージョンはスケールダウンされず保持されるので、リリース担当者は何が問題だったのかをリクエストを投げて検証することが可能です。

    release-flow-8.png

以下参考までに主要リソースのmanifestです。

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout
spec:
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: grpc-server
  workloadRef:
    apiVersion: apps/v1
    kind: Deployment
    name: grpc-server
  strategy:
    blueGreen:
      activeService: service
      previewService: service-preview
      postPromotionAnalysis:
        templates:
          - templateName: success-rate
        args:
          - name: service-name
            value: service.example.svc.cluster.local
      autoPromotionEnabled: false
      scaleDownDelaySeconds: 300
      abortScaleDownDelaySeconds: 30
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
  - name: success-rate
    interval: 2m
    count: 5
    successCondition: result[0] >= 0.95
    failureLimit: 3
    provider:
      prometheus:
        address: http://frontend.gmp-proxy.svc.cluster.local:9090
        timeout: 40
        # サービスのレスポンスの正常率を計算
        # リクエストがない場合(割合がNaNになる)場合は正常率を1とする
        query: |
          (
            sum(irate(istio_requests_total{reporter="destination",destination_service="{{args.service-name}}",response_code!~"5.."}[2m]))
            /
            sum(irate(istio_requests_total{reporter="destination",destination_service="{{args.service-name}}"}[2m]))
            > 0
          )
          or vector(1)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-service
  namespace: istio-gateway
spec:
  hosts:
    - service.example.svc.cluster.local
    - service-preview.example.svc.cluster.local
  gateways:
    - istio-gateway/istio-gateway
    - mesh
  http:
    # リクエストが検証用ヘッダを含む場合previewへルーティングする
    - route:
        - destination:
            host: service-preview.example.svc.cluster.local
            port:
              number: 5050
      match:
        - headers:
            x-release-tester:
              regex: ".*"
    # それ以外の場合activeへルーティングする
    - route:
        - destination:
            host: service.example.svc.cluster.local
            port:
              number: 5050

将来的な改善の余地

現状ではpreviewの検証は手動で行われるようになっていますが、将来的には自動E2Eテスト&リリース前の自動分析(上の図ではリリース後にAnalysisRunを実行していますがリリース前に差し込むことも可能です)を組み込むことで、よりリリースの堅牢性を高めることができ、ユーザーへの影響も抑えられる構成にできるかな、など構想しています。

また、現在はマネージドPrometheusへの認証のためGoogle Cloudの提供する認証プロキシ
(上の図でのgmp-proxy)を立てているのですが、Argo RolloutsでGoogle Managed PrometheusをサポートするPRが出されているので将来的にはダイレクトに認証できるようになりそうです。

終わりに

いかがだったでしょうか?自分は元々ダウンタイムなど全く気にせず自宅でKubernetesクラスターを運用していたのですが、今回のインターンを通して多くの知見が得られ、色々と改善のアイデアが浮かんできて楽しかったです(インターンが終わったら練り直そうと思います)。

リリースの堅牢性はサービスの改善サイクルのスピードアップに欠かせないものですので、今後もより良い改善の方法を模索していこうと思います。

▼新卒エンジニア研修のご紹介

レアゾン・ホールディングスでは、2025年新卒エンジニア研修にて「個のスキル」と「チーム開発力」の両立を重視した育成に取り組んでいます。 実際の研修の様子や、若手エンジニアの成長ストーリーは以下の記事で詳しくご紹介していますので、ぜひご覧ください!

▼採用情報

レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。 現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?