
# 为负载均衡类型的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。
图1pass-through访问示例   
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001927010505.png "点击放大")
- 对于CCE集群： 集群内部客户端访问负载均衡类型Service时，访问请求默认是通过集群服务转发规则（iptables或IPVS）转发到后端的容器实例。
  当负载均衡类型Service配置elb.pass-through后，集群内部客户端访问Service地址时会先访问到ELB，再通过ELB的负载均衡能力先访问到节点，然后通过集群服务转发规则（iptables或IPVS）转发到后端的容器实例。
  
- 对于CCE Turbo集群： 集群内节点访问负载均衡类型Service时，访问请求默认是通过集群服务转发规则（iptables或IPVS）转发到后端的容器实例。
  集群内容器访问负载均衡类型Service时，默认使用pass-through方式，此时客户端会直接访问ELB私网地址，然后通过ELB直接连接容器实例。
  
 
#### 约束限制
- 在CCE Standard集群中，当使用独享型负载均衡配置pass-through后，从工作负载Pod所在节点或同节点的其他容器中访问ELB的私网IP地址，会出现无法访问的问题。
- v1.19及以上集群版本支持。
- IPVS网络模式下，对接同一个ELB的Service需保持pass-through设置情况一致。
- 使用节点级别（Local）的服务亲和的场景下，会自动设置kubernetes.io/elb.pass-through为onlyLocal，开启pass-through能力。
 
#### 操作步骤
本文以Nginx镜像创建无状态工作负载为例，创建一个具有pass-through的Service。
1. 使用kubectl命令行工具连接集群。详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
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](https://support.huaweicloud.com/usermanual-cce/cce_10_0014.html#section6)。
   
   创建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控制台](https://console.huaweicloud.com/vpc/#/elb/list/grid)，查看Service对应的ELB（本示例中名为james）。
2. 单击ELB名称，并切换至"监控"，可以看到ELB的连接数为0。 
   ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001990384161.png "点击放大")
   
   
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转发，与预期一致。
   
   
 
