LoadBalancer Service を使用してバックエンド Pod を公開すると、ローリングアップデートによってサービスが中断されることがあります。この問題は、Pod がロードバランサーのバックエンドサーバーグループに登録されるよりも速く更新される場合に発生します。readiness gate を設定することで、Pod の更新をスムーズに行うことができます。このトピックでは、readiness gate 機能を使用して Pod の更新をスムーズに行う方法について説明します。
前提条件
-
次の要件を満たす ACK マネージドクラスターまたは ACK サーバーレスクラスターが必要です。詳細については、「ACKマネージドクラスターの作成」および「ACKサーバーレスクラスターの作成」をご参照ください。
-
ACK マネージドクラスターを使用している場合、ネットワークプラグインは Terway である必要があります。
-
クラスターのバージョンは 1.24 以降です。詳細については、「クラスターをアップグレードする」をご参照ください。
-
cloud-controller-manager コンポーネントは v2.10.0 以降です。詳細については、「Cloud Controller Manager」をご参照ください。
-
自動 readiness gate 注入機能を使用するには、cloud-controller-manager コンポーネントが v2.12.4 以降であり、コンポーネントのパラメーターで Pod ReadinessGate Webhook 機能が有効になっていることを確認してください。 Cloud Controller Manager の [パラメーター設定] セクションで、[Pod ReadinessGate Webhook 機能を有効にする] チェックボックスを選択し、次に [確認] をクリックします。
-
kubectlクライアントがACKクラスターに接続されています。 詳細については、「クラスターのkubeconfigファイルを取得し、kubectlを使用してクラスターに接続する」をご参照ください。
背景情報
LoadBalancer Service を使用してアプリケーションを公開し、ローリングアップデートを実行すると、短時間のサービス中断や接続障害が発生することがあります。
-
原因
新しい Pod の起動は、多くの場合、ロードバランサーによるバックエンドサーバーリストの更新よりも速く行われます。新しい Pod のコンテナの準備が整っても、その IP アドレスがまだロードバランサーのバックエンドに追加されていないうちに、ローリングアップデートプロセスが古い Pod の終了を開始してしまうことがあります。その結果、一部のトラフィックが、終了中または既にロードバランサーから削除された古い Pod に引き続きルーティングされ、接続障害につながります。
-
解決策
ポッドの YAML 設定で Pod Readiness Gate メカニズムを使用して、カスタム条件でその Ready 状態を制御できます。このレディネスゲートでは、LoadBalancer サービス用の
service.readiness.alibabacloud.com/<Service Name>のようなカスタム条件を設定できます。これらの条件が満たされた場合にのみ、ポッドはReadyとマークされ、トラフィックの受信を開始します。 -
手順例
-
仕組み
Pod に
readinessGatesが設定されている場合、その準備完了プロセスは次のようになります。-
コンテナプローブの準備:kubelet がコンテナの
readinessProbeを実行します。プローブが成功すると、Pod のContainersReadyステータスがTrueに変わります。この時点では、Pod 全体としてはまだ準備ができておらず、他の readiness gate ステータスの確認を待ちます。 -
CCM によるバックエンドの登録:cloud-controller-manager (CCM) はコンテナの準備ができたことを検出し、Pod の IP アドレスを指定されたロードバランサーのバックエンドサーバーグループに追加します。登録が成功すると、CCM は対応する Service の条件 (例:
service.readiness.alibabacloud.com/my-svc) を Pod に追加し、そのステータスをTrueに設定します。 -
Pod の完全な準備完了:kubelet は、すべての readiness gate の条件が
Trueであることを確認し、Pod の最終的なReadyステータスをTrueに設定します。その後に初めて Pod は正式に準備完了と見なされ、ローリングアップデートプロセスは安全に古い Pod を終了させることができます。
-
-
注意事項
-
Service が存在している必要があります:
readinessGatesで参照される Service 名が正しく、その Service がクラスター内に存在することを確認してください。Service 名が間違っているか、Pod の起動中に Service が削除されると、CCM はバックエンドを登録できません。Pod はReadyステータスに到達できず、デプロイプロセスが停止してしまいます。 -
複数の Service のサポート:Pod には、複数の
LoadBalancerService のために、複数のreadinessGates.conditionTypeエントリを設定できます。この場合、Pod は指定されたすべての Service のバックエンドに正常に登録された後にのみ準備完了となります。
-
操作手順
自動
Pod ReadinessGate Webhook を有効にすると、namespace に label k8s.alibabacloud.com/pod-readiness-gate-inject: enabled を追加して、その namespace 内のすべての Pod に対して readiness gate の自動インジェクションを有効にできます。
以下の手順では、default namespace に対して自動インジェクションを有効にする方法を説明します。
ステップ 1:自動インジェクション label の追加
-
defaultnamespace にk8s.alibabacloud.com/pod-readiness-gate-inject: enabledlabel を追加して、自動インジェクションを有効にします。kubectl label namespace default k8s.alibabacloud.com/pod-readiness-gate-inject=enabled期待される出力:
namespace/default labeled -
namespace の label を確認します。
kubectl get namespace default -oyaml期待される出力:
apiVersion: v1 kind: Namespace metadata: creationTimestamp: "2025-11-13T07:18:37Z" labels: k8s.alibabacloud.com/pod-readiness-gate-inject: enabled kubernetes.io/metadata.name: default name: default resourceVersion: "6440182" uid: 73aff814-ae29-465a-98a4-6d37b9b8ee1a spec: finalizers: - kubernetes status: phase: Active出力から、label が namespace に追加されたことがわかります。
ステップ 2:ロードバランサー Service の作成
-
次の YAML テンプレートに基づいて
my-svc.yamlという名前のファイルを作成します。必要に応じて、Classic Load Balancer (CLB) または Network Load Balancer (NLB) インスタンスを作成できます。CLB
apiVersion: v1 kind: Service metadata: name: my-svc namespace: default # namespace は default spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancerNLB
apiVersion: v1 kind: Service metadata: name: my-svc annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-zone-maps: "${zone-A}:${vsw-A},${zone-B}:${vsw-B}" # 例:cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321 spec: loadBalancerClass: alibabacloud.com/nlb # ロードバランサーのタイプが NLB であることを指定します。 ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancer -
サンプルの Service を作成します。
kubectl apply -f my-svc.yaml -
Service のステータスを確認します。
kubectl get service my-svcEXTERNAL-IP列に IP アドレスまたはドメイン名が表示されるまで待ちます。これは、対応するロードバランサーインスタンスが作成されたことを示します。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-svc LoadBalancer 192.XX.XX.215 <IP address/domain name> 80:30493/TCP 8s
ステップ 3:サンプルの Deployment の作成
-
次の YAML テンプレートに基づいて
my-nginx.yamlという名前のファイルを作成します。apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx # サンプル名 namespace: default # namespace は default labels: app: nginx spec: replicas: 2 # レプリカの数を指定します。 selector: matchLabels: app: nginx # Service によって公開されるように、Service のセレクターと一致させる必要があります。 template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 # このポートは Service で公開される必要があります。 -
サンプルの Deployment をデプロイします。
kubectl apply -f my-nginx.yaml -
Pod とその readiness gate のステータスを確認します。
kubectl get pod -owide -l app=nginx期待される出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-d9f95dcf9-8dhwj 1/1 Running 0 14s 172.XX.XXX.188 cn-hangzhou.172.XX.XXX.174 <none> 0/1 my-nginx-d9f95dcf9-z9hjm 1/1 Running 0 14s 172.XX.XXX.182 cn-hangzhou.172.XX.XXX.174 <none> 0/1コマンドを複数回実行すると、READINESS GATES のステータスが 0/1 から 1/1 に変わります。この変更は、Pod がロードバランサーのバックエンドサーバーグループに正常に登録されたことを示しています。
ステップ 4:ローリングアップデートの実行
-
サンプルの Deployment を再起動します。
kubectl rollout restart deployment my-nginx期待される出力:
deployment.apps/my-nginx restarted -
Pod とその readiness gate のステータスを確認します。
kubectl get pod -owide -l app=nginx期待される出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-d9f95dcf9-8dhwj 1/1 Running 0 113s 172.XX.XXX.188 cn-hangzhou.172.XX.XXX.174 <none> 1/1 my-nginx-df5c9cf7d-6p5jc 1/1 Running 0 6s 172.XX.XXX.182 cn-hangzhou.172.XX.XXX.174 <none> 0/1 my-nginx-df5c9cf7d-7dh2v 1/1 Running 0 15s 172.XX.XXX.189 cn-hangzhou.172.XX.XXX.174 <none> 1/1ローリングアップデート中にこのコマンドを複数回実行すると、Pod が readiness gate の準備が整うのを待っていることがわかります。ローリングアップデートは、gate の準備が整った後にのみ続行され、新しい Pod がロードバランサーのバックエンドサーバーグループに登録されることを保証します。
手動
ステップ 1:ロードバランサー Service の作成
-
次の YAML テンプレートに基づいて
my-svc.yamlという名前のファイルを作成します。必要に応じて、Classic Load Balancer (CLB) または Network Load Balancer (NLB) インスタンスを作成できます。CLB
apiVersion: v1 kind: Service metadata: name: my-svc namespace: default # namespace は default spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancerNLB
apiVersion: v1 kind: Service metadata: name: my-svc annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-zone-maps: "${zone-A}:${vsw-A},${zone-B}:${vsw-B}" # 例:cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321 spec: loadBalancerClass: alibabacloud.com/nlb # ロードバランサーのタイプが NLB であることを指定します。 ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancer -
サンプルの Service を作成します。
kubectl apply -f my-svc.yaml -
Service のステータスを確認します。
kubectl get service my-svcEXTERNAL-IP列に IP アドレスまたはドメイン名が表示されるまで待ちます。これは、対応するロードバランサーインスタンスが作成されたことを示します。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-svc LoadBalancer 192.XX.XX.215 <IP address/domain name> 80:30493/TCP 8s
ステップ 2:サンプルの Deployment の作成
-
my-nginx.yamlという名前のファイルを作成します。Pod テンプレートで、readiness gate のconditionTypeをservice.readiness.alibabacloud.com/my-svcに設定します。apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx # サンプル名 namespace: default # namespace は default labels: app: nginx spec: replicas: 2 # レプリカの数を指定します。 selector: matchLabels: app: nginx # Service によって公開されるように、Service のセレクターと一致させる必要があります。 template: metadata: labels: app: nginx spec: readinessGates: - conditionType: service.readiness.alibabacloud.com/my-svc # my-svc Service の readiness gate を設定します。 containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 # このポートは Service で公開される必要があります。 -
サンプルの Deployment をデプロイします。
kubectl apply -f my-nginx.yaml -
Pod とその readiness gate のステータスを確認します。
kubectl get pod -owide -l app=nginx期待される出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-d9f95dcf9-8dhwj 1/1 Running 0 14s 172.XX.XXX.188 cn-hangzhou.172.XX.XXX.174 <none> 0/1 my-nginx-d9f95dcf9-z9hjm 1/1 Running 0 14s 172.XX.XXX.182 cn-hangzhou.172.XX.XXX.174 <none> 0/1コマンドを複数回実行すると、READINESS GATES のステータスが 0/1 から 1/1 に変わります。この変更は、Pod がロードバランサーのバックエンドサーバーグループに正常に登録されたことを示します。
ステップ 3:ローリングアップデートの実行
-
サンプルの Deployment を再起動します。
kubectl rollout restart deployment my-nginx期待される出力:
deployment.apps/my-nginx restarted -
Pod とその readiness gate のステータスを確認します。
kubectl get pod -owide -l app=nginx期待される出力:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-d9f95dcf9-8dhwj 1/1 Running 0 113s 172.XX.XXX.188 cn-hangzhou.172.XX.XXX.174 <none> 1/1 my-nginx-df5c9cf7d-6p5jc 1/1 Running 0 6s 172.XX.XXX.182 cn-hangzhou.172.XX.XXX.174 <none> 0/1 my-nginx-df5c9cf7d-7dh2v 1/1 Running 0 15s 172.XX.XXX.189 cn-hangzhou.172.XX.XXX.174 <none> 1/1ローリングアップデート中にこのコマンドを複数回実行すると、Pod が readiness gate の準備が整うのを待っていることがわかります。ローリングアップデートは、gate の準備が整った後にのみ続行され、新しい Pod がロードバランサーのバックエンドサーバーグループに登録されることを保証します。