我对GCP相对较新(不到1年),并且仍在将各种服务映射到我现有的网络思维模型上的过程。
一旦我正在努力填补知识空白,便是如何将HTTP请求负载平衡到GKE集群中运行的服务。
在测试群集上,我在提供HTTP服务的Pod前面创建了一个服务:
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
该服务正在侦听节点端口30472和30816。
$ 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:
对负载均衡器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
在服务nodePorts(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
两个问题:
答案 0 :(得分:2)
我认为我找到了自己的问题的答案-有人可以确认我在正确的轨道上吗?
网络负载平衡器将流量重定向到群集中的节点,而无需修改数据包-端口80/443的数据包到达节点时仍具有端口80/443。
在节点上的端口80/443上没有监听任何内容。但是kube-proxy
编写了iptables规则,这些规则将数据包匹配到与负载均衡器IP匹配,并使用适当的ClusterIP和端口重写它们:
您可以在节点上看到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
一个有趣的含义是创建了nodePort,但似乎并未使用它。与kube docs中的此注释匹配:
Google Compute Engine无需分配NodePort即可使LoadBalancer正常工作
这也解释了为什么GKE创建一个自动防火墙规则,该规则允许从0.0.0.0/0到节点上端口80/443的流量。负载均衡器不会重写数据包,因此防火墙需要允许来自任何位置的流量到达节点上的iptables,然后将其重写。
答案 1 :(得分:1)
要了解LoadBalancer服务,您首先必须使用NodePort服务。这些工作的方式是在群集中的每个节点上都有一个代理(通常实际上已经针对perf在iptables或ipvs中实现,但是这是实现细节),并且在创建NodePort服务时,它会选择一个未使用的端口并设置每个这些代理之一可将数据包转发到您的Kubernetes Pod。 LoadBalancer服务建立在此之上,因此在GCP / GKE上,它会创建GCLB转发规则,将请求的端口映射到所有这些节点级代理的轮换。因此,GCLB监听端口80,该端口代理一个随机节点上的某个随机端口,该端口代理您的Pod上的内部端口。
该过程比该过程更具可定制性,但这是基本的默认设置。