创立用于测试的Deployment和Service
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
Service底层有哪些iptables链
当在 Kubernetes 中创立 Service 时,将会创立以下几个 iptables 链。这些链都是用于实现 Service 的外围性能,上面列出所波及到的链:
- PREROUTING 链:此链是由 kube-proxy 组件创立的,用于将 Service IP 地址映射到对应的 Pod IP 地址上。当申请进入节点时,该链将被触发,它依据申请的 Service IP 地址来查找对应的 Pod IP 地址,并将申请转发到该 Pod。
- KUBE-SERVICES 链:此链蕴含了一系列规定,用于将 Service IP 地址映射到对应的 Pod IP 地址上。当申请进入节点时,该链将被触发,并依据申请的 Service IP 地址来查找对应的 Pod IP 地址。如果找到了对应的 Pod IP 地址,申请将被转发到该 Pod。
- KUBE-SVC-XXX 链:此链蕴含了一系列规定,其中 XXX 代表 Service 的名称。每个 Service 都有一个对应的 KUBE-SVC-XXX 链。当申请进入节点时,该链将被触发,并依据 Service IP 地址查找对应的 KUBE-SVC-XXX 链。该链中的规定将申请转发到对应的 Pod。
- KUBE-SEP-XXX 链:此链蕴含了一系列规定,其中 XXX 代表 Service 的名称。每个 Service 都有一个对应的 KUBE-SEP-XXX 链。当申请进入节点时,该链将被触发,并依据 Service IP 地址查找对应的 KUBE-SEP-XXX 链。该链中的规定将申请转发到对应的 Pod。
- KUBE-FIREWALL 链:此链用于解决来自 Kubernetes 的外部流量。该链蕴含了一些规定,用于管制拜访 Kubernetes 的 API、DNS 和其余一些服务。
- KUBE-NODEPORT 链:当 Service 类型为 NodePort 时,此链将被创立。该链蕴含了一些规定,用于将节点的端口映射到 Service 的端口上。
- KUBE-MARK-DROP 链:当申请被回绝时,会触发此链。该链蕴含了一些规定,用于标记被回绝的数据包。
这些 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 规定,持续往下看,抽几条规定做个简略的剖析。
简略剖析
- 先看整体看看这1条规定
-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”的流量假装为内部指标,以便它们能够通过集群内部拜访。
规定中的参数解释如下:
- -A:将规定增加到链的开端
- KUBE-EXT-XRKWZPWLY5ZGEEBK:链的名称
- -m comment –comment “masquerade traffic for default/test-goweb:80-8090 external destinations”:增加一条正文,阐明此规定是用于假装“default/test-goweb”的流量,并指定了流量端口范畴和指标类型
- -j KUBE-MARK-MASQ:将流量标记为须要进行假装的流量,以便其可能来到集群并在指标处正确路由
请留神,KUBE-EXT-XRKWZPWLY5ZGEEBK、KUBE-MARK-MASQ是自定义的链名称,它在Kubernetes集群中的不同局部可能会有所不同。在理论应用时,链的名称可能会因不同的部署而有所变动,但规定的作用通常是类似的。
- 大略看看第2条
-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 的链上进行进一步解决。
- 大略看看第3条
-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 的链进行转换。
- 再看看第4条
-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 会相应地更新这些规定。所以,不须要人为手动治理这些规定,几乎是香到不行。
将Service底层的代理模式改为IPVS后
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选项将增加一个新的服务,并将其附加到一个现有的调度器上。如果调度器不存在,则会创立一个新的调度器。
- -A选项将增加一个新的服务,并将其附加到一个现有的调度器上。如果调度器不存在,则不会创立新的调度器。如果调度器曾经存在,则服务将被增加到现有的调度器中。
拿这条策略来看看
-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.24:8090: 后端实在服务器的IP地址和端口号,也就是POD的。
- -m: 应用IPVS的NAT模式。
- -w 1: 将权重设置为1,行将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的配置和保护。
本文转载于WX公众号:不背锅运维(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/3LGRf9NMs9qkMlGvTqVAcA
发表回复