TT Lab
はじめる
学ぶ 学習パス コース

CAPA — Argoプロジェクト認定アソシエイト

宣言と動作のあいだ

TT Labで続きを見る

一言でいうと

Argoのオブジェクトは、意図を書いたものにすぎず、その意図を現実にするのはコントローラーです。コントローラーがなければ、YAMLが正しいかどうかさえわかりません。

なぜコントローラーが必要なのか

前のモジュールで、WorkflowとRolloutを何個も使いました。しかし、それらのラボが動く場所にはコントローラーがなかったため、そのYAMLが実際に何をするのかを確認する方法がありませんでした。

Argoの4つのプロジェクトは、すべてコントローラーがあってはじめて意味が生まれるものです。オブジェクトは、意図を書いたものにすぎず、その意図を現実にするのは、コントローラーです。

Workflows   컨테이너를 실제로 돌린다      없으면 단계가 진행되지도 실패하지도 않는다
Rollouts    파드를 실제로 띄우고 나눈다    없으면 카나리가 몇 퍼센트인지 볼 수 없다
Analysis    Job 을 띄워 판정한다          없으면 자동 롤백이 통째로 빠진다

このコードブロックの韓国語は、Workflowsはコンテナを実際に実行し、なければステップが進行も失敗もしないこと、Rolloutsは、Podを実際に起動して分割し、なければカナリアが何%かを見られないこと、Analysisは、Jobを起動して判定し、なければ自動ロールバックが丸ごと抜け落ちることを述べています。

戻ったのはトラフィックであって、宣言ではない

最も価値のある落とし穴です。分析が失敗して自動ロールバックが起きても、spec.templateのイメージは、新しいバージョンのままです。

直すには、宣言を戻す必要があります。リポジトリのイメージタグを戻すコミットです。

limitはリトライの回数である

WorkflowsのretryStrategy.limitは、リトライの回数です。最初の試行はここに含まれません。limit: 2なら、実際の試行は3回です。

実行中にテンプレートを直しても変わらない

コントローラーが、開始時点の定義をstatus.storedTemplatesに埋め込んでおきます。再現性のためです。「テンプレートを直したのに、なぜそのままなのか」の答えがこれで、次のワークフローから変わります。

カナリアのウェイトが実際に何をするのか

setWeight: 20が、「リクエストの20%」を意味するのか、「Podの20%」を意味するのかは、構成によって異なります。この違いが、実測と期待をずらします。

trafficRouting ウェイトの意味 精度
なし Podの数の比率 粗いです。replicasが5なら、20%はPod1個です
Istio・Gateway API 実際のリクエストの比率 正確です
NGINX Ingress 実際のリクエストの比率(アノテーション) 正確です

trafficRoutingがないと、コントローラーはPodの数で近似します。replicas: 3でsetWeight: 10を指定すると、Pod0個は作れないため、1個(約33%)になります。小さなウェイトから始めるには、replicasが十分に大きいか、trafficRoutingがあることが必要です。

分析が何を見て判断するのか

AnalysisTemplateは、メトリクスのプロバイダーにクエリを投げて、その結果で続行するかを決めます。

metrics:
  - name: error-rate
    interval: 1m
    count: 5                    # 5번 재고
    failureLimit: 2             # 2번 실패하면 롤백
    successCondition: result[0] < 0.05
    provider:
      prometheus:
        address: http://prometheus.monitoring.svc:9090
        query: |
          sum(rate(http_requests_total{status=~"5..",version="{{args.version}}"}[2m]))
            / sum(rate(http_requests_total{version="{{args.version}}"}[2m]))

このコードブロックの2つの韓国語コメントは、順に、5回計測することと、2回失敗したらロールバックすることを述べています。

ここでよく間違えるのが、カナリアだけを絞り込まないクエリです。上のクエリにversionラベルがないと、安定版とカナリアを合算して測ることになり、カナリアが100%失敗しても、全体のエラー率は20%しか上がりません。しきい値を超えず、悪いデプロイが通過します。

そして、トラフィックが少ないときの落とし穴があります。カナリアにリクエストが3個入ってきて、1個が失敗すると、エラー率は33%です。最小サンプル数の条件をあわせてかける必要があります。

successCondition: result[0] < 0.05 || result[1] < 20   # 요청이 20건 미만이면 통과

このコードブロックの韓国語コメントは、リクエストが20件未満なら通過させる、という意味です。

デプロイ戦略を選ぶ基準

カナリア ブルーグリーン
リソース 少し増える(段階ごと) 2倍
巻き戻しの速度 ウェイトを0にする。速い Serviceセレクターの切り替え。最も速い
DBスキーマ 2つのバージョンが長く共存 2つのバージョンが短時間共存
適した場所 トラフィックが多く、メトリクスで判断できる 検証を人が行う、またはトラフィックが少ない

トラフィックが少ない内部サービスにカナリアを使うと、サンプルが足りず、分析が無意味です。その場合は、ブルーグリーンで、previewを人が確認して進めるほうがよいです。

実務で本当に大切なこと

自動ロールバックのあとには、必ず宣言を戻すコミットを入れます。ロールバックはトラフィックだけを戻し、spec.templateは新しいバージョンのまま残ります。GitOpsを使うと、リポジトリが依然として新しいイメージを指しているため、同じデプロイを無限に再試行します。

デプロイの判定は、Healthyではなく、status.stableRSで行います。昇格が終わってHealthyになったあとも、古いPodがTerminatingとして少しの間残り、イメージを数えると2種類が出ます。安定版を指すハッシュが、唯一ぶれない基準です。

retryStrategy.limitは、総試行回数ではありません。最初の試行はここに含まれないため、limit: 2は、実際には3回実行されます。タイムアウトの予算を計算するときに、1回ずつ見落とす場所です。

次の2つのラボで、これらを本物のコントローラーの上で、自分で確認します。