全部產品
Search
文件中心

Container Service for Kubernetes:Service異常問題排查

更新時間:Dec 28, 2024

本文介紹關於LoadBalancer型Service的異常問題診斷流程和排查思路。

背景資訊

當Service的類型設定為Type=LoadBalancer時,Container ServiceACK的CCM(Cloud Controller Manager)組件會自動為該Service建立或配置阿里雲傳統型負載平衡CLB(Classic Load Balancer),包括CLB、監聽、後端伺服器組等資源。關於CLB的自動更新策略,請參見Service的負載平衡配置注意事項

診斷流程

執行排查前,請確保CCM組件版本不低於V1.9.3.276-g372aa98-aliyun。關於如何升級CCM,請參見升級CCM組件。關於CCM的發布記錄,請參見Cloud Controller Manager

Service troubleshooting process

  1. 執行以下命令,確定CLB關聯的Service。

    kubectl get svc -A |grep -i LoadBalancer|grep {XXX.XXX.XXX.XXX}  # XXX.XXX.XXX.XXX是loadbalancer IP。
  2. 執行以下命令,檢查對應Service是否存在報錯事件。

    kubectl -n {your-namespace} describe svc {your-svc-name}
    重要

    如果您執行命令後看不到Event資訊,請確認您的CCM組件版本不低於V1.9.3.276-g372aa98-aliyun。關於如何查看及升級CCM版本,請參見升級CCM組件

  3. 如果以上排查無果,請提交工單

Service例外狀況事件及處理方式

不同報錯資訊的解決方案如下表所示。

報錯資訊

說明及解決方案

The backend server number has reached to the quota limit of this load balancers

指CLB的後端伺服器配額不足。

解決方案:您可以採取以下方式,最佳化配額消耗。

  • 預設情況下一個CLB執行個體可以掛載200個後端伺服器,請申請提升配額。關於如何查詢和提升配額,請登入Server Load Balancer配額管理

  • 建議您設定CLB外部流量策略為Local模式(設定externalTrafficPolicy: Local),因為Cluster模式會快速消耗配額。如果需要使用Cluster模式,建議通過標籤service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-label來指定使用的虛擬伺服器,從而減少配額消耗。關於如何在註解中添加標籤關聯後端的虛擬伺服器的操作,請參見通過Annotation配置傳統型負載平衡CLB

  • 由於多個Service複用一個CLB時,後端伺服器數是累加的。建議您建立Service時,建立CLB。

The loadbalancer does not support backend servers of eni type

共用型CLB不支援ENI。

解決方案:如果CLB後端使用的是ENI,您需要選擇效能保障型CLB執行個體。在Service中添加註解annotation: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: "slb.s1.small"

重要

添加註解需要注意是否符合CCM的版本要求。關於註解和CCM的版本對應關係,請參見通過Annotation配置傳統型負載平衡CLB

There are no available nodes for LoadBalancer

CLB無後端伺服器,請確認Service是否已關聯Pod且Pod正常運行。

解決方案:

  • 若未關聯Pod,請將Service關聯至應用Pod。

  • 若關聯的Pod運行異常,請定位解決Pod異常,具體操作請參見Pod異常問題排查

  • 如果CLB無後端伺服器但Pod正常運行,請檢查Pod所在節點是否為Master節點。如果是,請將業務Pod驅逐到Worker節點。如果不是,請提交工單

  • alicloud: not able to find loadbalancer named [%s] in openapi, but it's defined in service.loaderbalancer.ingress. this may happen when you removed loadbalancerid annotation

  • alicloud: can not find loadbalancer, but it's defined in service

無法根據Service關聯CLB。

解決方案:登入負載平衡管理主控台,根據Service的EXTERNAL-IP,在其所在的地區搜尋CLB。

  1. 如果搜尋不到CLB,且該Service無需再使用,則刪除對應的Service即可。

  2. 如果CLB存在,執行以下步驟。

    1. 如果CLB是手動在CLB控制台建立,在Service中添加註解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id。詳情請參見通過Annotation配置傳統型負載平衡CLB

    2. 如果CLB是由CCM自動建立,確認該CLB是否有標籤kubernetes.do.not.delete。如果沒有,請添加標籤。具體操作,請參見舊版本CCM如何支援SLB重新命名?

ORDER.ARREARAGE Message: The account is arrearage.

帳號欠費。

PAY.INSUFFICIENT_BALANCE Message: Your account does not have enough balance.

賬戶餘額不足。

Status Code: 400 Code: Throttlingxxx

CLB OpenAPI限流。

解決方案:

  1. 請登入Server Load Balancer配額管理,查看並確保CLB配額充足。

  2. 執行以下命令,查看叢集Service是否存在異常。如果存在,請參照此表處理例外狀況事件。

    kubectl -n {your-namespace} describe svc {your-svc-name}

Status Code: 400 Code: RspoolVipExist Message: there are vips associating with this vServer group.

無法刪除虛擬伺服器組關聯的監聽。

解決方案:

  1. 確認Service中的註解是否帶有CLB執行個體的ID(例如service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: {your-clb-id})。

    如果註解帶有CLB執行個體ID,說明是複用的CLB。

  2. 在CLB控制台中刪除Service中port對應的監聽。關於如何刪除CLB監聽,請參見配置監聽轉寄規則

Status Code: 400 Code: NetworkConflict

複用內網CLB時,該CLB和叢集不在同一個VPC內。

解決方案:請確保您的CLB和叢集在同一個VPC內。

Status Code: 400 Code: VSwitchAvailableIpNotExist Message: The specified VSwitch has no available ip.

虛擬交換器不足。

解決方案:通過service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vswitch-id: "${YOUR_VSWITCH_ID}"指定同VPC下另一個虛擬交換器。

The specified Port must be between 1 and 65535.

ENI模式不支援String類型的targetPort

解決方案:將Service YAML中的targetPort欄位改為INT類型或者升級CCM。關於如何升級CCM,請參見升級CCM組件

Status Code: 400 Code: ShareSlbHaltSales Message: The share instance has been discontinued.

低版本CCM預設建立共用型CLB,但該類型CLB已停止售賣。

解決方案:升級CCM組件

can not change ResourceGroupId once created

CLB資源群組一旦建立後不支援修改。

解決方案:移除Service中的註解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-resource-group-id:"rg-xxxx"

can not find eniid for ip x.x.x.x in vpc vpc-xxxx

無法在VPC內找到指定的ENI IP。

解決方案:確認Service中是否配置了註解service.beta.kubernetes.io/backend-type:eni。如果已配置,請確認叢集網路外掛程式是否為Flannel。Flannel網路模式不支援ENI模式,移除Service中對應的註解即可。

  • The operation is not allowed because the instanceChargeType of loadbalancer is PayByCLCU.

  • User does not have permission modify InstanceChargeType to spec.

CLB計費類型不支援從隨用隨付轉為按規格收費。

解決方案:

  • 移除service中的Annotation:service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec

  • 如果service中有service.beta.kubernetes.io/alibaba-cloud-loadbalancer-instance-charge-type,取值需設定為PayByCLCU

SyncLoadBalancerFailed the loadbalancer xxx can not be reused,can not reuse loadbalancer created by kubernetes.

複用了CCM建立的CLB。

解決方案:

  1. 查看Service YAML中的annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id對應的CLB ID。

  2. 根據Service狀態處理報錯。

    • 如果Service為pending狀態,您需要替換annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的CLB ID,更改為手動在傳統型負載平衡CLB控制台建立的CLB。

    • 如果Service不是pending狀態,根據以下實際情況處理。

      • 如果CLB對應的IP與Service的external IP一致,刪除annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id即可。

      • 如果CLB對應的IP與Service的external IP不一致,您需要登入傳統型負載平衡CLB控制台,找到叢集對應Region,根據Service的external IP尋找對應的CLB,更改annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的CLB ID。如果沒有找到對應的CLB,更改annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的CLB ID為手動在CLB控制台建立的CLB,然後重建Service。

alicloud: can not change LoadBalancer AddressType once created. delete and retry

CLB的類型一旦建立後不可更改,建立Service後更改了CLB的類型會導致該報錯。

解決方案:刪除重建Service。

the loadbalancer lb-xxxxx can not be reused, service has been associated with ip [xxx.xxx.xxx.xxx], cannot be bound to ip [xxx.xxx.xxx.xxx]

Service已經綁定一個CLB,不能再綁定另一個CLB。

解決方案:不支援通過更改service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id的CLB ID的方式複用已有CLB。如果需要更改綁定的CLB,需要刪除重建Service。

排查思路

對於非Service報錯類的異常問題,請參考下表進行排查。

問題類別

問題現象

解決方案

CLB訪問類

CLB負載不均

CLB負載不均

應用程式更新過程中訪問CLB出現503報錯

應用程式更新過程中訪問CLB出現503報錯

叢集內無法訪問CLB

叢集內無法訪問CLB

叢集外無法訪問CLB

叢集外無法訪問CLB

訪問HTTPS連接埠報錯The plain HTTP request was sent to HTTPS port

無法串連到後端HTTPS服務

CLB配置類

Serivce註解未生效

Service註解不生效如何處理?

CLB配置被修改

為何CLB的配置被修改?

複用已有CLB未生效

Service FAQ

複用已有CLB未配置監聽

為什麼複用已有CLB時沒有配置監聽?

CLB後端不一致

SLB虛擬伺服器組未更新如何處理?

CLB刪除類

CLB被刪除

什麼情況下會自動刪除SLB?

Service刪除後CLB未刪除

什麼情況下會自動刪除SLB?

CLB負載不均

問題原因

CLB的調度演算法設定不合理。

問題現象

CLB後端伺服器負載不均。

解決方案

  • Local模式Service(即externalTrafficPolicy: Local)需要將CLB調度演算法設定為加權輪詢演算法,即為Service添加註解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wrr"

  • 如果業務為長串連,則需要將CLB調度演算法設定為加權最少串連演算法,即為Service添加註解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wlc"

應用程式更新過程中訪問CLB出現503報錯

問題原因

沒有對CLB監聽設定串連優雅中斷,或沒有對Pod設定優雅終止。

問題現象

應用程式更新過程中訪問CLB出現503報錯。

解決方案

  1. 通過service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain等註解為CLB監聽設定串連優雅中斷。關於註解的詳細說明,請參見監聽的典型操作

  2. 根據容器網路模式,設定Pod的preStopreadinessProbe

    • readinessProbe為就緒檢查。只有就緒檢查通過後,Pod才會被加入到Endpoint中。Container ServiceACK監控到Endpoint變化後才會將Node掛載到CLB後端。需要合理設定就緒檢測(readinessProbe)的探測頻率、延時時間、不健康閾值等資料,部分應用啟動時間本身較長,如果設定的時間過短,會導致Pod反覆重啟。

    • preStop時間建議設定為業務處理完所有剩餘請求所需的時間,terminationGracePeriodSeconds 時間建議設定為preStop的時間再加30秒以上。

    Pod配置樣本:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      namespace: default
    spec:
      containers:
      - name: nginx
        image: nginx
        # 存活檢測
        livenessProbe:
          failureThreshold: 3
          initialDelaySeconds: 30
          periodSeconds: 30
          successThreshold: 1
          tcpSocket:
            port: 5084
          timeoutSeconds: 1
        # 就緒檢測
        readinessProbe:
          failureThreshold: 3
          initialDelaySeconds: 30
          periodSeconds: 30
          successThreshold: 1
          tcpSocket:
            port: 5084
          timeoutSeconds: 1
        # 優雅退出
        lifecycle:
          preStop:
            exec:
              command:
              - sleep
              - 30
      terminationGracePeriodSeconds: 60

叢集內無法訪問CLB

問題原因

CLB設定了externalTrafficPolicy: Local類型,這種類型的CLB地址只有在Node中部署了對應的後端Pod,才能被訪問。因為CLB的地址是叢集外使用,如果叢集節點和Pod不能直接存取,請求不會到CLB,會被當作Service的擴充IP地址,被kube-proxy的iptables或ipvs轉寄。

如果剛好叢集節點或者Pod所在的節點上沒有相應的後端服務Pod,就會發生網路不通的問題,而如果有相應的後端服務Pod,是可以正常訪問。相關問題的更多資訊請參見kube-proxy將external-lb的地址添加到節點本地iptables規則

問題現象

叢集內無法訪問CLB。

解決方案

  • 在Kubernetes叢集內通過ClusterIP或者服務名訪問。

    其中Ingress的服務名為:nginx-ingress-lb.kube-system

  • 將LoadBalancer的Service中的externalTrafficPolicy修改為Cluster,但是在應用中會丟失原IP,Ingress的服務修改命令如下。

    說明

    若是Ingress的CLB,只有Ingress的Pod所在節點上,Pod才能訪問通過Ingress或CLB暴露出去的服務。

    kubectl edit svc nginx-ingress-lb -n kube-system
  • 若是Terway的ENI或者ENI多IP的叢集,將LoadBalancer的Service中的externalTrafficPolicy修改為Cluster,並且添加ENI直通的annotation,例如annotation: service.beta.kubernetes.io/backend-type:"eni",具體格式如下,可以保留源IP,並且在叢集內訪問也沒有問題。詳細資料,請參見通過Annotation配置傳統型負載平衡CLB

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/backend-type: eni
      labels:
        app: nginx-ingress-lb
      name: nginx-ingress-lb
      namespace: kube-system
    spec:
      externalTrafficPolicy: Cluster

叢集外無法訪問CLB

問題原因

CLB設定了ACL或CLB未正常運行。

問題現象

叢集外無法訪問CLB。

解決方案

  1. 執行以下命令,查看Service事件資訊,並處理例外狀況事件。具體操作,請參見Service例外狀況事件及處理方式

    kubectl -n {your-namespace} describe svc {your-svc-name}
  2. 確認CLB是否配置了ACL。

    如果配置了ACL,請確認ACL是否允許用戶端IP訪問。關於CLB的ACL配置,請參見存取控制

  3. 確認CLB虛擬伺服器組是否為空白。

    如果虛擬伺服器組為空白,請檢查業務Pod是否關聯了Service及業務Pod是否正常運行。如果關聯的Pod運行異常,請定位解決Pod異常。具體操作,請參見Pod異常問題排查

  4. 確認CLB監聽的健全狀態檢查是否正常。

    如果CLB健全狀態檢查異常,請檢查業務Pod是否正常運行。關於CLB的健全狀態檢查,請參見健全狀態檢查探測

  5. 如果以上步驟未解決您的問題,請提交工單

無法串連到後端HTTPS服務

問題原因

CLB上配置認證後將會在CLB側進行解密,導致實際發送到後端Pod的請求為HTTP請求。

問題現象

無法串連到後端HTTPS服務。

解決方案

將Serivce中HTTPS連接埠對應的Target Port配置為HTTP連接埠。以Nginx為例,HTTPS連接埠為443,其對應的targetPort需要改為80

配置樣本:

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "https:443"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id: "${YOUR_CERT_ID}"
  name: nginx
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  - port: 443
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  type: LoadBalancer