全部产品
Search
文档中心

容器计算服务 ACS:Service异常问题排查

更新时间:Aug 23, 2024

本文介绍关于LoadBalancer型Service的异常问题诊断流程和排查思路。

背景信息

当Service的类型设置为Type=LoadBalancer时,容器计算服务ACS的CCM(Cloud Controller Manager)组件会自动为该Service创建或配置阿里云负载均衡SLB(Server Load Balancer),包括SLB、监听、后端服务器组等资源。关于SLB的自动更新策略,请参见Service的负载均衡配置注意事项

诊断流程

执行排查前,请确保CCM组件版本不低于V1.9.3.276-g372aa98-aliyun。关于如何升级CCM,请参见升级CCM组件。关于CCM的发布记录,请参见Cloud Controller Manager

Service troubleshooting process

  1. 执行以下命令,确定SLB关联的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 loadbalancer does not support backend servers of eni type

共享型SLB不支持ENI。

解决方案:如果SLB后端使用的是ENI,您需要选择性能保障型SLB实例。在Service中添加注解annotation: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: "slb.s1.small"

重要

添加注解需要注意是否符合CCM的版本要求。关于注解和CCM的版本对应关系,请参见通过Annotation配置传统型负载均衡CLB

There are no available nodes for LoadBalancer

SLB无后端服务器,请确认Service是否已关联Pod且Pod正常运行。

解决方案:

  • 若未关联Pod,请将Service关联至应用Pod。

  • 若关联的Pod运行异常,请定位解决Pod异常。具体操作,请参见Pod异常问题排查

  • 如果SLB无后端服务器但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关联SLB。

解决方案:登录负载均衡管理控制台,根据Service的EXTERNAL-IP,在其所在的地域搜索SLB。

  1. 如果搜索不到SLB,且该Service无需再使用,则删除对应的Service即可。

  2. 如果SLB存在,执行以下步骤。

    1. 如果SLB是手动在SLB控制台创建,在Service中添加注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id。详情请参见通过Annotation配置传统型负载均衡CLB

    2. 如果SLB是由CCM自动创建,确认该SLB是否有标签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

SLB OpenAPI限流。

解决方案:

  1. 请登录负载均衡SLB配额管理,查看并确保SLB配额充足。

  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中的注解是否带有SLB实例的ID(例如service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: {your-slb-id})。

    如果注解带有SLB实例ID,说明是复用的SLB。

  2. 在SLB控制台中删除Service中port对应的监听。关于如何删除SLB监听,请参见配置监听转发规则

Status Code: 400 Code: NetworkConflict

复用内网SLB时,该SLB和集群不在同一个VPC内。

解决方案:请确保您的SLB和集群在同一个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默认创建共享型SLB,但该类型SLB已停止售卖。

解决方案:升级CCM组件

can not change ResourceGroupId once created

SLB资源组一旦创建后不支持修改。

解决方案:移除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.

SLB计费类型不支持从按量付费转为按规格收费。

解决方案:

  • 移除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创建的SLB。

解决方案:

  1. 查看Service YAML中的annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id对应的SLB ID。

  2. 根据Service状态处理报错。

    • 如果Service为pending状态,您需要替换annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的SLB ID,更改为手动在传统型负载均衡CLB控制台创建的SLB。

    • 如果Service不是pending状态,根据以下实际情况处理。

      • 如果SLB对应的IP与Service的external IP一致,删除annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id即可。

      • 如果SLB对应的IP与Service的external IP不一致,您需要登录传统型负载均衡CLB控制台,找到集群对应Region,根据Service的external IP查找对应的SLB,更改annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的SLB ID。如果没有找到对应的SLB,更改annotationservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-id中的SLB ID为手动在SLB控制台创建的SLB,然后重建Service。

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

SLB的类型一旦创建后不可更改,创建Service后更改了SLB的类型会导致该报错。

解决方案:删除重建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已经绑定一个SLB,不能再绑定另一个SLB。

解决方案:不支持通过更改service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id的SLB ID的方式复用已有SLB。如果需要更改绑定的SLB,需要删除重建Service。

排查思路

对于非Service报错类的异常问题,请参考下表进行排查。

问题类别

问题现象

解决方案

SLB访问类

SLB负载不均

SLB负载不均

应用更新过程中访问SLB出现503报错

应用更新过程中访问SLB出现503报错

集群内无法访问SLB

Kubernetes集群中访问LoadBalancer暴露出去的SLB地址不通

集群外无法访问SLB

集群外无法访问SLB

访问HTTPS端口报错The plain HTTP request was sent to HTTPS port

访问HTTPS端口报错

SLB配置类

Serivce注解未生效

Service注解不生效如何处理?

SLB配置被修改

为何SLB的配置被修改?

复用已有SLB未生效

为什么复用已有SLB没有生效?

复用已有SLB未配置监听

为什么复用已有SLB时没有配置监听?

SLB后端不一致

SLB虚拟服务器组未更新如何处理?

SLB删除类

SLB被删除

什么情况下会自动删除SLB?

Service删除后SLB未删除

什么情况下会自动删除SLB?

SLB负载不均

问题原因

SLB的调度算法设置不合理。

问题现象

SLB后端服务器负载不均。

解决方案

  • 如果业务为长连接,则需要将SLB调度算法设置为加权最少连接算法,即为Service添加注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wlc"

应用更新过程中访问CLB出现503报错

问题原因

没有对SLB监听设置连接优雅中断,或没有对Pod设置优雅终止。

问题现象

应用更新过程中访问SLB出现503报错。

解决方案

  1. 通过service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain等注解为SLB监听设置连接优雅中断。关于注解的详细说明,请参见监听的典型操作

  2. 根据容器网络模式,设置Pod的preStopreadinessProbe

    • readinessProbe为就绪检查。只有就绪检查通过后,Pod才会被加入到Endpoint中。容器计算服务ACS监控到Endpoint变化后才会将Pod挂载到SLB后端。需要合理设置就绪检测(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

集群外无法访问SLB

问题原因

SLB设置了ACL或SLB未正常运行。

问题现象

集群外无法访问SLB。

解决方案

  1. 执行以下命令,查看Service事件信息,并处理异常事件。具体操作,请参见Service异常事件及处理方式

    kubectl -n {your-namespace} describe svc {your-svc-name}
  2. 确认SLB是否配置了ACL。

    如果配置了ACL,请确认ACL是否允许客户端IP访问。关于SLB的ACL配置,请参见访问控制

  3. 确认SLB虚拟服务器组是否为空。

    如果虚拟服务器组为空,请检查业务Pod是否关联了Service及业务Pod是否正常运行。如果关联的Pod运行异常,请定位解决Pod异常。具体操作,请参见Pod异常问题排查

  4. 确认SLB监听的健康检查是否正常。

    如果SLB健康检查异常,请检查业务Pod是否正常运行。关于SLB的健康检查,请参见健康检查探测

  5. 如果以上步骤未解决您的问题,请通过产品钉钉群咨询。

无法连接到后端HTTPS服务

问题原因

SLB上配置证书后将会在SLB侧进行解密,导致实际发送到后端Pod的请求为HTTP请求。

问题现象

无法连接到后端HTTPS服务。

解决方案

将Service中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