您可以配置preStop Hook,實現ALB Ingress後端Pod的平滑下線,確保Pod在被完全移除後才下線。配置後,容器在變換期間能夠保障服務的流量無縫切換,避免出現中斷。
前提條件
已建立ACK託管叢集或ACK專有叢集,且叢集為1.18及以上版本。具體操作,請參見建立ACK託管叢集、建立ACK專有叢集;如需升級叢集,請參見手動升級叢集。
已為叢集安裝ALB Ingress Controller組件。具體操作,請參見管理ALB Ingress Controller組件。
說明若需要在ACK專有叢集中通過ALB Ingress訪問服務,在部署服務前需要為ALB Ingress Controller授權。具體操作,請參見為ACK專有叢集授予ALB Ingress Controller存取權限。
原理介紹
Pod生命週期
Pod中的容器包括兩種類型:
初始化容器(Init容器):運行服務的主容器前置依賴的容器,完成一些初始化操作。
主容器(工作容器):運行服務進程的容器。
Pod啟動過程如下:
運行初始化容器:在主容器啟動之前,要啟動並執行容器,為主容器執行預置操作。
運行主容器:
容器啟動後執行postStart Hook函數。
容器執行存活性探測(Liveness Probe)、就緒性檢測(Readiness Probe)。
在容器退出前執行preStop Hook函數。
Pod終止流程和網路規則更新流程
在刪除Pod時K8s會同時進行Pod終止和網路規則更新兩個主要的流程。Pod終止流程和網路更新流程如下。
Pod終止流程
kube-apiserver收到Pod刪除請求,將Pod標記為
Terminating狀態。如果Pod定義了preStop Hook,將執行preStop Hook。
K8s叢集向容器發送SIGTERM訊號。
等待容器停止,或等待Pod刪除寬限期逾時。
說明Pod中容器刪除寬限期
terminationGracePeriodSeconds預設為30秒。逾時Pod刪除寬限期後容器仍未終止,K8s發送SIGKILL訊號給容器。
Pod被完全刪除。
網路規則更新流程
kube-apiserver收到Pod刪除請求,將Pod標記為
Terminating狀態。Endpoint Controller從Endpoint對象中刪除Pod的IP。
ALB Ingress Controller進行Server節點調諧,將Service Endpoints從後端伺服器組中移除,不再將流量路由到被刪除的Pod。
使用preStop Hook來實現Pod平滑下線
當Pod滾動升級過程中,如果舊的Pod沒有平滑退出,將導致應用無法正常處理業務請求,出現如下錯誤狀態代碼,影響應用的可用性。
狀態代碼 | 問題原因 |
504 | 當舊Pod在未處理完正常請求情況下被刪除,並且該請求為非等冪。 |
502 | 當ACK叢集已經刪除舊Pod,容器收到終止訊號(SIGTERM)並迅速終止,但ALB Ingress Controller仍在調諧流程中,導致Pod未及時從後端伺服器組中移除,流量依然被錯誤地路由到已終止的舊Pod上。 |
為了避免以上的情況發生,您可以採取如下方案。
在kube-apiserver接收到Pod刪除請求時,通過在Deployment配置內添加preStop Hook,可以為容器設定一個"Sleep"暫停期。這個暫停期是讓容器有時間在收到SIGTERM之前完成網路規則的更新,並等待ALB Ingress Controller完成Server調諧事件並確保Pod已從後端伺服器組中移除。這一步驟對於保障Pod的平穩下線至關重要,避免在變換或服務重啟期間造成流量中斷。
同時,Kubernetes為容器設定了在接收到SIGTERM後能持續啟動並執行最大寬限期(terminationGracePeriodSeconds)為30秒。當程式關閉時間與preStop Hook指定的操作時間之和超過了30秒時,預設寬限期將不足以讓容器完成所有的關閉步驟。kubelet會在等待2秒後直接給容器發送立即終止(SIGKILL)訊號,導致容器強制退出。
如果程式的關閉時間和在Deployment配置的preStop Hook之和超過30秒,應將terminationGracePeriodSeconds重新設定,調整為大於30秒,確保容器優雅退出。
步驟一:並配置Pod平滑退出preStop Hook
建立並儲存tea-service.yaml,配置確保Pod平滑退出的preStop Hook。
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函數,使kube-apiserver等待10秒後再向Pod發送SIGTERM訊號。 preStop: # preStop鉤子設定。 exec: # 通過執行命令的方式來實現preStop操作。 command: # 定義要執行的命令。 - /bin/sh - -c - "sleep 10" # 執行sleep操作,暫停10秒。 terminationGracePeriodSeconds: 45 # 設定Pod刪除寬限期。 --- apiVersion: v1 kind: Service metadata: name: tea-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: tea type: NodePort執行以下命令,部署樣本Deployment和Service。
kubectl apply -f tea-service.yaml建立並儲存tea-ingress.yaml檔案,用於配置Ingress。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tea-ingress spec: ingressClassName: alb rules: - host: demo.ingress.top http: paths: - path: / pathType: Prefix backend: service: name: tea-svc port: number: 80執行以下命令,部署Ingress。
kubectl apply -f tea-ingress.yaml執行以下命令,擷取ALB Ingress的
ADDRESS。kubectl get ingress預期輸出:
NAME CLASS HOSTS ADDRESS PORTS AGE tea-ingress alb demo.ingress.top alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com 80 7m5s
步驟二:結果驗證
啟動測試指令碼。
使用以下內容,建立
test.sh測試指令碼檔案。此指令碼用於測試應用的可用性,按每秒一次的頻率請求Nginx服務並查看狀態代碼。#!/bin/bash HOST="demo.ingress.top" DNS="alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com" # 填寫ALB Ingress的ADDRESS值。 printf "Response Code|| TIME \n" >> log.txt while true; do RESPONSE=$(curl -H Host:$HOST -s -o /dev/null -w "%{http_code}" -m 1 http://$DNS/) TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S) echo "$TIMESTAMP - $RESPONSE" >> log.txt sleep 1 done執行以下命令運行測試指令碼
test.sh。bash test.sh
執行以下命令,重新部署應用,觸發Pod滾動升級。
kubectl rollout restart deploy tea驗證Pod滾動升級。
初始階段應用副本數為3。

在重新部署應用時,新Pod建立階段由於新Pod沒有就緒,舊Pod仍在提供服務,會同時運行新舊兩個Pod。

新Pod就緒且成功掛載至ALB後端伺服器組後,會終止舊Pod。

所有舊Pod完成preStop Hook函數或超出
terminationGracePeriodSeconds逾時時間後,kubectl會向Container發送訊號終止舊的Pod,此時變換完成。
查看測試指令碼執行結果。檢查變換過程中請求的狀態代碼,可以看到狀態代碼全部為200,更新過程沒有中斷。
執行如下命令,查看測試指令碼執行結果。
cat log.txt預期輸出:

相關文檔
您可以使用ALB Ingress實現請求轉寄、HTTP重新導向至HTTPS、灰階發布等功能,詳細資料請參見ALB Ingress服務進階用法
您可以通過配置ReadinessGate來保證Pod上線階段的可用性,請參見使用ReadinessGate實現ALB Ingress後端Pod滾動升級時平滑上線。
如在使用ALB Ingress過程中遇到問題,您可以參見ALB Ingress FAQ、ALB Ingress異常問題排查進行自排查。