apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test-goweb
name: test-goweb
spec:
replicas: 6
selector:
matchLabels:
app: test-goweb
template:
metadata:
labels:
app: test-goweb
spec:
containers:
- image: 192.168.11.247/web-demo/goweb-demo:20221229v3
imagePullPolicy: IfNotPresent
name: goweb-demo
ports:
- containerPort: 8090
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
labels:
app: test-goweb
name: test-goweb
spec:
ports:
- name: 80-8090
nodePort: 30010
port: 80
protocol: TCP
targetPort: 8090
selector:
app: test-goweb
type: NodePort
当在 Kubernetes 中创建 Service 时,将会创建以下几个 iptables 链。这些链都是用于实现 Service 的核心功能,下面列出所涉及到的链:
这些 iptables 链是 Kubernetes 中实现 Service 的关键组件。它们使得客户端可以使用 Service 名称来访问运行在 Pod 中的应用程序,而不必了解其具体 IP 地址。
查看和这个service有关的iptables规则
# iptables-save | grep test-goweb
-A KUBE-EXT-XRKWZPWLY5ZGEEBK -m comment --comment "masquerade traffic for default/test-goweb:80-8090 external destinations" -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp --dport 30010 -j KUBE-EXT-XRKWZPWLY5ZGEEBK
-A KUBE-SEP-2KC5TQ77EILRJT77 -s 10.244.240.51/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-2KC5TQ77EILRJT77 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.51:8090
-A KUBE-SEP-5AVQRPMC6RQQAAKG -s 10.244.240.9/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-5AVQRPMC6RQQAAKG -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.9:8090
-A KUBE-SEP-7QBH2WDQDSESRX53 -s 10.244.240.19/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-7QBH2WDQDSESRX53 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.19:8090
-A KUBE-SEP-KGPYN3PAVPO2A2G3 -s 10.244.240.20/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-KGPYN3PAVPO2A2G3 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.20:8090
-A KUBE-SEP-VXCKMNYZWUWZOOOJ -s 10.244.240.38/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-VXCKMNYZWUWZOOOJ -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.38:8090
-A KUBE-SEP-XH5PMCJ3CYSK4B7L -s 10.244.240.56/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
-A KUBE-SEP-XH5PMCJ3CYSK4B7L -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.56:8090
-A KUBE-SERVICES -d 10.104.238.165/32 -p tcp -m comment --comment "default/test-goweb:80-8090 cluster IP" -m tcp --dport 80 -j KUBE-SVC-XRKWZPWLY5ZGEEBK
-A KUBE-SVC-XRKWZPWLY5ZGEEBK ! -s 10.244.0.0/16 -d 10.104.238.165/32 -p tcp -m comment --comment "default/test-goweb:80-8090 cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.19:8090" -m statistic --mode random --probability 0.16666666651 -j KUBE-SEP-7QBH2WDQDSESRX53
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.20:8090" -m statistic --mode random --probability 0.20000000019 -j KUBE-SEP-KGPYN3PAVPO2A2G3
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.38:8090" -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-VXCKMNYZWUWZOOOJ
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.51:8090" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-2KC5TQ77EILRJT77
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.56:8090" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-XH5PMCJ3CYSK4B7L
-A KUBE-SVC-XRKWZPWLY5ZGEEBK -m comment --comment "default/test-goweb:80-8090 -> 10.244.240.9:8090" -j KUBE-SEP-5AVQRPMC6RQQAAKG
上面看到的这一堆规则,就是由 kube-proxy 组件自动创建和维护 iptables 规则,继续往下看,抽几条规则做个简单的分析。
-A KUBE-EXT-XRKWZPWLY5ZGEEBK -m comment --comment "masquerade traffic for default/test-goweb:80-8090 external destinations" -j KUBE-MARK-MASQ
这是上面第一条iptables规则,它用于Kubernetes集群中的网络转发和流量伪装。具体来说,这个规则将来自Kubernetes服务“default/test-goweb”的流量伪装为外部目标,以便它们可以通过集群外部访问。
规则中的参数解释如下:
请注意,KUBE-EXT-XRKWZPWLY5ZGEEBK、KUBE-MARK-MASQ是自定义的链名称,它在Kubernetes集群中的不同部分可能会有所不同。在实际使用时,链的名称可能会因不同的部署而有所变化,但规则的作用通常是相似的。
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp --dport 30010 -j KUBE-EXT-XRKWZPWLY5ZGEEBK
它的作用是将从 NodePort 类型的 Service 访问到的流量(目标端口为 30010/tcp)转发到名为 KUBE-EXT-XRKWZPWLY5ZGEEBK 的链上进行进一步处理。
-A KUBE-SEP-2KC5TQ77EILRJT77 -s 10.244.240.51/32 -m comment --comment "default/test-goweb:80-8090" -j KUBE-MARK-MASQ
它的作用是将来自 IP 地址为 10.244.240.51 的源地址流量进行 SNAT 转换,以便将源 IP 地址更改为 Node 的 IP 地址,从而使流量能够返回到客户端。该规则使用名为 KUBE-MARK-MASQ 的链进行转换。
-A KUBE-SEP-2KC5TQ77EILRJT77 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.51:8090
它的作用是将从集群内某个节点上的 Pod 访问 Service 的流量进行 DNAT 转换,以便将流量重定向到特定 Pod 的 IP 地址和端口上。
k8s的iptables规则是由k8s自身自动维护的,它使用 kube-proxy 组件来自动创建和维护 iptables 规则,当创建一个 Service 时,kube-proxy 会自动为该 Service 创建一组 iptables 规则,当 Pod 被添加或删除时,kube-proxy 会相应地更新这些规则。所以,不需要人为手动管理这些规则,简直是香到不行。
tantianran@test-b-k8s-master:~$ kubectl get svc test-goweb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test-goweb NodePort 10.104.238.165 <none> 80:30010/TCP 25h
在其中一台节点上看虚拟服务器信息
tantianran@test-b-k8s-node01:~$ sudo ipvsadm-save
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r test-b-k8s-master:6443 -m -w 1
-A -t test-b-k8s-node01:domain -s rr
-a -t test-b-k8s-node01:domain -r 10.244.82.19:domain -m -w 1
-a -t test-b-k8s-node01:domain -r 10.244.240.60:domain -m -w 1
-A -t test-b-k8s-node01:9153 -s rr
-a -t test-b-k8s-node01:9153 -r 10.244.82.19:9153 -m -w 1
-a -t test-b-k8s-node01:9153 -r 10.244.240.60:9153 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:8000 -s rr
-a -t test-b-k8s-node01:8000 -r 10.244.240.16:8000 -m -w 1
-A -t test-b-k8s-node01:http -s rr
-a -t test-b-k8s-node01:http -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:http -r 10.244.240.63:8090 -m -w 1
-A -t test-b-k8s-node01:https -s rr
-a -t test-b-k8s-node01:https -r 10.244.240.15:4443 -m -w 1
-A -t test-b-k8s-node01:30001 -s rr
-a -t test-b-k8s-node01:30001 -r 10.244.240.11:8443 -m -w 1
-A -t test-b-k8s-node01:30010 -s rr
-a -t test-b-k8s-node01:30010 -r 10.244.240.24:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.48:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.52:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.54:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.62:8090 -m -w 1
-a -t test-b-k8s-node01:30010 -r 10.244.240.63:8090 -m -w 1
-A -u test-b-k8s-node01:domain -s rr
-a -u test-b-k8s-node01:domain -r 10.244.82.19:domain -m -w 1
-a -u test-b-k8s-node01:domain -r 10.244.240.60:domain -m -w 1
要注意了,在上面的虚拟服务器信息中可以看到,有的是-a,有的是-A,这两个选项都可以用于向IPVS中添加一个新的服务(virtual server)。它们的区别不仅仅在于是大小写的区别,更大的区别在于添加服务的方式和语义上略有不同:
拿这条策略来看看
-a -t test-b-k8s-node01:http -r 10.244.240.24:8090 -m -w 1
以下是每个选项的含义:
总而言之它的作用是:它将添加一个名为test-b-k8s-node01的HTTP虚拟服务,并将客户端的请求源IP地址改为工作节点的IP地址,并将请求发送到后端服务器10.244.240.24:8090,其中只有一个后端服务器,它的服务能力是1。
k8s中的Service底层不管是iptables还是ipvs,它们的策略规则都是k8s自身自动维护的。具体来说,当创建一个Service时,Kubernetes会在底层为该Service创建一个虚拟IP(VIP),并自动配置iptables或者ipvs规则,使得这个VIP可以将流量转发到Service中的多个Pod实例。
当使用iptables时,Kubernetes会在每个节点上创建iptables规则,通过iptables NAT功能实现负载均衡和服务发现。而当使用ipvs时,Kubernetes会在每个节点上创建ipvs规则,并使用ipvs的负载均衡算法实现服务发现和流量转发。
无论是使用iptables还是ipvs,Kubernetes都会自动维护这些规则,保证Service的负载均衡和高可用性。当Service中的Pod实例发生变化时,Kubernetes会自动更新iptables或ipvs规则,以确保流量能够正确地转发到新的Pod实例上。Kubernetes通过自动化的方式,简化了Service的配置和维护。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。