サービスの反復およびアップグレードのプロセス中に、システムの安定性を確保するためにカナリアリリースが必要です。 Application Load Balancer (ALB) Ingressは、カナリアアノテーションを使用して、ヘッダー、Cookie、および重みに基づいてカナリアリリースを実装することをサポートしています。 異なるルールを使用するカナリアリリースは、ヘッダーベース> クッキーベース> 重みベースの順に有効になります。 ヘッダーベース、cookieベース、および重みベースのルールを同時に設定すると、優先度が最も高いルールがカナリアリリースに最初に適用されます。
前提条件
異なるゾーンに存在する2つのvSwitchが作成され、ACKクラスターと同じ仮想プライベートクラウド (VPC) にデプロイされます。 詳細については、「vSwitchの作成と管理」をご参照ください。
ALB Ingressコントローラーがクラスターにインストールされています。 詳細については、「ALB Ingressコントローラーの管理」をご参照ください。
説明ALB Ingressを使用してACK専用クラスターにデプロイされたサービスにアクセスするには、まずALB Ingressコントローラーが必要とする権限をクラスターに付与する必要があります。 詳細については、「ACK専用クラスターにALB Ingressコントローラーへのアクセスを許可する」をご参照ください。
AlbConfigが作成されます。 詳細については、「AlbConfigの作成」をご参照ください。
kubectlクライアントがACKクラスターに接続されています。 詳細については、「クラスターのkubeconfigファイルを取得し、kubectlを使用してクラスターに接続する」をご参照ください。
使用上の注意
ヘッダーベースとクッキーベースのルールは、同じIngressで重みベースのルールを設定することはできません。 2つの別々のIngressでそれらを設定するか、カスタムルーティングルールを使用する必要があります。
カナリアアノテーションを使用してカナリアリリースを実行する場合、ALB Ingressルーティングルールが有効になる順序は、
Ingress名前空間または名前の辞書式順序によって異なります。 カナリアリリースルールが正しい順序で適用されるようにするには、alb.ingress.kubernetes.io/orderアノテーションを使用して順序を定義します。alb.ingress.kubernetes.io/orderの有効な値は1 ~ 1000です。 デフォルト値は 10 です。 値が小さいほど、優先度が高くなります。 たとえば、Ingressの優先度を上げたい場合は、そのalb.ingress.kubernetes.io/order設定の値を減らすことができます。カスタムルーティングルールを使用して、より複雑なルーティング条件に基づいてカナリアリリースを実行できます。 詳細については、「ALB Ingressのルーティングルールのカスタマイズ」をご参照ください。
ステップ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: NodePort次のコマンドを実行して、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 # Replace with your domain name and ensure that it can be resolved to the IP address of the load balancer where the Ingress controller resides. http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80次のコマンドを実行してIngressをデプロイします。
kubectl apply -f tea-ingress.yaml
ステップ2: 新しいサービスバージョンのカナリアリリースを実行する
リクエストヘッダーがlocation: hzの場合、トラフィックが新しいバージョンのcanary Serviceにルーティングされるように、新しいバージョンのServiceと新しいIngressをデプロイします。 他のヘッダーを含む、またはヘッダーを含まないリクエストは、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次のコマンドを実行してカナリアサービスをデプロイします。
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: NodePort次のコマンドを実行して、canary-svc Serviceをデプロイします。
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 # Replace with your domain name and ensure that it can be resolved to the IP address of the load balancer where the Ingress controller resides. 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 # Replace with your domain name and ensure that it can be resolved to the IP address of the load balancer where the Ingress controller resides. http: paths: - backend: service: name: canary-svc port: number: 80 path: / pathType: Prefixalb.ingress.kubernetes.io/canary-weight: 新しいサービスバージョンにルーティングされるトラフィックの割合を指定します。 この例では、値は50に設定されています。これは、トラフィックの50% が新しいサービスバージョンにルーティングされることを示します。
次のコマンドを実行して、Ingressをデプロイし、重みに基づいてリクエストをルーティングします。
kubectl apply -f canary-weight-ingress.yaml
カナリアリリースが成功したかどうかを確認します。
次のコマンドを実行して、ALBインスタンスのIPアドレスを照会します。
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ヘッダーをサービスに送信するリクエストを送信します。curl -H Host:demo.domain.ingress.top -H "location:hz" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.com期待される出力:
newlocation: hzヘッダーを持つリクエストに対してnewが返されます。location: hzヘッダーを持つリクエストは、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、ヘッダーを含まないリクエストをサービスに送信します。
curl -H Host:demo.domain.ingress.top http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.comnewはヘッダーを持たないリクエストの50% に対して返され、oldはリクエストの残りの50% に対して返されます。 ヘッダーを持たないリクエストの50% は、新しいサービスバージョンにルーティングされます。次のコマンドを複数回実行して、
location: bjヘッダーを含むリクエストをサービスに送信します。curl -H Host:demo.domain.ingress.top -H "location:bj" http://alb-ny3ute4r8yevni****.cn-chengdu.alb.aliyuncs.comnewは、location: bjヘッダを搬送する要求の50% に対して返され、oldは、要求の残りの50% に対して返される。location: bjヘッダーを運ぶ要求の50% は、新しいサービスバージョンにルーティングされます。
location: hzヘッダーを持つすべてのリクエストは、canaryという名前の新しいサービスバージョンにルーティングされます。 他のヘッダーを運び、ヘッダーを運ばない50% のリクエストのみが、新しいサービスバージョンにルーティングされます。 カナリアのリリースは成功しました。
ステップ3: 古いサービスバージョンを廃止する
新しいサービスバージョンが一定期間、期待どおりに実行されたら、古いサービスバージョンを廃止し、新しいサービスバージョンのみを保持する必要があります。 これを行うには、古いサービスバージョンのIngressのサービスを新しいサービスバージョンに変更して、Ingressが新しいサービスバージョンにトラフィックをルーティングできるようにする必要があります。 次に、カナリアIngressを削除します。
次のコマンドを実行して、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 # Replace with your domain name and ensure that it can be resolved to the IP address of the load balancer where the Ingress controller resides. http: paths: - path: / pathType: Prefix backend: service: name: canary-svc # Change tea-svc to canary-svc. port: number: 80変更されたIngressを有効にするには、次のコマンドを実行します。
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期待される出力:
newlocation: hzヘッダーを持つリクエストに対してnewが返されます。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期待される出力:
newlocation: bjヘッダーを持つリクエストに対して、newが返されます。location: bjヘッダーを持つリクエストは、新しいサービスバージョンにルーティングされます。
location: hzヘッダーを運ぶリクエスト、他のヘッダーを運ぶリクエスト、およびヘッダーを運ばないリクエストはすべて、新しいサービスバージョンにルーティングされます。 古いサービスバージョンは非推奨です。次のコマンドを実行して、canary-weight-ingressおよびcanary-header-ingressという名前のcanary ingressを削除します。
kubectl delete ing canary-weight-ingress canary-header-ingress