跳至內容

如何解決未通過 Amazon EKS 中的負載平衡器運作狀態檢查?

5 分的閱讀內容
0

我的負載平衡器未通過 Amazon Elastic Kubernetes Service (Amazon EKS) 的運作狀態檢查。

解決方法

若要疑難排解 Amazon EKS 中的負載平衡器運作狀態檢查問題,請完成下列各節的步驟。

檢查 Pod 的狀態

檢查 Pod 是否處於執行中狀態,且該 Pod 中的容器已準備就緒:

$ kubectl get pod -n YOUR_NAMESPACE

**注意:**將 YOUR_NAMESPACE 取代為您的 Kubernetes 命名空間。

範例輸出:

NAME                           READY   STATUS    RESTARTS   AGEpodname                        1/1     Running   0          16s

如果 Pod 中應用程式容器的狀態非執行中,則不會回應負載平衡器運作狀態檢查,且不會通過檢查。

檢查 Pod 和服務標籤選擇器

如果是 Pod 標籤,請執行下列命令:

$ kubectl get pod -n YOUR_NAMESPACE --show-labels

範例輸出:

NAME                           READY   STATUS    RESTARTS   AGE     LABELSalb-instance-6cc5cd9b9-prnxw   1/1     Running   0          2d19h   app=alb-instance,pod-template-hash=6cc5cd9b9

若要確認您的 Kubernetes 服務是否使用 Pod 標籤,請執行下列命令,檢查輸出是否與 Pod 標籤相符:

$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.selector}{"\n"}'

**注意:**將 SERVICE_NAME 取代為您的 Kubernetes 服務,並將 YOUR_NAMESPACE 取代為您的 Kubernetes 命名空間。

範例輸出:

{"app":"alb-instance"}

檢查缺少的端點

服務選擇器的 Kubernetes 控制器會持續掃描符合其選擇器的 Pod,然後將更新發佈至端點物件。如果您選取不正確的標籤,就不會顯示任何端點。

執行下列命令:

$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE

範例輸出:

Name:                     alb-instanceNamespace:                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                                AGEalb-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. 選擇安全性索引標籤,然後勾選安全群組輸入規則。
    如果每個執行個體的安全群組不同,必須在安全群組主控台中修改安全輸入規則:
    安全性索引標籤中,選取安全群組 ID。
    選擇編輯傳入規則以修改輸入規則。
    新增傳入規則,允許來自叢集中其他節點群組的流量。

確認 Target Port 是否設為您的服務

您的 **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

**注意:**將 CONTROLLER_POD_NAME 取代為您的控制器 Pod 名稱,並將 YOUR_NAMESPACE 取代為您的 Kubernetes 命名空間。

檢查 Application Load Balancer 是否有輸入註釋的問題

如果 Application Load Balancer 出現問題,請檢查 Kubernetes 輸入註釋:

$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE

**注意:**將 INGRESS_NAME 取代為您 Kubernetes Ingress 的名稱,並將 YOUR_NAMESPACE 取代為您的 Kubernetes 命名空間。

範例輸出:

Name:             alb-instance-ingressNamespace:        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 網站上的 Ingress annotations

檢查 Network Load Balancer 是否有 Kubernetes 服務註釋的問題

如果 Network Load Balancer 出現問題,請檢查 Kubernetes 服務註釋:

$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE

範例輸出:

Name:                     nlb-ipNamespace:                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 服務註釋,請參閱 Kubernetes 網站上的 Service annotations

手動測試運作狀態檢查

檢查您的應用程式 Pod IP 位址:

$ kubectl get pod -n YOUR_NAMESPACE -o wide

執行測試 Pod 以在叢集內手動測試運作狀態檢查:

$ kubectl run -n YOUR_NAMESPACE troubleshoot -it --rm --image=amazonlinux -- /bin/bash

接著執行 HTTP 運作狀態檢查:

# curl -Iv APPLICATION_POD_IP/HEALTH_CHECK_PATH

**注意:**將 APPLICATION_POD_IP 取代為您的應用程式 Pod IP 位址,並將 HEALTH_CHECK_PATH 取代為 Application Load Balancer 目標群組運作狀態檢查路徑。

範例命令:

# 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 回應狀態代碼為 3xx4xx,請變更運作狀態檢查路徑。下列註釋回應 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

**注意:**將 APPLICATION_POD_IP 取代為您的應用程式 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 叢集中的多個節點群組可以彼此自由通訊。
  • 如果網路存取控制清單 (網路 ACL) 與您 Pod 執行的子網路相關聯,允許來自負載平衡器子網路 CIDR 範圍的流量。
  • 如果網路 ACL 與負載平衡器子網路相關聯,允許從 Pod 執行的子網路臨時連接埠範圍傳回流量。
  • 路由表允許來自 VPC CIDR 範圍內的本機流量。

重新啟動 kube-proxy

如果每個節點上執行的 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 負載平衡器控制器設定 Application Load Balancer?

如何疑難排解由 Amazon EKS 中 Kubernetes 服務控制器建立的負載平衡器?

如何在 Amazon EKS 中自動探索 Application Load Balancer 使用的子網路?