Kubernetes アプリケーションデプロイメントツールとして、Kruise Rollouts は、カナリアリリースやブルーグリーンデプロイメントなど、さまざまなカナリアリリースポリシーを提供します。 Kruise Rollouts を Microservices Engine (MSE) マイクロサービスガバナンスと共に使用して、サービス呼び出しプロセス中にアプリケーションの新しいバージョンのスムーズなカナリアリリースを実装できます。 これにより、新しいバージョンの安定性が確保されます。
エンドツーエンドカナリアリリースの概要
従来のカナリアリリースモードでは、マイクロサービスアーキテクチャが使用されているシナリオでの複雑な配信要件を満たすことができません。 エンドツーエンドカナリアリリース機能は、各マイクロサービスアプリケーションのカナリアトラフィックをカナリア環境またはグループにルーティングするために導入されました。 開発者は、トラフィックがアップストリームカナリア環境からダウンストリームカナリア環境に流れることを期待しています。 このようにして、リクエストはカナリア環境内に残り、トラフィックレーンが生成されます。 トラフィックレーンでは、呼び出しプロセスに含まれる一部のマイクロサービスアプリケーションにそれぞれのカナリア環境がない場合でも、これらのマイクロサービスアプリケーションのリクエストをダウンストリームカナリア環境にルーティングできます。 この場合、システムの安定性を確保するために、複数のサービスへの変更を同時にリリースできます。 次の図は、エンドツーエンドカナリアリリースのプロセスを示しています。

Kruise Rollouts の概要
Kruise Rollouts は、OpenKruise によって提供されるオープンソースのプログレッシブロールアウトフレームワークです。 詳細については、「Kruise Rollouts」をご参照ください。 Kruise Rollouts を使用して、カナリアリリース、ブルーグリーンデプロイメント、A/B テストを実行できます。 また、Kruise Rollouts を使用して、カナリアトラフィックとポッドを制御することもできます。 リリースプロセスはバッチで自動化し、Managed Service for Prometheus のメトリックに基づいて一時停止できます。 Kruise Rollouts はバイパスの認識できない接続も提供し、Deployments、CloneSets、StatefulSets など、さまざまなワークロードと互換性があります。 詳細については、「Kruise Rollouts」をご参照ください。
Kruise Rollouts はバイパスコンポーネントです。 Container Service for Kubernetes (ACK) クラスタに Rollouts リソースを作成するだけで、アプリケーションのリリースと更新を自動化できます。 Kruise Rollouts は、Helm および PaaS プラットフォームとの低コストでのシームレスな統合をサポートしています。 次の図は、Kruise Rollouts を使用したカナリアリリースのアーキテクチャを示しています。
手順 1: 準備を行う
Kruise Rollouts コンポーネントをインストールします。
ACK コンソール にログインします。 左側のナビゲーションペインで、[クラスタ] をクリックします。
[クラスタ] ページで、管理するクラスタを見つけて、その名前をクリックします。 左側のナビゲーションペインで、 を選択します。
コンポーネントの管理 ページで、アプリケーションの管理 タブをクリックします。
[ack-kruise] カードを見つけて、[インストール] をクリックします。
表示されるメッセージで、[OK] をクリックします。
MSE Ingress Controller コンポーネントをインストールします。 MseIngressConfig リソースと IngressClass リソースを作成します。 詳細については、「MSE Ingress を使用して ACK クラスタ内のアプリケーションにアクセスする」をご参照ください。
アプリケーションのマイクロサービスガバナンスを有効にします。 詳細については、「ACK クラスタ内のマイクロサービスアプリケーションのマイクロサービスガバナンスを有効にする」をご参照ください。
手順 2: デモアプリケーションをデプロイする
デプロイメント、サービス、および Ingress リソースを作成します。
mse-demo.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
コードの表示
# サービス
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a
spec:
ports:
- name: http
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
# アプリケーション a
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a # アプリケーション名を設定
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.0
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
# アプリケーション b
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-b # アプリケーション名を設定
labels:
app: spring-cloud-b
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-b:mse-2.0.0
imagePullPolicy: Always
name: spring-cloud-b
# アプリケーション c
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-c # アプリケーション名を設定
labels:
app: spring-cloud-c
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.0
imagePullPolicy: Always
name: spring-cloud-c
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nacos-server
spec:
replicas: 1
selector:
matchLabels:
app: nacos-server
template:
metadata:
labels:
app: nacos-server
spec:
containers:
- env:
- name: MODE
value: standalone
image: nacos/nacos-server:v2.2.0
imagePullPolicy: Always
name: nacos-server
dnsPolicy: ClusterFirst
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: nacos-server
spec:
type: ClusterIP
ports:
- name: nacos-server-8848-8848
port: 8848
protocol: TCP
targetPort: 8848
- name: nacos-server-9848-9848
port: 9848
protocol: TCP
targetPort: 9848
selector:
app: nacos-server
---
apiVersion: v1
kind: Service
metadata:
labels:
app: demo-mysql
name: demo-mysql
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: demo-mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-mysql
spec:
selector:
matchLabels:
app: demo-mysql
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: demo-mysql
spec:
containers:
- args:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
env:
- name: MYSQL_ROOT_PASSWORD
value: root
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/demo-mysql:3.0.1
name: demo-mysql
ports:
- containerPort: 3306
次のコマンドを実行して、ビジネスアプリケーションをデプロイします。
kubectl apply -f mse-demo.yaml
mse-Ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
コードの表示
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
mse.ingress.kubernetes.io/service-subset: ""
name: spring-cloud-a
spec:
ingressClassName: mse
rules:
- http:
paths:
- backend:
service:
name: spring-cloud-a
port:
number: 20001
path: /
pathType: Prefix
次のコマンドを実行して、Ingress ルールを作成します。
kubectl apply -f mse-ingress.yaml
次のコマンドを実行して、パブリック IP アドレスをクエリします。
kubectl get ingress
期待される出力:
NAME CLASS HOSTS ADDRESS PORTS AGE
spring-cloud-a <none> * EXTERNAL_IP 80 12m
次のコマンドを実行して、ルートステータスを確認します。 <EXTERNAL_IP> は、前の手順で取得した IP アドレスに置き換えます。
curl http://<EXTERNAL_IP>/A/a
期待される出力:
A[192.168.42.115][config=base] -> B[192.168.42.118] -> C[192.168.42.101]%
手順 3: Kruise Rollouts を使用して自動エンドツーエンドカナリアリリースを実装する
Kruise Rollouts のカナリアリリースルールを定義します。
説明 この例では、カナリアリリースは 3 つのバッチで実行されます。
A/B テストが実行されます。 header[User-Agent]=xiaoming を含むリクエストはカナリアバージョンに転送されます。 その他のリクエストはベースバージョンに転送されます。
ポッドの半分がカナリアバージョンを実行し、リクエストの半分がカナリアバージョンに転送されます。
すべてのポッドがカナリアバージョンを実行し、すべてのリクエストがカナリアバージョンに転送されます。
rollout.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
コードの表示
# エンドツーエンドカナリアリリースのアプリケーションのロールアウト構成を指定します。
# ロールアウト構成 a
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
# rollout-b や rollout-c など、他のマイクロサービスアプリケーションの同様の構成。
name: rollout-a
annotations:
rollouts.kruise.io/trafficrouting: mse-traffic
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: spring-cloud-a
strategy:
canary:
steps:
- pause: {} # 最初の手順の後で一時停止します。
replicas: 1 # カナリアレプリカの数を 1 に設定します。
patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
labels:
alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
---
# ロールアウト構成 b
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollout-b
annotations:
rollouts.kruise.io/trafficrouting: mse-traffic
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: spring-cloud-b
strategy:
canary:
steps:
- pause: {} # 最初の手順の後で一時停止します。
replicas: 1 # カナリアレプリカの数を 1 に設定します。
patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
labels:
alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
---
# ロールアウト構成 c
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollout-c
annotations:
rollouts.kruise.io/trafficrouting: mse-traffic
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: spring-cloud-c
strategy:
canary:
steps:
- pause: {} # 最初の手順の後で一時停止します。
replicas: 1 # カナリアレプリカの数を 1 に設定します。
patchPodTemplateMetadata: # カナリアポッドのメタデータにパッチを適用します。
labels:
alicloud.service.tag: gray # カナリアポッドにラベルを追加します。
opensergo.io/canary-gray: gray # カナリアポッドにラベルを追加します。
---
# レーンに基づいてエンドツーエンドカナリアリリースを構成します。
apiVersion: rollouts.kruise.io/v1alpha1
kind: TrafficRouting
metadata:
name: mse-traffic
spec:
objectRef:
- service: spring-cloud-a
ingress:
classType: mse
name: spring-cloud-a
strategy:
matches:
# A/B テストを実行します。 トラフィックはリクエストヘッダーに基づいてルーティングされます。
- headers:
- type: Exact
name: User-Agent
value: xiaoming
# リクエストの半分がカナリアバージョンに転送されます。
# weight 値は 30 です。 リクエストの 30% がカナリアバージョンに転送されます。
requestHeaderModifier: # リクエストヘッダーを変更します。
set:
- name: x-mse-tag # ヘッダー名を設定します。
value: gray # ヘッダー値を設定します。
次のコマンドを実行して、ACK クラスタに Rollouts リソースをデプロイします。
kubectl apply -f rollout.yaml
次のコマンドを実行して、Rollouts リソースのステータスをクエリします。
kubectl get rollout
STATUS=Healthy が期待どおりに返された場合、Rollouts リソースは正しく動作しています。
アプリケーションを更新します。
Kruise Rollouts は共通の構成であり、クラスタに配布するだけで済みます。 新しいアプリケーションバージョンをリリースするには、デプロイメントを更新するだけで済みます。 Kruise Rollouts を再度構成する必要はありません。 たとえば、spring-cloud-a と spring-cloud-c のイメージバージョンを mse-2.0.1 に直接更新してから、kubectl apply -f mse-demo.yaml コマンドを実行して、デプロイメントをクラスタにデプロイできます。 kubectl に加えて、Helm または Vela を使用してデプロイメントをクラスタにデプロイできます。
mse-demo.yaml ファイルを変更して、spring-cloud-a と spring-cloud-c のイメージバージョンを mse-2.0.1 に更新します。
コードの表示
# アプリケーション a
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-a
...
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.1 # イメージバージョンを更新
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
...
# アプリケーション c
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c
spec:
...
image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.1 # イメージバージョンを更新
次のコマンドを実行して、Rollouts リソースのステータスをクエリします。
kubectl get rollouts rollouts-a -n default
kubectl get rollouts rollouts-c -n default
期待される出力:
NAME STATUS CANARY_STEP CANARY_STATE MESSAGE AGE
rollouts-a Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m
rollouts-c Progressing 1 StepPaused Rollout is in step(1/1), and you need manually confirm to enter the next step 41m
STATUS 列と CANARY_STATE 列を確認して、Rollouts リソースのステータスとリリースステージを表示できます。
カナリアバージョンが期待どおりに実行されていることを確認したら、残りのバッチをリリースできます。
前の手順では、カナリアバージョンのアプリケーションの一部のみをリリースし、リクエストの一部をカナリアバージョンに転送します。 アプリケーションログとメトリックデータに基づいてカナリアバージョンが期待どおりに実行されていることを確認したら、rollout.rollouts.kruise.io/<rollouts-demo> approved コマンドを実行して、カナリアバージョンの残りのアプリケーションをリリースできます。 <rollouts-demo> は、Rollouts リソースの名前を示します。
オプション。 新しいアプリケーションバージョンが期待どおりに実行されない場合は、アプリケーションバージョンをロールバックします。
リリースプロセス中にカナリアバージョンが期待どおりに実行されない場合は、デプロイメント構成を変更してから、kubectl apply -f mse-demo.yaml コマンドを実行して、アプリケーションバージョンをロールバックします。 Rollouts リソースで変更操作を実行する必要はありません。
マイクロサービスガバナンスのエンドツーエンドカナリアリリース機能はレーンを提供し、テストとリリース中の検証を大幅に容易にします。 マイクロサービスガバナンスを Kruise Rollouts と共に使用することで、DevOps プロセスにおけるオンラインアプリケーションの安定性を大幅に向上させることができます。