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

更新时间:

问题描述

在Kubernetes集群中有部分节点能访问集群暴露出去的Local类型SLB,但是也有部分节点不能访问,且Ingress出现该问题较多。

问题原因

SLB设置了externalTrafficPolicy: Local类型,这种类型的SLB地址只有在Node中部署了对应的后端Pod,才能被访问。因为SLB的地址是集群外使用,如果集群节点和Pod不能直接访问,请求不会到SLB,会被当作Service的扩展IP地址,被kube-proxy的iptables或ipvs转发。

如果刚好集群节点或者Pod所在的节点上没有相应的后端服务Pod,就会发生网络不通的问题,而如果有相应的后端服务Pod,是可以正常访问。相关问题的更多信息请参见kube-proxy将external-lb的地址添加到节点本地iptables规则

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

若出现该问题,可以参见以下方法解决问题,推荐您使用第一种方法:

  • 在Kubernetes集群内通过ClusterIP或者服务名访问。
    其中Ingress的服务名为:nginx-ingress-lb.kube-system
  • 将LoadBalancer的Service中的externalTrafficPolicy修改为Cluster,但是在应用中会丢失源IP,Ingress的服务修改命令如下。
    说明:若是Ingress的SLB,只有Ingress的Pod所在节点上,Pod才能访问通过Ingress或SLB暴露出去的服务。
    • 修改Ingress上的svc为Cluster类型,集群会进行SNAT,Ingress的Pod不在的节点上也可以访问Ingress或SLB暴露出去的服务,后端应用无法获取客户端真实IP地址。
    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,并且在集群内访问也没有问题。详细信息请参见通过负载均衡(Server Load Balancer)访问服务
    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

适用于

  • 容器服务Kubernetes版

说明:请在升级到Kubernetes V1.14之前检查下是否做了对应配置,排除升级后出现该问题的风险。