文档首页/ 云容器引擎 CCE/ 用户指南/ 网络/ 服务(Service)/ 负载均衡(LoadBalancer)/ 为负载均衡类型的Service配置pass-through能力
更新时间:2024-08-17 GMT+08:00

为负载均衡类型的Service配置pass-through能力

操作场景

对于负载均衡类型的Service,负责集群内部流量转发的kube-proxy组件默认会将Service绑定的ELB IP地址配置到节点本地的转发规则中,从集群内部访问ELB的地址时,流量就会直接在集群内部转发,而不会经过ELB转发。

如果Service设置了服务亲和为节点级别,即externalTrafficPolicy取值为Local,Service将只会把流量转发给本节点上的Pod。从集群内部(节点上或容器中)访问Pod时,如果客户端所在节点正好没有相应的后端服务Pod,可能会出现访问不通的情况。

解决方案

CCE服务支持pass-through能力,在负载均衡类型的Service中配置kubernetes.io/elb.pass-through的annotation,可以实现集群内部访问Service的ELB地址时绕出集群,并通过ELB的转发最终转发到后端的Pod。

图1 pass-through访问示例
  • 对于CCE集群:

    集群内部客户端访问LB类型Service时,访问请求默认是通过集群服务转发规则(iptables或IPVS)转发到后端的容器实例。

    当LB类型Service配置elb.pass-through后,集群内部客户端访问Service地址时会先访问到ELB,再通过ELB的负载均衡能力先访问到节点,然后通过集群服务转发规则(iptables或IPVS)转发到后端的容器实例。

  • 对于CCE Turbo集群:

    集群内部客户端访问LB类型Service时,默认使用pass-through方式,此时客户端会直接访问ELB私网地址,然后通过ELB直接连接容器实例。

约束限制

  • 在CCE Standard集群中,当使用独享型负载均衡配置pass-through后,从工作负载Pod所在节点或同节点的其他容器中访问ELB的私网IP地址,会出现无法访问的问题。
  • 1.15及以下老版本集群暂不支持该能力。
  • IPVS网络模式下,对接同一个ELB的Service需保持pass-through设置情况一致。
  • 使用节点级别(Local)的服务亲和的场景下,会自动设置kubernetes.io/elb.pass-through为onlyLocal,开启pass-through能力。

操作步骤

本文以Nginx镜像创建无状态工作负载为例,创建一个具有pass-through的Service。

  1. 使用kubectl命令行工具连接集群。详情请参见通过kubectl连接集群
  2. 使用Nginx镜像创建无状态工作负载。

    创建nginx-deployment.yaml文件,内容如下:

    apiVersion: apps/v1     
    kind: Deployment         
    metadata:
      name: nginx            
    spec:
      replicas: 2                     
      selector:              
        matchLabels:
          app: nginx
      template:              
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx:latest
            name: container-0
            resources:
              limits:
                cpu: 100m
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 200Mi
          imagePullSecrets:
          - name: default-secret
    执行以下命令,部署工作负载。
    kubectl create -f nginx-deployment.yaml

  3. 创建负载均衡类型的Service,并设置“kubernetes.io/elb.pass-through”“true”关于负载均衡类型的Service具体创建方法,请参见自动创建负载均衡类型Service

    创建nginx-elb-svc.yaml文件内容如下,本示例中自动创建了一个名为james的共享型ELB实例。
    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":"bandwidth","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

  4. 执行以下命令创建服务。

    kubectl create -f nginx-elb-svc.yaml

配置验证

  1. 登录ELB控制台,查看Service对应的ELB(本示例中名为james)。
  2. 单击ELB名称,并切换至“监控”,可以看到ELB的连接数为0。

  3. 使用kubectl命令行登录集群中的任意一个Nginx容器中,然后访问ELB的地址。

    1. 查询集群中的Nginx容器。
      kubectl get pod
      回显如下:
      NAME                     READY   STATUS    RESTARTS   AGE
      nginx-7c4c5cc6b5-vpncx   1/1     Running   0          9m47s
      nginx-7c4c5cc6b5-xj5wl   1/1     Running   0          9m47s
    2. 登录任意一个Nginx容器。
      kubectl exec -it nginx-7c4c5cc6b5-vpncx -- /bin/sh
    3. 访问ELB地址。
      curl **.**.**.**

  4. 稍微等待一段时间,查看ELB控制台的监控数据。

    如果ELB出现新建访问连接,说明本次访问经过ELB转发,与预期一致。