Kruise Rollout は、Kubernetes ネイティブおよび OpenKruise のワークロード (Deployment、StatefulSet、CloneSet、Advanced StatefulSet) 向けの段階的リリースを実現する Kubernetes 拡張機能です。Container Service for Kubernetes (ACK) でカナリアリリース、A/B テスト、バッチロールアウトを実行できます。Kruise Rollout
2 つのユースケース:
-
カナリアリリースと A/B テスト — 全体への展開の前に、Nginx Ingress または MSE Ingress を使用して部分的なトラフィックを新バージョンにルーティングします
-
マイクロサービスアプリケーションの段階的リリース — Ingress を使用せずに Pod をバッチでロールアウトします。トラフィックシフトを内部で処理するアプリケーション (Nacos ベースのサービスなど) に適しています
Kruise Rollout 段階的リリースアーキテクチャ:
仕組み
Kruise Rollout は OpenKruise のプログレッシブデリバリーコントローラーであり、Deployment、StatefulSet、および OpenKruise ワークロードに対するカナリアリリース、A/B テスト、ブルーグリーンデプロイメント、パーティションベースの段階的ロールアウトをサポートします。ワークロードの更新を捕捉し、段階的に実行します。各ステップでは、更新するポッドの数 (replicas) と一時停止する期間 (pause) を指定します。Ingress ベースのデプロイメントでは、各ステップでトラフィックの重み (weight) も制御します。
Rollout リソースを一度構成すれば、以降のデプロイメント更新ごとに、Kruise Rollout が自動的に変更をインターセプトし、定義されたステップに従って進行します。Rollout は Prometheus メトリクスを使用してバッチの進行と一時停止を自動化することもできます。
前提条件
以下を確認してください:
-
-
A/B テストまたはカナリアリリースの場合はバージョン 1.19 以上
-
段階的リリースの場合はバージョン 1.16 以上
-
-
kubectl-kruise がインストールされていること。
事前準備
ステップ 1: ack-kruise アドオンのインストール
-
ACK コンソールにログオンします。左側のナビゲーションペインで、[クラスター]を選択します。
-
[クラスター] ページで、目的のクラスターの名前をクリックします。左側のナビゲーションペインで、[アドオン] をクリックします。
-
[アドオン] ページで、[アプリケーション管理] タブをクリックします。[ack-kruise] カードで、[インストール] をクリックします。
-
ダイアログボックスで、[OK] をクリックします。
ack-kruise アドオン 1.8 以降は v1beta1 API をサポートします。詳細については、「API 仕様」をご参照ください。
ステップ 2: サンプルアプリケーションのデプロイ
デプロイメントとサービスを使用して echoserver サービスをデプロイします。echoserver サービスをデプロイメントとイングレスを使用してデプロイします。このサンプルは、両方のユースケースで使用されます。
-
echoserver.yamlという名前のファイルを作成します。 -
構成を適用します。
kubectl apply -f echoserver.yaml
ユースケース 1: Ingress を使用したカナリアリリースと A/B テスト
Nginx Ingress または MSE Ingress を使用して、カナリアリリースと A/B テスト用に Kruise Rollout を構成します。trafficRoutings フィールドは、各ステップでトラフィックの重みを制御するために、Rollout を Service と Ingress に接続します。各 Rollout は 3 つのステップを定義します:
| 戦略 | ステップ 1 | ステップ 2 | ステップ 3 |
|---|---|---|---|
| カナリアリリース | トラフィック重み 20%、Pod 1 つ、手動一時停止 | トラフィック重み 50%、Pod 50%、60 秒自動一時停止 | 100% (完全リリース)、60秒自動一時停止 |
| A/B テスト | User-Agent: Android トラフィックを新バージョンにルーティング、Pod 1 つ、手動一時停止 |
Pod 50%、60 秒自動一時停止 | Pod 100%、60秒自動一時停止 |
ステップ 1: Ingress コントローラーのインストールと Ingress の作成
Ingress タイプを選択し、対応する手順に従ってください。
Nginx Ingress
-
Nginx Ingress Controller をインストールします。
-
新規クラスター:クラスター作成の際に、[Ingress] 設定セクションで [Nginx Ingress] を選択します。
-
既存のクラスター: 「Nginx Ingress を作成して Service を公開する」をご参照ください。
-
-
echoserver-ingress.yamlという名前のファイルを作成します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echoserver spec: ingressClassName: nginx rules: - http: paths: - backend: service: name: echoserver port: number: 80 path: /apis/echo pathType: Exact -
Ingress を適用します。
kubectl apply -f echoserver-ingress.yaml
MSE Ingress
-
MSE Ingress Controller をインストールし、MseIngressConfig と IngressClass を作成します。詳細については、「MSE Ingress を介したコンテナサービスへのアクセス」をご参照ください。
-
echoserver-ingress.yamlという名前のファイルを作成します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echoserver spec: # ingressClassName を mse に設定する必要があります。 ingressClassName: mse rules: - http: paths: - backend: service: name: echoserver port: number: 80 path: /apis/echo pathType: Exact -
Ingress を適用します。
kubectl apply -f echoserver-ingress.yaml
ステップ 2: アプリケーションへのアクセスの確認
-
外部 IP アドレスまたはホスト名を取得します。Nginx Ingress:
export EXTERNAL_IP=$(kubectl get ingress echoserver -o jsonpath="{.status.loadBalancer.ingress[0].ip}")MSE Ingress:
export EXTERNAL_IP=$(kubectl get ingress echoserver -o jsonpath="{.status.loadBalancer.ingress[0].hostname}") -
アクセスをテストします。
curl http://${EXTERNAL_IP}/apis/echo想定される出力:
Hostname: echoserver-75d49c475c-ls2bs Pod Information: node name: version1 pod name: echoserver-75d49c475c-ls2bs pod namespace: default Server values: server_version=nginx: 1.13.3 - lua: 10008 ...
ステップ 3: Rollout リソースの定義
ユースケースに応じた戦略で rollout.yaml という名前のファイルを作成します。trafficRoutings フィールドは、各ステップでトラフィックをシフトするために、Rollout を echoserver Service と Ingress にリンクします。
カナリアリリース
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: echoserver
strategy:
canary:
steps:
# ステップ 1: トラフィックの 20% を新バージョン (Pod 1 つ) にルーティングします。手動承認まで一時停止します。
- weight: 20
replicas: 1
pause: {}
# ステップ 2: トラフィック 50%、Pod 50% に増やします。60 秒後に自動的に進行します。
- weight: 50
replicas: 50%
pause: {duration: 60} # 単位: 秒
# ステップ 3: 完全リリース。
- weight: 100
replicas: 100%
pause: {duration: 60} # 単位: 秒
trafficRoutings:
- service: echoserver
ingress:
name: echoserver
A/B テスト
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: echoserver
strategy:
canary:
steps:
# ステップ 1: Android トラフィックを新バージョン (Pod 1 つ) にルーティングします。手動承認まで一時停止します。
- matches:
- headers:
- type: Exact
name: User-Agent
value: Android
pause: {}
replicas: 1
# ステップ 2: Pod 50%、引き続き Android トラフィックをマッチングします。60 秒後に自動的に進行します。
- matches:
- headers:
- type: Exact
name: User-Agent
value: Android
pause: {duration: 60} # 単位: 秒
replicas: 50%
# ステップ 3: 完全リリース。
- matches:
- headers:
- type: Exact
name: User-Agent
value: Android
pause: {duration: 60} # 単位: 秒
replicas: 100%
trafficRoutings:
- service: echoserver
ingress:
name: echoserver
Rollout を適用し、正常であることを確認します。
kubectl apply -f rollout.yaml
kubectl get rollout
想定される出力:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE
rollouts-demo Healthy 3 Completed workload deployment is completed 7s
STATUS=Healthy は、Rollout の準備が整ったことを示します。
ステップ 4: アップグレードのトリガー
Kruise Rollout は、Deployment 仕様が変更されると自動的に開始されます。echoserver.yaml のイメージバージョンを更新してリリースをトリガーします。
# echoserver.yaml (関連セクション)
spec:
containers:
- name: echoserver
image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.3
env:
- name: NODE_NAME
value: version2 # オプション: 検証出力で新バージョンを識別するのに役立ちます
更新された Deployment を適用します。Helm や Vela などのツールも使用できます。
kubectl apply -f echoserver.yaml
ロールアウトのステータスを確認します。
kubectl get rollouts rollouts-demo -n default
想定される出力:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE
rollouts-demo Progressing 1 StepPaused Rollout is in step(1/3), and you need manually confirm to enter the next step 41m
ステータスフィールドの意味:
| フィールド | 値 | 意味 |
|---|---|---|
STATUS |
Progressing |
カナリアリリースが進行中 |
CANARY_STEP |
1 |
現在 3 ステップ中の 1 ステップ目 |
CANARY_STATE |
StepPaused |
ステップ 1 が完了し、手動承認を待機中 |
ステップ 5: トラフィック分散の確認と進行
カナリアリリース
-
Service に 10 回アクセスし、出力の
node nameを確認します。for i in {1..10}; do curl -s http://${EXTERNAL_IP}/apis/echo | grep 'node name'; sleep 1; done想定される出力 (約 8 リクエストが version1、2 リクエストが version2):
node name: version1 node name: version1 node name: version2 node name: version1 node name: version2 node name: version1 node name: version1 node name: version1 node name: version1 node name: version18:2 の比率は、ステップ 1 で構成された 20% の重み付けと一致します。
-
ステップ 1 を承認してステップ 2 に進みます。
kubectl-kruise rollout approve rollouts/rollouts-demo -n default -
ステップ 2 とステップ 3 を通じてロールアウトを監視します。
kubectl get rollouts rollouts-demo -n default -wロールアウトは自動的にステップ 2 (重み 50%、一時停止 60 秒) とステップ 3 (100%、一時停止 60 秒) を進みます。
STATUS=HealthyかつCANARY_STATE=Completedになると、ロールアウトは完了です。
A/B テスト
-
User-Agent: Androidヘッダーありとなしでリクエストを送信します。curl -s http://${EXTERNAL_IP}/apis/echo | grep 'Pod Information:' -A 3 curl -sH "User-Agent: Android" http://${EXTERNAL_IP}/apis/echo | grep 'Pod Information:' -A 3想定される出力:
Pod Information: node name: version1 pod name: echoserver-69598f9458-7c66v pod namespace: default Pod Information: node name: version2 pod name: echoserver-fvhzg-687b4b56-qbhc8 pod namespace: defaultヘッダーなしのリクエストは version1 にルーティングされ、Android リクエストは version2 にルーティングされます。
-
ステップ 1 を承認してステップ 2 に進みます。
kubectl-kruise rollout approve rollouts/rollouts-demo -n default -
完了までロールアウトを監視します。
kubectl get rollouts rollouts-demo -n default -wロールアウトは自動的にステップ 2 とステップ 3 を進みます。
STATUS=HealthyかつCANARY_STATE=Completedになると、ロールアウトは完了です。
リリースのロールバック
いずれかのステップで新バージョンが意図しない動作をした場合は、以前の Deployment 構成を復元して再適用します。Rollout リソースの変更は不要です。
# echoserver.yaml (ロールバックバージョン)
spec:
containers:
- name: echoserver
image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.2
env:
- name: NODE_NAME
value: version1
kubectl apply -f echoserver.yaml
ユースケース 2: マイクロサービスアプリケーションの段階的リリース
Nacos などのマイクロサービスフレームワークは、Ingress や Service レベルのルーティングなしでトラフィックシフトを内部で処理します。Kruise Rollout のパーティションベースの段階的リリースを使用して、trafficRoutings フィールドなしで Pod をバッチでロールアウトします。
マイクロサービスフレームワークがトラフィックシフトを管理するため、このユースケースではロールアウトバッチの進行のみを扱い、トラフィックの検証は行いません。
ステップ 1: Rollout リソースの定義とデプロイ
この Rollout は partition ローリングスタイルを使用して、Pod を 3 つのバッチ (1 Pod、次に 50%、最後に 100%) でリリースします。マイクロサービスフレームワークがトラフィックを管理するため、trafficRoutings フィールドは省略されています。
# rollout.yaml として保存
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
annotations:
rollouts.kruise.io/rolling-style: partition
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: echoserver
strategy:
canary:
steps:
# ステップ 1: Pod 1 つを更新します。手動承認まで一時停止します。
- replicas: 1
pause: {}
# ステップ 2: Pod の 50% を更新します。60 秒後に自動的に進行します。
- replicas: 50%
pause: {duration: 60} # 単位: 秒
# ステップ 3: すべての Pod を更新します。
- replicas: 100%
pause: {duration: 60} # 単位: 秒
kubectl apply -f rollout.yaml
ステップ 2: アップグレードのトリガー
echoserver.yaml のイメージバージョンを更新します。
# echoserver.yaml (関連セクション)
spec:
containers:
- name: echoserver
image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.3
env:
- name: NODE_NAME
value: version2 # オプション: 新バージョンの識別に役立ちます
kubectl apply -f echoserver.yaml
ステップ 3: ロールアウトステータスの確認
kubectl get rollouts rollouts-demo -n default
想定される出力:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE
rollouts-demo Progressing 1 StepPaused Rollout is in step(1/3), and you need manually confirm to enter the next step 41m
| フィールド | 値 | 意味 |
|---|---|---|
STATUS |
Progressing |
リリースが進行中 |
CANARY_STEP |
1 |
現在 3 ステップ中の 1 ステップ目 |
CANARY_STATE |
StepPaused |
ステップ 1 が完了し、手動承認を待機中 |
ステップ 4: バッチの承認と進行状況の監視
ステップ 1 を承認してステップ 2 に進みます。
kubectl-kruise rollout approve rollouts/rollouts-demo -n default
ロールアウトを監視します。
kubectl get rollouts rollouts-demo -n default -w
承認後、ロールアウトはステップ 2 (Pod 50%、一時停止 60 秒) とステップ 3 (すべての Pod、一時停止 60 秒) を進みます。主要な状態遷移:
CANARY_STATE |
意味 |
|---|---|
StepPaused |
バッチが完了し、手動承認または時間指定の自動一時停止を待機中 |
StepUpgrade |
このバッチで Pod をアップグレード中 |
StepReady |
バッチのアップグレードが完了 |
Completed |
すべてのステップが完了 |
STATUS=Healthy かつ CANARY_STATE=Completed になると、ロールアウトは完了です。
リリースのロールバック
新バージョンが意図しない動作をした場合は、以前の Deployment 構成を復元して再適用します。Rollout リソースの変更は不要です。
# echoserver.yaml (ロールバックバージョン)
spec:
containers:
- name: echoserver
image: openkruise-registry.cn-shanghai.cr.aliyuncs.com/openkruise/demo:1.10.2
env:
- name: NODE_NAME
value: version1
kubectl apply -f echoserver.yaml
次のステップ
-
Kruise Rollout API 仕様