在Pod上线阶段,需要确保Pod在接收流量之前真正达到可服务状态,您可以通过配置readiness gate来保证Pod上线阶段的可用性。ALB Ingress Controller支持启用readiness gate功能,持续监控ACS集群Pod的状态,等待Pod状态变为可用状态后再将完全启动的Pod挂载到后端服务器组,并向该Pod转发流量。本文通过是否配置readiness gate的对照实验,介绍如何实现ALB Ingress后端Pod滚动升级时平滑上线。
背景信息
存活、就绪和启动探针
Kubernetes可以通过存活(Liveness)、就绪(Readiness)、启动(Startup)这三类可用性探针来检查Pod的健康状态、服务可用性和启用条件,提高应用的可用性。您可以通过HTTP请求、TCP Socket连接或命令行方式配置这三类探针,设置执行探测的频率、超时时间、健康阈值和不健康阈值等参数。更多信息,请参见配置存活、就绪和启动探针。
Readiness Gate机制
在可用性探针模式下,Pod的Ready状态仅由kubelet根据容器状态判断。然而,对于复杂应用程序来说,往往需要更精细地控制容器内服务的可用性,并且需要具备控制Pod的Ready状态的能力。
通过readiness gate机制,您可以设置一个或多个自定义的Pod可用性探测来判断Pod是否可用。新增的自定义条件(condition)状态将由外部Controller控制器设置,Kubernetes将在判断全部readinessGates
条件都为true时,才将Pod设置为服务可用状态。更多信息,请参见Pod Readiness Gate。
ALB Ingress Controller支持启用readiness gate功能,在Deployment中配置readinessGates
自定义条件为target-health.alb.k8s.alibabacloud
后,ACS集群持续监控Pod状态。当ALB Ingress Controller将Pod成功添加到ALB后端服务器组后,ACS集群才标记Pod状态可用并向Pod转发流量,从而实现ALB Ingress后端Pod滚动升级时平滑上线。
前提条件
已为ACS集群安装ALB Ingress Controller组件。具体操作,请参见管理ALB Ingress Controller组件。
已创建AlbConfig和IngressClass。具体操作,请参见创建AlbConfig和创建IngressClass。
连接集群。具体操作,请参见获取集群kubeconfig并通过kubectl工具连接集群或在CloudShell上通过kubectl管理Kubernetes集群。
操作步骤
步骤一:部署示例应用tea
创建tea-service.yaml文件并拷贝以下示例内容到文件中。示例部署了一个名称为
tea
的Deployment以及名称为tea-svc
的Service。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/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: ClusterIP
执行以下命令,部署Deployment和Service。
kubectl apply -f tea-service.yaml
执行以下命令,检查应用状态。
kubectl get pods -o wide
预期输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tea-5cb56xxxxx-xxxxx 1/1 Running 0 1m4s 192.168.xxx.xxx xxx <none> <none>
其中Pod的
READINESS GATES
显示为<none>
,表示未配置readinessGates
。创建以下内容到tea-ingress.yaml文件中。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - host: www.example.com http: paths: - path: /tea pathType: Prefix backend: service: name: tea-svc port: number: 80
执行以下命令,部署Ingress。
kubectl apply -f tea-ingress.yaml
执行以下命令,获取ALB Ingress的信息。
kubectl get ingress
预期输出:
NAME CLASS HOSTS ADDRESS PORTS AGE tea-ingress alb www.example.com alb-qu066wzmi5fbixxxxx.cn-xxxxxxx.alb.aliyuncs.com 80 6m47s
本文中配置的www.example.com
域名仅作为示例,正式域名的配置请参见配置域名解析。
步骤二:验证示例应用tea滚动升级时有中断
启动测试脚本。
使用以下内容,创建
test.sh
测试脚本文件。此脚本用于测试示例应用的可用性,不断发送请求并查看HTTP返回状态码。#!/bin/bash HOST="www.example.com" DNS="alb-qu066wzmi5fbixxxxx.cn-xxxxxxx.alb.aliyuncs.com" # 填写ALB Ingress的ADDRESS值。 while true; do RESPONSE=$(curl -H Host:$HOST -s -o /dev/null -w "%{http_code}" -m 1 http://$DNS/tea) TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S) echo "$TIMESTAMP - $RESPONSE" done
执行以下命令运行测试脚本
test.sh
。bash test.sh
打开一个新的终端窗口执行以下命令,重新部署应用,触发Pod滚动升级。
kubectl rollout restart deploy tea
验证Pod滚动升级。
可以看到脚本执行的结果中出现了少量状态码
502
(Bad Gateway),意味着示例应用tea提供服务的网关(即ALB Ingress)出现了短暂的中断。
步骤三:部署示例应用tea-readiness并配置readinessGates
创建tea-readiness-service.yaml文件并拷贝以下示例内容到文件中。示例部署了一个名称为
tea-readiness
的Deployment以及名称为tea-readiness-svc
的Service,并配置Pod的.spec.readinessGates.conditionType
为target-health.alb.k8s.alibabacloud
,来启用ALB Ingress Controller的readiness gate功能。apiVersion: apps/v1 kind: Deployment metadata: name: tea-readiness spec: replicas: 1 selector: matchLabels: app: tea-readiness template: metadata: labels: app: tea-readiness spec: containers: - name: tea-readiness image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest ports: - containerPort: 80 # 配置readinessGates readinessGates: - conditionType: target-health.alb.k8s.alibabacloud --- apiVersion: v1 kind: Service metadata: name: tea-readiness-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: tea-readiness type: ClusterIP
执行以下命令,部署Deployment和Service。
kubectl apply -f tea-readiness-service.yaml
执行以下命令,检查应用状态。
kubectl get pods -o wide
预期输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tea-5cb56xxxxx-xxxxx 1/1 Running 0 11m 192.168.xxx.xxx xxx <none> <none> tea-readiness-5cb56xxxxx-xxxxx 1/1 Running 0 4m7s 192.168.xxx.xxx xxx <none> 0/1
由于此时还未配置Ingress,因此tea-readiness的
READINESS GATES
显示为0/1
,表示readinessGates
配置未生效。创建以下内容到tea-readiness-ingress.yaml文件中。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-readiness-ingress spec: ingressClassName: alb rules: - host: www.example.com http: paths: - path: /tea-readiness pathType: Prefix backend: service: name: tea-readiness-svc port: number: 80
执行以下命令,部署Ingress。
kubectl apply -f tea-readiness-ingress.yaml
执行以下命令,获取ALB Ingress的信息。
kubectl get ingress
预期输出:
NAME CLASS HOSTS ADDRESS PORTS AGE tea-ingress alb www.example.com alb-qu066wzmi5fbi5lg85.cn-beijing.alb.aliyuncs.com 80 12m tea-readiness-ingress alb www.example.com alb-qu066wzmi5fbi5lg85.cn-beijing.alb.aliyuncs.com 80 65s
步骤四:验证示例应用tea-readiness滚动升级时平滑上线
执行以下命令,检查应用状态。此时tea-readiness的
READINESS GATES
显示为1/1
,表示readinessGates
配置已生效。kubectl get pods -o wide
预期输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES tea-5cb56xxxxx-xxxxx 1/1 Running 0 13m 192.168.xxx.xxx xxx <none> <none> tea-readiness-5cb56xxxxx-xxxxx 1/1 Running 0 6m2s 192.168.xxx.xxx xxx <none> 1/1
启动测试脚本。
使用以下内容,创建
test-readiness.sh
测试脚本文件。此脚本用于测试示例应用的可用性,不断发送请求并查看HTTP返回状态码。#!/bin/bash HOST="www.example.com" DNS="alb-qu066wzmi5fbixxxxx.cn-xxxxxxx.alb.aliyuncs.com" # 填写ALB Ingress的ADDRESS值。 while true; do RESPONSE=$(curl -H Host:$HOST -s -o /dev/null -w "%{http_code}" -m 1 http://$DNS/tea-readiness) TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S) echo "$TIMESTAMP - $RESPONSE" done
执行以下命令运行测试脚本
test-readiness.sh
。bash test-readiness.sh
打开一个新的终端窗口执行以下命令,重新部署应用,触发Pod滚动升级。
kubectl rollout restart deploy tea-readiness
验证Pod滚动升级。
可以看到脚本执行的结果状态码全部为200,验证滚动升级过程没有异常或中断。