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

背景信息

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

诊断流程

执行排查前,请确保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 ${your-loadbalancer-id}
  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

指SLB的后端服务器配额不足。

解决方案:您可以采取以下方式,优化配额消耗。
  • 默认情况下一个SLB实例可以挂载200个后端服务器,请申请提升配额。关于如何查询和提升配额,请登录负载均衡SLB配额管理
  • 建议您设置SLB外部流量策略为Local模式(设置externalTrafficPolicy: Local),因为Cluster模式会快速消耗配额。如果需要使用Cluster模式,建议通过标签service.beta.kubernetes.io/alibaba-cloud-loadbalancer-backend-label来指定使用的虚拟服务器,从而减少配额消耗。关于如何在注解中添加标签关联后端的虚拟服务器的操作,请参见通过Annotation配置负载均衡
  • 由于多个Service复用一个SLB时,后端服务器数是累加的。建议您创建Service时,新建SLB。
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的版本对应关系,请参见常用注解
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配置负载均衡
    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中对应的注解即可。

排查思路

对于非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后端服务器负载不均。

解决方案
  • Local模式Service(即externalTraficPolicy: Local)需要将SLB调度算法设置为加权轮询算法,即为Service添加注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wrr"
  • 如果业务为长连接,则需要将SLB调度算法设置为加权最少连接算法,即为Service添加注解service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wlc"

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

问题原因

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

问题现象

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

解决方案
  1. 通过service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain等注解为SLB监听设置连接优雅中断。关于注解的详细说明,请参见监听
  2. 根据容器网络模式,设置Pod的preStopreadinessProbe
    • readinessProbe为就绪检查。只有就绪检查通过后,Pod才会被加入到Endpoint中。容器服务ACK监控到Endpoint变化后才会将Node挂载到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服务。

解决方案

将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