在生产环境中,Pod发生滚动更新、弹性伸缩、故障迁移非常常见,如果在Pod创建、终止过程中缺乏完善的高可用机制,可能导致请求被转发到尚未就绪或已经终止的Pod,引发请求失败或响应延迟,影响用户体验。通过配置ALB健康检查、ReadinessGate、preStop Hook,可以实现流量的平滑迁移,保障业务持续高可用。
核心配置示例
在工作负载中配置就绪门控
readinessGate和停止前回调preStop:apiVersion: apps/v1 kind: Deployment metadata: name: tea spec: ... template: ... spec: containers: - ... lifecycle: # 设置preStop Hook函数,使Pod在收到SIGTERM前等待10秒。 preStop: exec: # 通过执行命令的方式实现preStop操作。 command: - /bin/sh - -c - "sleep 10" # 暂停10秒,为ALB Ingress留出时间。 terminationGracePeriodSeconds: 45 # 设置Pod删除宽限期,需大于preStop等待时间。 readinessGates: # 配置ReadinessGate。 - conditionType: target-health.alb.k8s.alibabacloud # ALB Ingress自定义Condition。在Ingress中通过Annotations配置健康检查:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress annotations: alb.ingress.kubernetes.io/healthcheck-enabled: "true" # 启用健康检查。 alb.ingress.kubernetes.io/healthcheck-protocol: "TCP" # 健康检查协议。 alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5" # 健康检查超时时间。 alb.ingress.kubernetes.io/healthcheck-interval-seconds: "2" # 健康检查间隔。 alb.ingress.kubernetes.io/healthy-threshold-count: "3" # 健康阈值。 alb.ingress.kubernetes.io/unhealthy-threshold-count: "3" # 不健康阈值。 spec: ingressClassName: alb rules: - ...
工作原理
就绪门控(ReadinessGate)
未配置时:新Pod启动后会被自动标记为Ready并接受流量。但是,如果新Pod未能成功添加到ALB后端服务器组(例如超出ALB后端限额等原因),集群对该状况无法感知,Pod虽处于Ready状态但实际无法接收请求,造成客户端请求失败。
配置后:确保只有当ALB Ingress Controller将Pod成功添加到ALB后端服务器组后,才标记Pod为Ready状态,避免出现ALB后端服务器组和集群Pod状态不同步的问题。
停止前回调(preStop Hook)
未配置时:kubelet在Pod被标记为
Terminating时,将立即向容器发送SIGTERM信号,容器将停止接收新连接。同时,ALB实例将Pod从后端服务器组中移除。在移除操作尚未完成时,可能还会有请求被转发到终止的Pod,导致502错误。配置后:
SIGTERM信号将会在preStop Hook执行完成后再发送。使用preStop Hook,可以在容器收到SIGTERM信号前插入一段等待时间(例如10秒),使ALB实例有足够时间将Pod从后端服务器组中移除后再终止容器。
删除宽限期(terminationGracePeriodSeconds)在Pod进入Terminating状态后就会开始计算,不论是否配置了preStop Hook。到达宽限期后,还未终止的容器将被发送SIGKILL信号强制终止。因此,使用preStop Hook时,请将terminationGracePeriodSeconds设置为大于preStop Hook花费时间的值,以确保preStop Hook执行完成后容器仍有足够时间处理剩余请求并优雅退出。
ALB健康检查
未配置时:在异常场景中,可能出现Pod不可用后,变更无法同步到ALB后端服务器组的情况,导致ALB实例继续向不可用的Pod转发流量,使客户端收到5xx状态码。
配置后:ALB实例进行主动探测,识别异常Pod并停止向其转发请求,降低请求失败风险。
验证ALB Ingress高可用配置
步骤一:准备工作
将集群版本升级到1.18或更高。
将下方示例保存到
tea-deploy-basic.yaml,然后执行kubectl apply -f tea-deploy-basic.yaml。示例中未包含preStop Hook、ReadinessGate和健康检查配置。
apiVersion: apps/v1 kind: Deployment metadata: name: tea spec: replicas: 3 selector: matchLabels: app: tea template: metadata: labels: app: tea spec: containers: - name: tea image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: tea-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: tea type: NodePort --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80获取ALB实例的DNS域名。
kubectl get ingress tea-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}{"\n"}'将下方示例保存到test.sh文件。
示例脚本按五秒一次的频率触发Pod滚动升级。
#!/bin/bash while true; do kubectl rollout restart deploy tea sleep 5 done执行
bash test.sh滚动更新Pod,同时在另一个终端中执行压测命令:hey -z 30s -c 100 http://ALB_URL/观察结果:出现部分
502、504状态码,说明未配置高可用机制时应用无法正常处理业务请求。
步骤二:在工作负载中配置preStop Hook和ReadinessGate
将下方示例保存到tea-deploy.yaml文件,然后执行
kubectl apply -f tea-deploy.yaml。apiVersion: apps/v1 kind: Deployment metadata: name: tea spec: replicas: 3 selector: matchLabels: app: tea template: metadata: labels: app: tea spec: containers: - name: tea image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest ports: - containerPort: 80 lifecycle: # 设置preStop Hook函数,使Pod在收到SIGTERM前等待10秒。 preStop: exec: # 通过执行命令的方式实现preStop操作。 command: - /bin/sh - -c - "sleep 10" # 暂停10秒,为ALB Ingress留出时间。 terminationGracePeriodSeconds: 45 # 设置Pod删除宽限期,需大于preStop等待时间。 readinessGates: # 配置ReadinessGate。 - conditionType: target-health.alb.k8s.alibabacloud # ALB Ingress自定义Condition。执行
bash test.sh滚动更新Pod,同时在另一个终端中执行压测命令:hey -z 30s -c 100 http://ALB_URL/观察结果:状态码全部为
200,502和504状态码消失,表明preStop Hook和ReadinessGate配置成功。执行
kubectl scale deployment tea --replicas=1对Deployment进行缩容,同时在另一个终端中执行压测命令:hey -z 30s -c 100 http://ALB_URL/观察结果:出现少量
502和504状态码,这是因为在未配置健康检查的情况下,ALB实例仍旧会向进入终止流程的不可用Pod转发流量,导致请求错误。
步骤三:在Ingress中配置健康检查
执行
kubectl scale deployment tea --replicas=3,恢复工作负载Pod数量。将下方示例保存到tea-ingress.yaml文件,然后执行
kubectl apply -f tea-ingress.yaml。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress annotations: alb.ingress.kubernetes.io/healthcheck-enabled: "true" # 启用健康检查。 alb.ingress.kubernetes.io/healthcheck-protocol: "TCP" # 健康检查协议。 alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5" # 健康检查超时时间。 alb.ingress.kubernetes.io/healthcheck-interval-seconds: "2" # 健康检查间隔。 alb.ingress.kubernetes.io/healthy-threshold-count: "3" # 健康阈值。 alb.ingress.kubernetes.io/unhealthy-threshold-count: "3" # 不健康阈值。 spec: ingressClassName: alb rules: - http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80执行
kubectl scale deployment tea --replicas=1,对Deployment进行缩容。同时在另一个终端中执行压测命令:hey -z 30s -c 100 http://ALB_URL/观察结果:状态码应全部为
200,无502、504等错误,表明ALB Ingress高可用配置成功。
相关文档
关于ALB Ingress健康检查的详细配置和其他高级配置,请参见ALB Ingress服务高级用法。
如在使用ALB Ingress过程中遇到问题,请参见ALB Ingress FAQ、ALB Ingress异常问题排查进行自助排查。