如何解決 Amazon EKS 中 Network Load Balancer 的目標運作狀態不佳問題?

上次更新日期︰2022 年 1 月 6 日

我想在 Amazon Elastic Kubernetes Service (Amazon EKS) 中解決 Network Load Balancer 的目標運作狀態不佳問題。

簡短描述

以下是 Network Load Balancer 的目標運作狀態不佳常見原因:

  • 運作狀態檢查設定不正確。若要解決此問題,請從 Amazon Virtual Private Cloud (Amazon VPC) 中執行的主機手動啟動運作狀態檢查。
  • Pod 中存在非預期的例外狀況。若要解決此問題,請遵循檢查 Pod 中是否存在非預期例外狀況解決方案部分中的疑難排解步驟。
  • Network Load Balancer 的 externalTrafficPolicy 設定為本機 (來自 Kubernetes 網站),並在 DHCP 選項集上使用自訂 Amazon VPC DNS。若要解決此問題,請使用主機名稱覆寫標誌修補 kube-proxy

注意:您可以透過查看服務注釋 service.beta.kubernetes.io/aws-load-balancer-nlb-target-type 是否存在,來確定目標群組類型是 IP 地址還是執行個體。

解決方案

驗證目標群組是否為 IP 地址或執行個體

執行以下命令:

kubectl get service service_name -o yaml

注意:用您的服務名稱取代 service_name。如果 service.beta.kubernetes.io/aws-load-balancer-nlb-target-type 註釋不存在,則預設目標類型為執行個體。

驗證運作狀態檢查設定是否正確

檢查是否已針對您的服務設定 Elastic Load Balancing (ELB) 註釋 (來自 Kubernetes 網站):

`kubectl get service service_name -o yaml`

範例輸出:

service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
# The number of successive successful health checks required for a backend to be considered healthy for traffic. Defaults to 2, must be between 2 and 10

service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
# The number of unsuccessful health checks required for a backend to be considered unhealthy for traffic. Defaults to 6, must be between 2 and 10

service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "20"
# The approximate interval, in seconds, between health checks of an individual instance. Defaults to 10, must be between 5 and 300

service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
# The amount of time, in seconds, during which no response means a failed health check. This value must be less than the service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval value. Defaults to 5, must be between 2 and 60

service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol: TCP
service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: traffic-port
# can be integer or traffic-port

service.beta.kubernetes.io/aws-load-balancer-healthcheck-path
# health check path.

如果前述註釋設定不正確,則目標可能運作狀態不佳。

從 Amazon VPC 中執行的主機手動啟動運作狀態檢查

針對執行個體目標類型,請透過 NodePort 執行以下 curl 命令:

curl-ivk node_IP:NodePort

注意:用您節點的 IP 地址取代 node_IP

針對 IP 地址目標類型,請執行以下 curl 命令:

curl -ivk pod_IP:pod_port

注意:用您 Pod 的 IP 地址取代 pod_IP,用您 Pod 的連接埠取代 pod_port

檢查 Pod 中是否存在非預期的例外狀況

執行個體目標類型

檢查服務規範以了解目前的運作狀態檢查組態註釋 (來自 GitHub 網站):

kubectl get service service_name -o yaml

檢查是否存在端點以驗證服務之後是否存在 Pod:

kubectl get endpoints service_name -o yaml

如果服務不存在端點,則檢查 Pod 標籤和服務標籤是否相符:

kubectl describe service
kubectl describe pod pod_name or kubectl get pod --show-labels

注意:用您 Pod 的名稱取代 pod_name

檢查 Pod 是否處於執行中狀態:

kubectl get pod -o wide

檢查 Pod 的狀態以驗證 Pod 是否在執行中而不會有任何重新啟動:

kubectl get pods -o wide

如果重新啟動,則會收集 Pod 日誌來確定原因:

kubectl logs pod_name
kubectl logs pod_name --previous

登入 Amazon VPC 中的主機,您可以在其中與節點進行通訊。

透過 NodePort 使用 curl 命令,來檢查 Pod 是否傳回預期的 HTTP 狀態碼:

curl node_IP:NodePort

如果 curl 命令沒有傳回預期的 HTTP 狀態碼,則後端 Pod 也不會傳回預期的 HTTP 狀態碼。

使用相同的主機連線至 Pod 的 IP 地址,並檢查 Pod 是否正確設定:

curl pod_IP:pod_port

如果 curl 命令沒有傳回預期的 HTTP 狀態碼,則無法正確設定 Pod。

注意:如果服務的 externalTrafficPolicy (來自 Kubernetes 網站) 設定為本機,則只有執行該服務之後端 Pod 的節點才會視為運作狀態正常的目標。

IP 地址目標類型

檢查服務規範以了解目前的運作狀態檢查組態註釋 (來自 GitHub 網站):

kubectl get service service_name -o yaml

登入 Amazon VPC 中的主機,並使用 curl 命令與 Pod 的 IP 地址進行通訊:

curl pod_IP:pod_port

如果 curl 命令沒有傳回預期的 HTTP 狀態碼,則無法正確設定 Pod。

請使用主機名稱覆寫標誌修補 kube-proxy

請使用以下方式修改 kube-proxy 常駐程式規範命令、引數和環境:

---
spec:
  template:
    spec:
      containers:
      - name: kube-proxy
        command: [ "/bin/sh" ]
        args:
        - -c
        - |
          kube-proxy --v=2 --hostname-override=$(NODE_NAME) --config=/var/lib/kube-proxy-config/config
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName

針對執行個體目標類型,如果 externalTrafficPolicy 設定為叢集本機,則對於 NodePort,節點安全群組的預設輸入設定為 0.0.0.0/0。此外,當 externalTrafficPolicy 設定為本機時,額外的運作狀態檢查 NodePort 設定為允許子網路 CIDR IP 地址範圍。

若要針對 NodePort 控制節點安全群組上的來源 IP 地址,請在規範中新增 loadBalancerSourceRanges,並包含以下範圍:

spec:
loadBalancerSourceRanges:
- "143.231.0.0/16"
- "xx.yy.zz.zz/24"

注意:如果未設定 .spec.loadBalancerSourceRanges,則 Kubernetes 將允許從 0.0.0.0/0 到節點安全群組的流量。如果節點具有公有 IP 地址,則非 Network Load Balancer 流量也可以到達修改後安全群組中的每一個執行個體。


此文章是否有幫助?


您是否需要帳單或技術支援?