サービスのアップグレード中にカナリアリリースを使用すると、システムの安定性を維持できます。ALB イングレスは、ヘッダー、Cookie、または重みに基づくカナリアアノテーションをサポートしています (優先度:ヘッダー > Cookie > 重み)。トラフィックの一部を本番環境の新しいバージョンのサービスにルーティングして検証し、準備が整ったら昇格させます。
前提条件
以下を完了してください:
-
ACK クラスターと同じ VPC 内の、異なるゾーンにある 2 つの vSwitch。 詳細については、「vSwitch の作成と管理」をご参照ください。
-
クラスターに ALB Ingress Controller がインストールされていること。詳細については、「ALB Ingress Controller の管理」をご参照ください。
ACK 専用クラスターの場合、クラスターに ALB イングレスへのアクセス権限を付与してください。詳細については、「ACK 専用クラスターに ALB イングレスコントローラーへのアクセス権限を付与する」をご参照ください。
-
AlbConfig が作成されました。「AlbConfig を作成する」をご参照ください。
-
kubectl が ACK クラスターに接続されていること。 詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
カナリアアノテーション
すべてのカナリア Ingress には、alb.ingress.kubernetes.io/canary: "true" アノテーションが必要です。これがない場合、カナリア Ingress は本番 Ingress と並行してルーティングされるのではなく、競合してしまいます。
これらのアノテーションはトラフィック分割を制御します:
| アノテーション | 説明 |
|---|---|
alb.ingress.kubernetes.io/canary |
Ingress がカナリアであることを示します。"true" に設定します。すべてのカナリア Ingress で必須です。 |
alb.ingress.kubernetes.io/canary-by-header |
一致させるリクエストヘッダーのキー。一致するリクエストはカナリアサービスにルーティングされます。 |
alb.ingress.kubernetes.io/canary-by-header-value |
一致させるヘッダーの値。canary-by-header が必要です。このアノテーションが設定されていない場合は無視されます。 |
alb.ingress.kubernetes.io/canary-weight |
ヘッダーまたは Cookie のルールに一致しない場合に、カナリアサービスに転送するトラフィックの割合 (0~100)。0 は転送なし、100 はすべて転送を意味します。 |
alb.ingress.kubernetes.io/order |
ルーティングルールの評価順序。有効な値は 1~1000 です。デフォルトは 10 です。値が小さいほど優先度が高くなります。このアノテーションがない場合、順序は Ingress の名前空間と名前の辞書順に従います。 |
ルール優先度:ヘッダーベース > Cookie ベース > 重みベース。
注意事項
-
ヘッダーベースおよび Cookie ベースのルールは、重みベースのルールと 1 つの Ingress を共有できません。別々の Ingress を使用するか、複雑な条件にはカスタムルーティングルールを使用してください。
-
カナリア Ingress のホストは、本番 Ingress のホストと完全に一致する必要があります。
-
複数のカナリア Ingress が同じホストを共有する場合、辞書順に頼るのではなく、
alb.ingress.kubernetes.io/orderを使用して明示的に優先度を設定してください。
ステップ 1:本番サービスのデプロイ
本番環境の Deployment、サービス、および Ingress をデプロイします。
-
tea-deploy.yamlを作成し、適用します:apiVersion: apps/v1 kind: Deployment metadata: name: tea spec: replicas: 1 selector: matchLabels: app: tea template: metadata: labels: app: tea spec: containers: - name: tea image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx:latest ports: - containerPort: 80kubectl apply -f tea-deploy.yaml -
tea-svc.yamlを作成し、適用します:apiVersion: v1 kind: Service metadata: name: tea-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: tea type: NodePortkubectl apply -f tea-svc.yaml -
tea-ingress.yamlを作成し、適用します:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - host: demo.domain.ingress.top # ご利用のドメイン名に置き換えてください。ロードバランサーの IP に解決される必要があります。 http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80kubectl apply -f tea-ingress.yaml
ステップ 2:カナリアサービスとルーティングルールのデプロイ
カナリアサービスを 2 つのカナリア Ingress と共にデプロイします。1 つはヘッダーに基づいてルーティングし、もう 1 つは残りのトラフィックを重みに基づいて分割します。
カナリア Ingress を適用する前に:
-
すべてのカナリア Ingress に
alb.ingress.kubernetes.io/canary: "true"を設定します。これがない場合、カナリア Ingress は本番 Ingress と競合します。 -
hostフィールドは、本番 Ingress のホスト (この例ではdemo.domain.ingress.top) と完全に一致する必要があります。 -
ヘッダーベースと重みベースのルールは、別々の Ingress に設定する必要があります。
-
canary-deploy.yamlを作成し、適用します:apiVersion: apps/v1 kind: Deployment metadata: name: canary spec: replicas: 1 selector: matchLabels: app: canary template: metadata: labels: app: canary spec: containers: - name: canary image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx:latest ports: - containerPort: 80kubectl apply -f canary-deploy.yaml -
canary-svc.yamlを作成し、適用します:apiVersion: v1 kind: Service metadata: name: canary-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: canary type: NodePortkubectl apply -f canary-svc.yaml -
ヘッダーベースのカナリア Ingress を作成します。
location: hzを持つリクエストはcanary-svcにルーティングされ、他のヘッダーは次のルールにフォールバックします。canary-header-ingress.yamlを作成し、適用します:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/canary: "true" alb.ingress.kubernetes.io/canary-weight: "50" name: canary-weight-ingress namespace: default spec: ingressClassName: alb rules: - host: demo.domain.ingress.top # 本番環境の Ingress ホストと完全に一致させる必要があります。 http: paths: - backend: service: name: canary-svc port: number: 80 path: / pathType: Prefixkubectl apply -f canary-header-ingress.yaml -
重みベースのカナリア Ingress を作成します。一致しないリクエストは、本番サービスとカナリアサービスの間で 50/50 に分割されます。
canary-weight-ingress.yamlを作成し、適用します:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/canary: "true" alb.ingress.kubernetes.io/canary-weight: "50" name: canary-weight-ingress namespace: default spec: ingressClassName: alb rules: - host: demo.domain.ingress.top # 本番 Ingress のホストと完全に一致する必要があります。 http: paths: - backend: service: name: canary-svc port: number: 80 path: / pathType: Prefixkubectl apply -f canary-weight-ingress.yaml
カナリアリリースの検証
-
ALB インスタンスのアドレスを取得します:
kubectl get ing期待される出力:
NAME CLASS HOSTS ADDRESS PORTS AGE canary-header-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 8m23s canary-weight-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 8m16s tea-ingress alb demo.domain.ingress.top alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com 80 7m5s -
location: hzを含むリクエストが常にカナリアに到達することを確認します:for i in $(seq 1 10); do curl -s -H "Host:demo.domain.ingress.top" -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com; done10 回の応答すべてが
newを返します。ヘッダールールは最も高い優先度を持ち、一致するすべてのリクエストをカナリアにルーティングします。 -
一致するヘッダーのないリクエストが約 50/50 に分割されることを確認します:
for i in $(seq 1 10); do curl -s -H "Host:demo.domain.ingress.top" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com; done応答は
new(カナリア) とold(本番) の間で交互に、ほぼ半分ずつ返されます。一致しないヘッダー (例:location: bj) も同じ重みベースの分割に従います。
ステップ 3: 新しいバージョンをプロモートする
カナリアが安定した後、すべての本番トラフィックを新しいサービスにリダイレクトし、カナリア Ingress を削除します。
-
tea-ingress.yamlを更新してcanary-svcを指すようにします:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - host: demo.domain.ingress.top http: paths: - path: / pathType: Prefix backend: service: name: canary-svc # tea-svc から変更。 port: number: 80kubectl apply -f tea-ingress.yaml -
カナリア Ingress を削除します:
kubectl delete ing canary-weight-ingress canary-header-ingress -
すべてのトラフィックが新バージョンに到達することを確認します:
for i in $(seq 1 10); do curl -s -H "Host:demo.domain.ingress.top" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com; done10 回の応答すべてが
newを返します。旧バージョンのサービスは完全に非推奨になりました。
次のステップ
-
HTTP から HTTPS へのリダイレクト、カスタムルーティングルールなどについては、「ALB Ingress の高度な設定」をご参照ください。
-
トラブルシューティングについては、「Ingress に関するよくある質問」をご参照ください。