カナリアリリースは、一般的に使用されるソフトウェアリリース戦略です。サービスのイテレーション中に本番環境でシステムの安定性を確保するために、新しいサービスバージョンをすべてのユーザーに段階的にプッシュできます。Application Load Balancer (ALB) Ingress を使用すると、カナリアアノテーションを使用して、ヘッダー、Cookie、および重みに基づいてカナリアリリースを実行できます。このトピックでは、カナリアリリースを実行するために ALB Ingress にカナリアアノテーションを追加する方法について説明します。
前提条件
ACS クラスタが作成されていること。詳細については、ACS クラスタの作成を参照してください。
ALB Ingress コントローラーが ACS クラスタにインストールされていること。詳細については、ALB Ingress コントローラーの管理を参照してください。
AlbConfig と IngressClass が作成されていること。詳細については、AlbConfig の作成とIngressClass の作成を参照してください。
ACS クラスタに接続していること。詳細については、クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続するとCloud Shell で kubectl を使用して ACS クラスタを管理するを参照してください。
注意事項
カナリアアノテーションに基づいて実装されたカナリアリリース規則の優先順位は、ヘッダー > Cookie > 重みです。上記のポリシーがすべて設定されている場合、ヘッダーベースの規則が優先的に使用されます。カナリアアノテーションの詳細については、ALB Ingress カナリアアノテーションを参照してください。
ヘッダーベースおよび Cookie ベースの規則は、同じ Ingress で重みベースの規則と設定することはできません。2 つの別々の Ingress で設定するか、カスタムルーティング規則を使用する必要があります。カスタムルーティング規則を使用すると、より複雑なルーティング条件に基づいてカナリアリリースを実行できます。詳細については、ALB Ingress のルーティング規則のカスタマイズを参照してください。
カナリアアノテーションを使用してカナリアリリースを実行する場合、ALB Ingress ルーティング規則が有効になる順序は、
Ingress の名前空間または名前
の辞書順によって異なります。カナリアリリース規則が正しい順序で適用されるようにするには、alb.ingress.kubernetes.io/order
アノテーションを使用して順序を定義できます。alb.ingress.kubernetes.io/order
の有効な値は 1 ~ 1000 です。デフォルト値は 10 です。値が小さいほど、優先順位が高くなります。たとえば、Ingress の優先順位を上げる場合は、alb.ingress.kubernetes.io/order
設定の値を小さくすることができます。
手順 1: アプリケーションを作成する
tea という名前のサービスをデプロイします。
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: 80
次のコマンドを実行して、tea サービスをデプロイします。
kubectl apply -f tea-deploy.yaml
tea-svc という名前のサービスをデプロイします。
tea-svc.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1 kind: Service metadata: name: tea-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: tea type: ClusterIP
次のコマンドを実行して、tea-svc サービスをデプロイします。
kubectl apply -f tea-svc.yaml
tea-ingress という名前の Ingress をデプロイします。
tea-ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - host: demo.domain.ingress.top # ドメイン名に置き換え、Ingress コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。 http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f tea-ingress.yaml
デプロイが成功したことを確認します。
次のコマンドを実行して、サービスにアクセスします。
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
予期される出力:
old
手順 2: 新しいサービスバージョンのカナリアリリースを実行する
新しいサービスバージョンと新しい Ingress をデプロイして、location: hz
ヘッダーを持つすべてのリクエストを canary という名前の新しいサービスバージョンにルーティングし、他のリクエストの 50% を新しいサービスバージョンにルーティングします。他のリクエストには、他のヘッダーを持つリクエストとヘッダーを持たないリクエストが含まれます。
canary という名前の新しいサービスバージョンをデプロイします。
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: 80
次のコマンドを実行して、canary サービスをデプロイします。
kubectl apply -f canary-deploy.yaml
canary-svc という名前のサービスをデプロイします。
canary-svc.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1 kind: Service metadata: name: canary-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: canary type: ClusterIP
次のコマンドを実行して、canary-svc サービスをデプロイします。
kubectl apply -f canary-svc.yaml
ヘッダーに基づいてリクエストをルーティングする Ingress をデプロイします。
canary-header-ingress.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/canary: "true" alb.ingress.kubernetes.io/canary-by-header: "location" alb.ingress.kubernetes.io/canary-by-header-value: "hz" name: canary-header-ingress namespace: default spec: ingressClassName: alb rules: - host: demo.domain.ingress.top # ドメイン名に置き換え、Ingress コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。 http: paths: - backend: service: name: canary-svc port: number: 80 path: / pathType: Prefix
alb.ingress.kubernetes.io/canary を true に設定して、カナリアアノテーションを有効にします。
alb.ingress.kubernetes.io/canary-by-header および alb.ingress.kubernetes.io/canary-by-header-value を、一致させたいヘッダーのキーと値に設定します。この例では、ヘッダーの KV ペアは
location: hz
に設定されています。location: hz
ヘッダーを持つすべてのリクエストは、新しいサービスバージョンにルーティングされます。他のヘッダーを持つリクエストは、規則の優先順位に基づいて他のカナリアリリース規則と照合され、一致する規則に関連付けられたサービスバージョンにルーティングされます。
次のコマンドを実行して、ヘッダーに基づいてリクエストをルーティングする Ingress をデプロイします。
kubectl apply -f canary-header-ingress.yaml
重みに基づいてリクエストをルーティングする Ingress をデプロイします。
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 コントローラーが存在するロードバランサーの IP アドレスに解決できることを確認します。 http: paths: - backend: service: name: canary-svc port: number: 80 path: / pathType: Prefix
alb.ingress.kubernetes.io/canary-weight: 新しいサービスバージョンにルーティングされるトラフィックの割合を指定します。この例では、値は 50 に設定されており、トラフィックの 50% が新しいサービスバージョンにルーティングされることを示しています。
次のコマンドを実行して、重みに基づいてリクエストをルーティングする Ingress をデプロイします。
kubectl apply -f canary-weight-ingress.yaml
カナリアリリースが成功したかどうかを確認します。
次のコマンドを実行して、ALB インスタンスの IP アドレスをクエリします。
kubectl get ingress
予期される出力:
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
ヘッダーをサービスに送信するリクエストを送信します。curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
予期される出力:
new
new
は、location: hz
ヘッダーを持つリクエストに対して返されます。location: hz
ヘッダーを持つリクエストは、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、ヘッダーを含まないリクエストをサービスに送信します。
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
new
は、ヘッダーを含まないリクエストの 50% に対して返され、old
は、残りの 50% のリクエストに対して返されます。ヘッダーを含まないリクエストの 50% は、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、
location: bj
ヘッダーを含むリクエストをサービスに送信します。curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
new
は、location: bj
ヘッダーを含むリクエストの 50% に対して返され、old
は残りの 50% のリクエストに対して返されます。location: bj
ヘッダーを含むリクエストの 50% は、新しいサービスバージョンにルーティングされます。
location: hz
ヘッダーを持つすべてのリクエストは、canary という名前の新しいサービスバージョンにルーティングされます。他のヘッダーを持ち、ヘッダーを持たないリクエストの50%のみが新しいサービスバージョンにルーティングされます。カナリアリリースは成功しました。
ステップ 3: 古いサービスバージョンの廃止
新しいサービスバージョンが一定期間期待どおりに動作したら、古いサービスバージョンを廃止し、新しいサービスバージョンのみを維持する必要があります。これを行うには、古いサービスバージョンのイングレスのサービスを新しいサービスバージョンに変更して、イングレスが新しいサービスバージョンにトラフィックをルーティングできるようにする必要があります。次に、カナリアイングレスを削除します。
次のコマンドを実行して、tea-ingress.yaml ファイルを変更します。
vim tea-ingress.yaml
次のコマンドを実行して、tea-ingress.yaml ファイルのサービスを tea-svc から canary-svc に変更します。
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: canary-svc # tea-svc を canary-svc に変更します。 port: number: 80
変更したイングレスを有効にするには、次のコマンドを実行します。
kubectl apply -f tea-ingress.yaml
古いサービスバージョンが廃止されているかどうかを確認します。
次のコマンドを複数回実行して、
location: hz
ヘッダーを含むリクエストをサービスに送信します。curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
予期される出力:
new
new
がlocation: hz
ヘッダーを含むリクエストに対して返されます。location: hz
ヘッダーを含むリクエストは、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、ヘッダーを含まないリクエストをサービスに送信します。
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
予期される出力:
new
new
がヘッダーを含まないリクエストに対して返されます。ヘッダーを含まないリクエストは、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、
location: bj
ヘッダーを含むリクエストをサービスに送信します。curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com
予期される出力:
new
new
がlocation: bj
ヘッダーを含むリクエストに対して返されます。location: bj
ヘッダーを含むリクエストは、新しいサービスバージョンにルーティングされます。
location: hz
ヘッダーを含むリクエスト、他のヘッダーを含むリクエスト、およびヘッダーを含まないリクエストはすべて、新しいサービスバージョンにルーティングされます。古いサービスバージョンは廃止されました。次のコマンドを実行して、canary-weight-ingress と canary-header-ingress という名前のカナリアイングレスを削除します。
kubectl delete ingress canary-weight-ingress canary-header-ingress