如何解決 Amazon EKS 中負載平衡器運作狀態檢查失敗的問題?
我的負載平衡器在 Amazon Elastic Kubernetes Service (Amazon EKS) 中的運作狀態檢查一直失敗。
簡短描述
若要解決 Amazon EKS 中負載平衡器的運作狀態檢查問題,請完成以下部分所述的步驟:
- 檢查 Pod 的狀態
- 檢查 Pod 和服務標籤選取器
- 檢查是否缺少端點
- 檢查 Application Load Balancer 的服務流量政策和叢集安全群組
- 確認 targetPort 是否設為 EKS
- 確認 AWS 負載平衡器控制器是否有正確的許可
- 檢查 Application Load Balancer 是否有傳入註解的問題
- 檢查 Network Load Balancer 是否有 Kubernetes Service 註解的問題
- 手動測試運作狀態檢查
- 檢查聯網
- 重新啟動 kube-proxy
解決方案
檢查 Pod 的狀態
檢查 Pod 是否處於執行中狀態,且 Pod 中的容器已準備就緒:
$ kubectl get pod -n YOUR_NAMESPACE
**注意:**請以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
範例輸出:
NAME READY STATUS RESTARTS AGE podname 1/1 Running 0 16s
**注意:**如果 Pod 中的應用程式容器未執行,則負載平衡器的運作狀態檢查將無回應,且檢查會失敗。
檢查 Pod 和服務標籤選取器
請對 Pod 標籤執行以下命令:
$ kubectl get pod -n YOUR_NAMESPACE --show-labels
範例輸出:
NAME READY STATUS RESTARTS AGE LABELS alb-instance-6cc5cd9b9-prnxw 1/1 Running 0 2d19h app=alb-instance,pod-template-hash=6cc5cd9b9
若要確認 Kubernetes Service 是否使用 Pod 標籤,請執行以下命令檢查其輸出是否與 Pod 標籤相符:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.selector}{"\n"}'
注意:請以您的 Kubernetes Service 取代 SERVICE_NAME,並以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
範例輸出:
{"app":"alb-instance"}
檢查是否缺少端點
服務選取器的 Kubernetes 控制器會持續掃描,找出與其選取器相符的 Pod,然後將更新內容發布到端點物件上。如果選取了不正確的標籤,則不會顯示任何端點。
執行以下命令:
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
範例輸出:
Name: alb-instance Namespace: default Labels: <none> Annotations: <none> Selector: app=alb-instance-1 Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.44.151 IPs: 10.100.44.151 Port: http 80/TCP TargetPort: 80/TCP NodePort: http 32663/TCP Endpoints: <none> Session Affinity: None External Traffic Policy: Cluster Events: <none>
檢查是否缺少端點:
$ kubectl get endpoints SERVICE_NAME -n YOUR_NAMESPACE
範例輸出:
NAME ENDPOINTS AGE alb-instance <none> 2d20h
檢查 Application Load Balancer 的服務流量政策和叢集安全群組是否有問題
Application Load Balancer 目標群組的目標運作狀態不佳有兩個原因。服務流量政策 spec.externalTrafficPolicy 設為 Local (而非 Cluster)。或是叢集中的節點群組與不同的叢集安全群組聯結,且流量無法在節點群組之間自由流動。
確認流量政策的設定正確:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.externalTrafficPolicy}{"\n"}'
範例輸出:
Local
將設定更改為 Cluster:
$ kubectl edit svc SERVICE_NAME -n YOUR_NAMESPACE
檢查叢集安全群組
1. 開啟 Amazon EC2 主控台。
2. 選取運作狀態良好的執行個體。
3. 選擇安全性索引標籤並檢查安全群組傳入規則。
4. 選取運作狀態不佳的執行個體。
5. 選擇安全性索引標籤並檢查安全群組傳入規則。
如果每個執行個體的安全群組不同,則必須使用安全群組主控台來修改安全傳入規則:
1. 在安全性索引標籤中,選取安全群組 ID。
2. 選擇編輯連入規則按鈕以修改傳入規則。
3. 新增連入規則以允許叢集中其他節點群組傳入的流量。
確認 targetPort 是否設為您的服務
您的 targetPort 需為服務傳送流量目的地 Pod 中的 containerPort。
若要確認您的 targetPort 設定值為何,請執行以下命令:
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath="{.items[*]}{.metadata.name}{'\t'}{.spec.ports[].targetPort}{'\t'}{.spec.ports[].protocol}{'\n'}"
範例輸出:
alb-instance 8080 TCP
在上面的範例輸出中,targetPort 設為 8080。但是,由於 containerPort 設為 80,因此您也必須將 targetPort 設為 80。
確認 AWS 負載平衡器控制器是否有正確的許可
AWS 負載平衡器控制器必須具有更新安全群組的正確許可,才能讓負載平衡器的流量傳送到執行個體或 Pod。如果控制器沒有正確的許可,則您會收到錯誤訊息。
檢查 AWS 負載平衡器控制器部署記錄中是否有錯誤:
$ kubectl logs deploy/aws-load-balancer-controller -n kube-system
檢查個別控制器 Pod 記錄中是否有錯誤:
$ kubectl logs CONTROLLER_POD_NAME -n YOUR_NAMESPACE
注意:請以您的控制器 Pod 名稱取代 CONTROLLER_POD_NAME,並以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
檢查 Application Load Balancer 是否有傳入註解的問題
有關 Application Load Balancer 的問題,請查看 Kubernetes 傳入註解:
$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE
注意:請以您的 Kubernetes 傳入名稱取代 INGRESS_NAME,並以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
範例輸出:
Name: alb-instance-ingress Namespace: default Address: k8s-default-albinsta-fcb010af73-2014729787.ap-southeast-2.elb.amazonaws.com Default backend: alb-instance:80 (192.168.81.137:8080) Rules: Host Path Backends ---- ---- -------- awssite.cyou / alb-instance:80 (192.168.81.137:8080) Annotations: alb.ingress.kubernetes.io/scheme: internet-facing kubernetes.io/ingress.class: alb Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfullyReconciled 25m (x7 over 2d21h) ingress Successfully reconciled
若要尋找您的使用案例專用的傳入註解,請參閲 Kubernetes 網站中的傳入註解。
檢查 Network Load Balancer 是否有 Kubernetes Service 註解的問題
有關 Network Load Balancer 的問題,請查看 Kubernetes Service 註解:
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
範例輸出:
Name: nlb-ip Namespace: default Labels: <none> Annotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external Selector: app=nlb-ip Type: LoadBalancer IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.161.91 IPs: 10.100.161.91 LoadBalancer Ingress: k8s-default-nlbip-fff2442e46-ae4f8cf4a182dc4d.elb.ap-southeast-2.amazonaws.com Port: http 80/TCP TargetPort: 80/TCP NodePort: http 31806/TCP Endpoints: 192.168.93.144:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
**注意:**請記下 APPLICATION_POD_IP。您將需要它來執行運作狀態檢查命令。
若要尋找您的使用案例專用的 Kubernetes Service 註解,請參閲 Kubernetes 網站中的服務註解。
手動測試運作狀態檢查
查看您的應用程式 Pod IP 地址:
$ kubectl get pod -n YOUR_NAMESPACE -o wide
執行測試 Pod 以手動測試叢集內的運作狀態檢查,藉此確定 HTTP 的運作狀態:
$ kubectl run -n YOUR_NAMESPACE troubleshoot -it --rm --image=amazonlinux -- /bin/bash
若要進行 HTTP 運作狀態檢查:
# curl -Iv APPLICATION_POD_IP/HEALTH_CHECK_PATH
注意:請以您的應用程式 Pod IP 取代APPLICATION_POD_IP,並以 ALB 目標群組運作狀態檢查路徑取代 HEALTH_CHECK_PATH。
命令範例:
# curl -Iv 192.168.81.137
範例輸出:
* Trying 192.168.81.137:80... * Connected to 192.168.81.137 (192.168.81.137) port 80 (#0) > HEAD / HTTP/1.1 > Host: 192.168.81.137 > User-Agent: curl/7.78.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < Server: nginx/1.21.3 Server: nginx/1.21.3 < Date: Tue, 26 Oct 2021 05:10:17 GMT Date: Tue, 26 Oct 2021 05:10:17 GMT < Content-Type: text/html Content-Type: text/html < Content-Length: 615 Content-Length: 615 < Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT < Connection: keep-alive Connection: keep-alive < ETag: "6137835f-267" ETag: "6137835f-267" < Accept-Ranges: bytes Accept-Ranges: bytes < * Connection #0 to host 192.168.81.137 left intact
查看 HTTP 回應狀態代碼。如果回應狀態代碼為 200 OK,表示您的應用程式對運作狀態檢查路徑發出正確回應。
如果 HTTP 回應狀態代碼為 3xx 或 4xx,則可更改運作狀態檢查路徑。可使用 200 OK 來回應以下註解:
alb.ingress.kubernetes.io/healthcheck-path: /ping
或
您可對傳入資源使用以下註解,藉此新增成功的運作狀態檢查回應狀態代碼範圍:
alb.ingress.kubernetes.io/success-codes: 200-399
若要進行 TCP 運作狀態檢查,請使用以下命令來安裝 netcat 命令:
# yum update -y && yum install -y nc
測試 TCP 運作狀態檢查:
# nc -z -v APPLICATION_POD_IP CONTAINER_PORT_NUMBER
**注意:**請以您的應用程式 Pod IP 取代 APPLICATION_POD_IP,並以您的容器連接埠取代 CONTAINER_PORT_NUMBER。
命令範例:
# nc -z -v 192.168.81.137 80
範例輸出:
Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 192.168.81.137:80. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.
檢查聯網
若有聯網問題,請確認以下問題是否獲得解決:
- EKS 叢集中的多個節點群組可以自由地彼此通訊往來
- 與子網路 (您的 Pod 在此執行) 關聯的網路存取控制清單 (網路 ACL) 可讓來自負載平衡器子網路 CIDR 範圍的流量傳入
- 與您的負載平衡器子網路關聯的網路 ACL 需讓 Pod 所在位置的子網路流量可返回至暫時連接埠範圍
- 路由表可讓來自 VPC CIDR 範圍的本機流量傳入
重新啟動 kube-proxy
如果執行於每個節點上的 kube-proxy 運作不正常,則可能無法更新服務和端點的 iptables 規則。重新啟動 kube-proxy 以強制執行它,藉此重新檢查並更新 iptables 規則:
kubectl rollout restart daemonset.apps/kube-proxy -n kube-system
範例輸出:
daemonset.apps/kube-proxy restarted
相關資訊
如何在 Amazon EKS 的 Amazon EC2 節點群組上使用 AWS Load Balancer 控制器設定 Application Load Balancer?
如何對 Amazon EKS 的服務負載平衡器進行疑難排解?
如何標記 Amazon EKS 叢集中的 Amazon VPC 子網路,以便負載平衡器或輸入控制器自動探索子網路?
相關內容
- 已提問 9 個月前lg...
- 已提問 9 個月前lg...
- 已提問 9 個月前lg...
- 已提問 1 年前lg...
- AWS 官方已更新 9 個月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前