文档首页> 云容器引擎 CCE> 常见问题> 网络管理> 网络异常> 集群内部无法使用ELB地址访问负载
更新时间:2024-01-18 GMT+08:00

集群内部无法使用ELB地址访问负载

问题现象

在集群内部(节点上或容器中),使用ELB地址无法访问。

问题原因

当Service设置了服务亲和为节点级别,即externalTrafficPolicy取值为Local时,在使用中可能会碰到从集群内部(节点上或容器中)访问不通的情况,回显类似如下内容:
upstream connect error or disconnect/reset before headers. reset reason: connection failure
或:
curl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused

在集群中访问ELB地址时出现无法访问的场景较为常见,这是由于Kubernetes在创建Service时,kube-proxy会把ELB的访问地址作为外部IP(即External-IP,如下方回显所示)添加到iptables或IPVS中。如果客户端从集群内部发起访问ELB地址的请求,该地址会被认为是服务的外部IP,被kube-proxy直接转发,而不再经过集群外部的ELB。

当externalTrafficPolicy的取值为Local时,在不同容器网络模型和服务转发模式下访问不通的场景如下:
  • 多实例的工作负载需要保证所有实例均可正常访问,否则可能出现概率性访问不通的情况。
  • CCE Turbo集群(云原生2.0网络模型)中,仅当Service的后端对接使用主机网络(HostNetwork)的Pod时,亲和级别支持配置为节点级别。
  • 表格中仅列举了可能存在访问不通的场景,其他不在表格中的场景即表示可以正常访问。

服务端发布服务类型

访问类型

客户端请求发起位置

容器隧道集群(IPVS)

VPC集群(IPVS)

容器隧道集群(IPTABLES)

VPC集群(IPTABLES)

节点访问类型Service

公网/私网

与服务Pod同节点

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

与服务Pod不同节点

访问服务端所在节点IP+NodePort — 通

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 通

访问非服务端所在节点IP+NodePort — 无法访问

正常访问

正常访问

与服务Pod同节点的其他容器

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

无法访问

与服务Pod不同节点的其他容器

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

独享型负载均衡类型Service

私网

与服务Pod同节点

无法访问

无法访问

无法访问

无法访问

与服务Pod同节点的其他容器

无法访问

无法访问

无法访问

无法访问

DNAT网关类型Service

公网

与服务Pod同节点

无法访问

无法访问

无法访问

无法访问

与服务Pod不同节点

无法访问

无法访问

无法访问

无法访问

与服务Pod同节点的其他容器

无法访问

无法访问

无法访问

无法访问

与服务Pod不同节点的其他容器

无法访问

无法访问

无法访问

无法访问

nginx-ingress插件对接独享型ELB(Local)

私网

与cceaddon-nginx-ingress-controller Pod同节点

无法访问

无法访问

无法访问

无法访问

与cceaddon-nginx-ingress-controller Pod同节点的其他容器

无法访问

无法访问

无法访问

无法访问

解决办法

解决这个问题通常有如下办法:

  • 推荐)在集群内部访问使用Service的ClusterIP或服务域名访问。
  • 将Service的externalTrafficPolicy设置为Cluster,即集群级别服务亲和。不过需要注意这会影响源地址保持。
    apiVersion: v1 
    kind: Service
    metadata: 
      annotations:   
        kubernetes.io/elb.class: union
        kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"traffic","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}'
      labels: 
        app: nginx 
      name: nginx 
    spec: 
      externalTrafficPolicy: Cluster
      ports: 
      - name: service0 
        port: 80
        protocol: TCP 
        targetPort: 80
      selector: 
        app: nginx 
      type: LoadBalancer
  • 使用Service的pass-through特性,使用ELB地址访问时绕过kube-proxy,先访问ELB,经过ELB再访问到负载。
    • 独享型负载均衡配置pass-through后,CCE Standard集群在工作负载同节点和同节点容器内无法通过Service访问。
    • 1.15及以下老版本集群暂不支持该能力。
    • IPVS网络模式下,对接同一个ELB的Service需保持pass-through设置情况一致。
    • 使用节点级别(Local)的服务亲和的场景下,会自动设置kubernetes.io/elb.pass-through为onlyLocal,开启pass-through能力。
    apiVersion: v1 
    kind: Service 
    metadata: 
      annotations:   
        kubernetes.io/elb.pass-through: "true"
        kubernetes.io/elb.class: union
        kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"traffic","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}'
      labels: 
        app: nginx 
      name: nginx 
    spec: 
      externalTrafficPolicy: Local
      ports: 
      - name: service0 
        port: 80
        protocol: TCP 
        targetPort: 80
      selector: 
        app: nginx 
      type: LoadBalancer