代码之家  ›  专栏  ›  技术社区  ›  James Healy

GCP负载平衡器如何将流量路由到GKE服务?

  •  1
  • James Healy  · 技术社区  · 6 年前

    我对GCP还比较陌生(1年),我还在将各种服务映射到我现有的网络心理模型中。

    在测试集群上,我在提供HTTP的pods前面创建了一个服务:

    apiVersion: v1
    kind: Service
    metadata:
      name: contour
    spec:
     ports:
     - port: 80
       name: http
       protocol: TCP
       targetPort: 8080
     - port: 443
       name: https
       protocol: TCP
       targetPort: 8443
     selector:
       app: contour
     type: LoadBalancer
    

    $ kubectl get svc contour
    NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
    contour   LoadBalancer   10.63.241.69   35.x.y.z   80:30472/TCP,443:30816/TCP   41m
    

    GCP网络负载均衡器会自动为我创建。它在35.x.y.z有自己的公共IP,并且正在监听端口80-443:

    auto load balancer

    卷曲负载平衡器IP可以工作:

    $ curl -q -v 35.x.y.z
    * TCP_NODELAY set
    * Connected to 35.x.y.z (35.x.y.z) port 80 (#0)
    > GET / HTTP/1.1
    > Host: 35.x.y.z
    > User-Agent: curl/7.62.0
    > Accept: */*
    > 
    < HTTP/1.1 404 Not Found
    < date: Mon, 07 Jan 2019 05:33:44 GMT
    < server: envoy
    < content-length: 0
    <
    

    如果我进入GKE节点,我可以看到 kube-proxy 正在侦听服务节点端口(30472和30816),但没有任何东西具有侦听端口80或443的套接字:

    # netstat -lntp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 127.0.0.1:20256         0.0.0.0:*               LISTEN      1022/node-problem-d 
    tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      1221/kubelet        
    tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      1369/kube-proxy     
    tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      297/systemd-resolve 
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      330/sshd            
    tcp6       0      0 :::30816                :::*                    LISTEN      1369/kube-proxy     
    tcp6       0      0 :::4194                 :::*                    LISTEN      1221/kubelet        
    tcp6       0      0 :::30472                :::*                    LISTEN      1369/kube-proxy     
    tcp6       0      0 :::10250                :::*                    LISTEN      1221/kubelet        
    tcp6       0      0 :::5355                 :::*                    LISTEN      297/systemd-resolve 
    tcp6       0      0 :::10255                :::*                    LISTEN      1221/kubelet        
    tcp6       0      0 :::10256                :::*                    LISTEN      1369/kube-proxy
    

    两个问题:

    1. 如果节点上没有监听端口80或443,负载平衡器是否将通信量定向到端口30472和30816?
    2. 如果负载平衡器接受80/443上的通信量并转发到30472/30816,我在哪里可以看到该配置?在负载平衡器屏幕上单击,我看不到任何有关端口30472和30816的信息。
    2 回复  |  直到 6 年前
        1
  •  2
  •   James Healy    6 年前

    我想我找到了我自己问题的答案-有人能证实我走对了路吗?

    网络负载均衡器将流量重定向到群集中的一个节点,而不修改数据包-当端口80/443到达该节点时,它们仍然具有端口80/443。

    kube-proxy 编写了与数据包匹配的iptables规则

    您可以在节点上看到iptables配置:

    $ iptables-save | grep KUBE-SERVICES | grep loadbalancer                                                                                                            
    -A KUBE-SERVICES -d 35.x.y.z/32 -p tcp -m comment --comment "default/contour:http loadbalancer IP" -m tcp --dport 80 -j KUBE-FW-D53V3CDHSZT2BLQV                                                                 
    -A KUBE-SERVICES -d 35.x.y.z/32 -p tcp -m comment --comment "default/contour:https loadbalancer IP" -m tcp --dport 443 -j KUBE-FW-J3VGAQUVMYYL5VK6  
    
    $ iptables-save | grep KUBE-SEP-ZAA234GWNBHH7FD4
    :KUBE-SEP-ZAA234GWNBHH7FD4 - [0:0]
    -A KUBE-SEP-ZAA234GWNBHH7FD4 -s 10.60.0.30/32 -m comment --comment "default/contour:http" -j KUBE-MARK-MASQ
    -A KUBE-SEP-ZAA234GWNBHH7FD4 -p tcp -m comment --comment "default/contour:http" -m tcp -j DNAT --to-destination 10.60.0.30:8080
    
    $ iptables-save | grep KUBE-SEP-CXQOVJCC5AE7U6UC
    :KUBE-SEP-CXQOVJCC5AE7U6UC - [0:0]
    -A KUBE-SEP-CXQOVJCC5AE7U6UC -s 10.60.0.30/32 -m comment --comment "default/contour:https" -j KUBE-MARK-MASQ
    -A KUBE-SEP-CXQOVJCC5AE7U6UC -p tcp -m comment --comment "default/contour:https" -m tcp -j DNAT --to-destination 10.60.0.30:8443
    

    kube docs :

    Google计算引擎不需要分配NodePort来使LoadBalancer工作

    它还解释了为什么GKE创建一个自动防火墙规则,允许从0.0.0.0/0到节点上的端口80/443的流量。负载均衡器不会重写数据包,因此防火墙需要允许来自任何地方的流量到达节点上的iptables,并在那里重写。

        2
  •  1
  •   coderanger    6 年前

    要了解LoadBalancer服务,首先必须了解NodePort服务。这些工作的方式是在集群中的每个节点上都有一个代理(通常现在在iptables或ipvs中实现perf,但这是一个实现细节),当创建node port服务时,它会选择一个未使用的端口,并将这些代理中的每一个设置为将数据包转发到Kubernetes pod。LoadBalancer服务在此基础上构建,因此在GCP/GKE上创建一个GCLB转发规则,将请求的端口映射到所有这些节点级代理的旋转。所以GCLB监听端口80,它代理随机节点上的某个随机端口,代理pod上的内部端口。

    这个过程比那个更具可定制性,但这是基本的默认值。