標準的なカナリアリリースは、一度に 1 つのサービスのみを対象とします。上流サービスのカナリアバージョンが下流サービスを呼び出す場合、リクエストは下流のベースバージョンにフォールバックし、互換性がない可能性があります。エンドツーエンドカナリアリリースは、一部のサービスにカナリアデプロイメントがない場合でも、呼び出しチェーン内のすべてのサービスのカナリアバージョンを介してタグ付きトラフィックをルーティングすることで、この問題を解決します。Microservices Engine (MSE) は、サービス間の呼び出し全体でカナリアコンテキストを自動的に伝播します。Application Load Balancer (ALB) イングレスと組み合わせてゲートウェイでトラフィック分割を行うことで、ビジネスコードを変更することなくエンドツーエンドカナリアリリースを実現します。
仕組み
ALB Ingress は、ドメイン名によって受信トラフィックを分割し、カナリアトラフィックを最初のサービスのカナリアバージョンに送信します。その後、MSE は後続の各呼び出しを通じてカナリアタグを伝播するため、すべての下流サービスはリクエストを独自のカナリアバージョンにルーティングします。
この例での呼び出しフロー:
Client request --> ALB Ingress gateway --> Application A --> Application B --> Application C
-
www.aliyundoc.com へのリクエストは、
www.aliyundoc.comに送信され、ベース環境(すべてのアプリケーションの安定版)にルーティングされます。 -
www.example.comへのリクエストは、カナリア環境(すべてのアプリケーションのカナリアバージョン)に送信されます。
MSE は、エンドツーエンドカナリアリリースを次の 2 つの概念に基づいて整理します。
-
レーングループ -- 呼び出しチェーンに参加するアプリケーションのセット。
-
Lane — Lane グループ内のトラフィック隔離環境 (「canary」など) であり、各 Lane はたとえば
grayのようなタグで識別されます。
サンプルシナリオ
この例でのアプリケーションアーキテクチャ:
-
ALB Ingress ゲートウェイ -- イングレスレイヤーでトラフィックを分割します。
-
3 つの Spring Cloud アプリケーション -- トランザクションセンター (アプリケーション A)、商品センター (アプリケーション B)、在庫センター (アプリケーション C)。
-
Nacos -- アプリケーション間のサービス検出を処理します。
-
アクセス方法 -- クライアントベースまたは HTMLベース。
アプリケーション A は Spring Boot アプリケーションにすることができます。呼び出し順序は、ALB Ingress ゲートウェイ > アプリケーション A > アプリケーション B > アプリケーション C です。
ドメインベースルーティングは、ベース環境をカナリア環境から分離します。
| ドメイン | 環境 |
|---|---|
www.aliyundoc.com |
ベース (安定バージョン) |
www.example.com |
カナリア (新しいバージョン) |

注意事項
-
クラスターが Flannel ネットワークプラグインを使用している場合、ALB Ingress ゲートウェイのバックエンドサービスは NodePort または LoadBalancer タイプである必要があります。
-
ALB Ingress ゲートウェイの vSwitch は、Container Service for Kubernetes (ACK) クラスターと同じ Virtual Private Cloud (VPC) 内にある必要があります。サポートされているリージョンについては、「サポートされているリージョンとゾーン」をご参照ください。
前提条件
開始する前に、次のことを確認してください。
-
Kubernetes V1.18 以降を実行している ACK クラスター。詳細については、「ACK マネージドクラスターの作成」または「ACK 専用クラスターの作成 (廃止)」をご参照ください。
-
ACK クラスターに接続されている kubectl。詳細については、「クラスターの kubeconfig を取得し、kubectl を使用して接続する」をご参照ください。
-
クラスターにインストールされている ALB イングレス コントローラー コンポーネントです。クラスター作成時に、[ALB イングレス] を [Ingress] として [コンポーネント設定] ステップで選択してインストールするか、後から [アドオン] ページからインストールします。詳細については、「コンポーネントの管理」をご参照ください。
-
Microservice Governance ページで Microservices Governance Professional Edition がアクティブ化されていること。詳細については、「Microservices Governance の課金概要」をご参照ください。
-
ACK クラスター内のアプリケーションで MSE Microservices Governance が有効になっていること。詳細については、「ACK または ACS クラスター内の Java マイクロサービスアプリケーションで Microservices Governance を有効にする」をご参照ください。
MSE Microservices Governance を有効にする
名前空間レベルまたは単一アプリケーションで Microservices Governance を有効にします。
オプション 1: 名前空間で有効にする
-
MSE コンソールにログインし、上部のナビゲーションバーでリージョンを選択します。
-
左側のナビゲーションウィンドウで、[マイクロサービスガバナンス] > [アプリケーションガバナンス] を選択します。
-
[アプリケーションリスト] ページで、[ACK アプリケーションアクセス] をクリックします。
-
[ACK アプリケーションアクセス]ダイアログボックスで、以下のパラメーターを設定し、[OK]をクリックします。
| パラメーター | 説明 |
|---|---|
| クラスタータイプ | [ACK クラスター]、[ACK Serverless クラスター]、または [ACS クラスター] を選択します。ACK が MSE を呼び出す権限を付与していない場合は、[権限を付与してください] をクリックします。 |
| クラスター名/ID | ターゲットクラスターを選択します。必要に応じて、キーワードで検索してください。 |
| ack-onepilot | インストールステータスが表示されます。インストールされていない場合、クラスターを選択すると、システムによって自動的にインストールされます。必要な権限を持たない Resource Access Management (RAM) ユーザーを使用している場合は、ACK コンソールに移動し、クラスターの詳細を開き、[アドオン] をクリックして [ack-onepilot] を見つけ、[インストール] をクリックしてください。詳細については、「ack-onepilot コンポーネント」および「MSE マイクロサービスガバナンスコンポーネントのインストールとアップグレード」をご参照ください。 |
| アクセスタイプ | [名前空間アクセス] を選択します。 |
| クラスターの名前空間 | ターゲットの名前空間を選択します。 |
| マイクロサービスガバナンスの名前空間 | ガバナンス名前空間を選択します。 |
ack-onepilot がインストールされると、エージェントが自動的にインジェクトされ、アプリケーションの起動時間が最大 10 秒増加する場合があります。
クラスターが以下のリージョン(青島、杭州、北京、上海、上海-金融クラウド、深セン、香港 (中国)、シンガポール、フランクフルト、シドニー、シリコンバレー、またはバージニア)のいずれにも属していない場合、クラスターがインターネットにアクセスでき、acm.aliyun.com:8080 に接続できることを確認してください。
オプション 2: 単一アプリケーションで有効にする
-
MSE コンソールにログインし、上部のナビゲーションバーでリージョンを選択します。
-
左側のナビゲーションウィンドウで、[マイクロサービスガバナンス] > [アプリケーションガバナンス] を選択します。
-
[アプリケーションリスト] ページで、[ACK アプリケーションアクセス] をクリックします。
-
「ACK アプリケーションアクセス」ダイアログボックスで、次のパラメーターを設定し、[OK] をクリックします。
| パラメーター | 説明 |
|---|---|
| クラスタータイプ | ACK クラスター、ACK サーバーレスクラスター、または ACS クラスター を選択します。ACK による MSE の呼び出しをまだ許可していない場合は、権限を付与してください をクリックします。 |
| クラスター名/ID | 対象のクラスターを選択します。必要に応じてキーワードで検索できます。 |
| ack-onepilot | インストール状態を表示します。詳細については、上記の「オプション 1」をご参照ください。 |
| アクセスタイプ | 単一アプリケーションアクセス を選択します。 |
| アクセス手順 | 以下の手順に従って操作します。ACK コンソールで、ワークロード > デプロイメント に移動し、アプリケーションの名前空間に切り替えます。対象のアプリケーションを見つけ、YAML で表示 をクリックします。以下のラベルを追加し、更新 をクリックします。 |
spec:
template:
metadata:
labels:
# MSE ガバナンスを有効にするには "on" に設定します。値は二重引用符で囲む必要があります。
msePilotAutoEnable: "on"
# ガバナンス名前空間を指定します。名前空間が存在しない場合、自動的に作成されます。
mseNamespace: default
# MSE のアプリケーション名を指定します。名前は二重引用符で囲む必要があります。
msePilotCreateAppName: "your-deployment-name"
ステップ 1: デモアプリケーションをデプロイする
アプリケーション A、B、および C のベース版およびカナリーバージョン、およびサービス検出用の Nacos サーバーをデプロイします。各アプリケーションには、ベース版とカナリーバージョンの 2 つのデプロイメントがあり、カナリーバージョンには alicloud.service.tag: gray というタグが付いています。
-
ACK コンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
-
[クラスター] ページで、対象のクラスターを見つけ、その名前をクリックします。 左側のナビゲーションウィンドウで、[ワークロード] > [デプロイメント] を選択します。
-
名前空間を選択し、[YAML から作成] をクリックします。次の YAML コンテンツをコピーして、[作成] をクリックします。
# アプリケーション A (トランザクションセンター) のベースバージョン
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
labels:
msePilotCreateAppName: spring-cloud-a
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-governance-demo/spring-cloud-a:3.0.1
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# アプリケーション A のカナリアバージョン
# "alicloud.service.tag: gray" は、このデプロイメントをカナリアバージョンとして識別します。
# MSE はこのラベルを使用して、カナリアタグ付きトラフィックをこれらの Pod にルーティングします。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-a-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a-new
strategy:
template:
metadata:
labels:
# このラベルは、Pod が "gray" (カナリア) レーンに属していることを MSE に伝えます。
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
app: spring-cloud-a-new
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
# ダウンストリーム呼び出し全体でカナリアコンテキストの伝播を有効にします。
- name: profiler.micro.service.tag.trace.enable
value: "true"
image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-a:3.0.1
imagePullPolicy: Always
name: spring-cloud-a-new
ports:
- containerPort: 20001
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# アプリケーション B (商品センター) のベースバージョン
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
strategy:
template:
metadata:
labels:
msePilotCreateAppName: spring-cloud-b
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-governance-demo/spring-cloud-b:3.0.1
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# アプリケーション B のカナリアバージョン
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-b-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b-new
template:
metadata:
labels:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-b
app: spring-cloud-b-new
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-b:3.0.1
imagePullPolicy: Always
name: spring-cloud-b-new
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# アプリケーション C (在庫センター) のベースバージョン
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
labels:
msePilotCreateAppName: spring-cloud-c
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-governance-demo/spring-cloud-c:3.0.1
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 30
# アプリケーション C のカナリアバージョン
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-c-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c-new
template:
metadata:
labels:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-c
app: spring-cloud-c-new
spec:
containers:
- env:
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/spring-cloud-c:3.0.1
imagePullPolicy: IfNotPresent
name: spring-cloud-c-new
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 30
# サービス検出用の Nacos サーバー
---
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: registry.cn-hangzhou.aliyuncs.com/mse-governance-demo/nacos-server:v2.1.2
imagePullPolicy: Always
name: nacos-server
dnsPolicy: ClusterFirst
restartPolicy: Always
# Nacos サーバー Service
---
apiVersion: v1
kind: Service
metadata:
name: nacos-server
spec:
ports:
- port: 8848
protocol: TCP
targetPort: 8848
selector:
app: nacos-server
type: ClusterIP
ネットワーク設定を構成する
アプリケーション A 用に 2 つの Kubernetes Service を作成します。1 つはベースバージョン用、もう 1 つはカナリアバージョン用です。ALB Ingress はドメイン名に基づいてこれらの Service にトラフィックをルーティングします。
# アプリケーション A のベースバージョン用 Service
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-base
spec:
ports:
- name: http
nodePort: 32605
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
sessionAffinity: None
type: NodePort
---
# アプリケーション A のカナリアバージョン用 Service
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-gray
spec:
ports:
- name: http
nodePort: 31622
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a-new
sessionAffinity: None
type: NodePort
ステップ 2: ALB Ingress ルーティングを構成する
-
AlbConfig オブジェクトを作成します。詳細については、「AlbConfig オブジェクトの作成」をご参照ください。
重要ALB Ingress ゲートウェイの vSwitch は、クラスターと同じ VPC 内にある必要があります。そうでない場合、ご利用のビジネスに悪影響を受けます。
-
Ingress リソースを作成します。以下の YAML を
gray-ingress.yamlとして保存します。-
Kubernetes V1.19 より前のバージョンを実行しているクラスターの場合:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: demo namespace: default spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: - path: /a backend: serviceName: spring-clud-a-base servicePort: 20001 - host: www.example.com http: paths: - backend: serviceName: spring-cloud-a-gray servicePort: 20001 path: /a pathType: ImplementationSpecific -
Kubernetes V1.19 以降のバージョンを実行しているクラスターの場合:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress spec: ingressClassName: alb rules: - host: www.aliyundoc.com http: paths: - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base port: number: 20001 - host: www.example.com http: paths: - path: /a pathType: ImplementationSpecific backend: service: name: spring-clud-a-base-gray port: number: 20001
-
-
Ingress リソースを適用します。
kubectl apply -f gray-ingress.yaml

出力の ADDRESS フィールドが空の場合、Ingress 詳細ページでイベントを確認し、前提条件を見直してトラブルシューティングしてください。
ステップ 3: MSE コンソールでレーングループとレーンを作成する
-
MSE コンソールにログインし、上部のナビゲーションバーでリージョンを選択します。
-
左側のナビゲーションウィンドウで、[マイクロサービスガバナンス] > [フルリンク グレースケール] を選択します。
-
[レーン グループとレーンを作成。] をクリックします。レーン グループがすでに存在する場合は、[+] をクリックし、[レーン グループを作成] を選択します。
-
「[Create Lane Group]」パネルで、3つのアプリケーション —
spring-cloud-a、spring-cloud-b、およびspring-cloud-c— を追加し、「[OK]」をクリックします。 -
[フルリンクグレースケール] ページの下部で、[最初の分割レーンを作成] をクリックします。[レーンの作成] パネルで、タグ [グレー] を選択し、[OK] をクリックします。
結果を確認する
テストリクエストを送信して、呼び出しチェーン全体でトラフィックが正しく流れることを確認します。
ベース環境ルーティングを確認する:
curl -H"Host:aliyundoc.base.com" http://<alb-endpoint>/a
期待される出力:
A[172.18.XX.XX] -> B[172.18.XX.XX] -> C[172.18.XX.XX]%
アプリケーション名に "gray" サフィックスがないため、3 つのサービスすべてがベースバージョンを使用してリクエストを処理したことを確認できます。
カナリア環境ルーティングを確認する:
curl -H"Host:www.example.com" http://<alb-endpoint>/a
期待される出力:
Agray[172.18.XX.XX] -> Bgray[172.18.XX.XX] -> Cgray[172.18.XX.XX]%
各アプリケーション名の "gray" サフィックスは、MSE がアプリケーション A から B、C への呼び出しチェーン全体でカナリアコンテキストを伝播したことを確認します。これは、ALB レイヤーでのドメインベースルーティングと MSE レイヤーでのレーンベースルーティングの両方が正しく機能していることを証明します。
<alb-endpoint> を実際の ALB イングレス ゲートウェイエンドポイント(例: alb-828vagckg5omzfy49n.cn-beijing.alb.aliyuncs.com)に置き換えます。このエンドポイントは、kubectl get ingress の出力で確認できます。