使用Readiness Gate实现ALB Ingress后端Pod滚动升级时平滑上线

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机制

在可用性探针模式下,PodReady状态仅由kubelet根据容器状态判断。然而,对于复杂应用程序来说,往往需要更精细地控制容器内服务的可用性,并且需要具备控制PodReady状态的能力。

通过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 ControllerPod成功添加到ALB后端服务器组后,ACS集群才标记Pod状态可用并向Pod转发流量,从而实现ALB Ingress后端Pod滚动升级时平滑上线。

前提条件

操作步骤

步骤一:部署示例应用tea

  1. 创建tea-service.yaml文件并拷贝以下示例内容到文件中。示例部署了一个名称为teaDeployment以及名称为tea-svcService。

    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
  2. 执行以下命令,部署DeploymentService。

    kubectl apply -f tea-service.yaml
  3. 执行以下命令,检查应用状态。

    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>

    其中PodREADINESS GATES显示为<none>,表示未配置readinessGates

  4. 创建以下内容到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
  5. 执行以下命令,部署Ingress。

    kubectl apply -f tea-ingress.yaml
  6. 执行以下命令,获取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滚动升级时有中断

  1. 启动测试脚本。

    1. 使用以下内容,创建test.sh测试脚本文件。此脚本用于测试示例应用的可用性,不断发送请求并查看HTTP返回状态码。

      #!/bin/bash
      HOST="www.example.com"
      DNS="alb-qu066wzmi5fbixxxxx.cn-xxxxxxx.alb.aliyuncs.com"   # 填写ALB IngressADDRESS值。
      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
    2. 执行以下命令运行测试脚本test.sh

      bash test.sh
  2. 打开一个新的终端窗口执行以下命令,重新部署应用,触发Pod滚动升级。

    kubectl rollout restart deploy tea 
  3. 验证Pod滚动升级。

    image

    可以看到脚本执行的结果中出现了少量状态码502(Bad Gateway),意味着示例应用tea提供服务的网关(即ALB Ingress)出现了短暂的中断。

步骤三:部署示例应用tea-readiness配置readinessGates

  1. 创建tea-readiness-service.yaml文件并拷贝以下示例内容到文件中。示例部署了一个名称为tea-readinessDeployment以及名称为tea-readiness-svcService,并配置Pod.spec.readinessGates.conditionTypetarget-health.alb.k8s.alibabacloud,来启用ALB Ingress Controllerreadiness 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
  2. 执行以下命令,部署DeploymentService。

    kubectl apply -f tea-readiness-service.yaml
  3. 执行以下命令,检查应用状态。

    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-readinessREADINESS GATES显示为0/1,表示readinessGates配置未生效。

  4. 创建以下内容到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
  5. 执行以下命令,部署Ingress。

    kubectl apply -f tea-readiness-ingress.yaml
  6. 执行以下命令,获取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滚动升级时平滑上线

  1. 执行以下命令,检查应用状态。此时tea-readinessREADINESS 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
  2. 启动测试脚本。

    1. 使用以下内容,创建test-readiness.sh测试脚本文件。此脚本用于测试示例应用的可用性,不断发送请求并查看HTTP返回状态码。

      #!/bin/bash
      HOST="www.example.com"
      DNS="alb-qu066wzmi5fbixxxxx.cn-xxxxxxx.alb.aliyuncs.com"   # 填写ALB IngressADDRESS值。
      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
    2. 执行以下命令运行测试脚本test-readiness.sh

      bash test-readiness.sh
  3. 打开一个新的终端窗口执行以下命令,重新部署应用,触发Pod滚动升级。

    kubectl rollout restart deploy tea-readiness
  4. 验证Pod滚动升级。

    image

    可以看到脚本执行的结果状态码全部为200,验证滚动升级过程没有异常或中断。