共计 6421 个字符,预计需要花费 17 分钟才能阅读完成。
Service 的底层
Kubernetes Service 的底层实现能够应用两种网络模式:iptables 和 ipvs。
在 Kubernetes 中,Service 是一个形象的逻辑概念,用于公开应用程序的网络服务。它将一组 Pod 封装在一个虚构 IP 地址前面,能够通过该 IP 地址和相应的端口号拜访这些 Pod。而底层实现 Service 的网络模式,能够通过 kube-proxy 来进行设置。
Kubernetes 晚期版本中,kube-proxy 默认应用 iptables 实现 Service,即通过 iptables 规定来实现申请的转发和负载平衡。而在 Kubernetes 1.11 版本之后,新增了对 IPVS 的反对。IPVS 是一种高性能的、基于内核的负载均衡器,能够提供更高的性能和更丰盛的负载平衡算法。
相比之下,iptables 在规定较多时可能会影响性能,而 IPVS 的性能更高,且能够反对多种负载平衡算法,例如 RR、LC、WRR 等。因而,在高并发、高负载的场景下,应用 IPVS 作为 Service 的底层实现是更为适合的抉择。
优缺点
Kubernetes Service 底层应用 iptables 和 ipvs 作为负载平衡的实现形式,其实两者都是各有优缺点的,上面好好聊聊:
应用 iptables 作为负载均衡器的长处如下:
- 简略易用:iptables 是 Linux 中默认的防火墙软件,应用宽泛,熟练掌握 iptables 的管理员能够很容易地配置 Service 的负载平衡。
- 稳定性高:iptables 在 Linux 中曾经通过多年的应用和优化,稳定性失去了很好的保障,能够满足大部分场景下的负载平衡需要。
- 配置灵便:iptables 提供了非常灵活的配置形式,能够依据不同的业务场景和需要进行定制化配置,能够轻松地实现多种转发策略。
然而,应用 iptables 作为负载均衡器也存在一些毛病:
- 性能不够优良:iptables 的性能绝对较差,当集群规模增大时,会带来肯定的性能压力。
- 负载平衡粒度较粗:iptables 的负载平衡粒度较粗,只能对 IP 地址进行负载平衡,无奈对申请的 Header 信息等进行辨认,对于某些须要更精密的负载平衡场景可能无奈满足需要。
应用 ipvs 作为负载均衡器的长处如下:
- 性能优良:ipvs 的性能十分优良,能够反对高并发和大规模的负载平衡。
- 负载平衡粒度细:ipvs 的负载平衡粒度比 iptables 更细,能够对申请的 Header 信息等进行辨认,能够满足更精密的负载平衡场景。
然而,应用 ipvs 作为负载均衡器也存在一些毛病:
- 配置绝对简单:ipvs 的配置比 iptables 更加简单,须要较高的技术水平和教训。
- 稳定性绝对较低:ipvs 的稳定性绝对较低,须要管理员常常进行监控和保护。
应用 iptables 和 ipvs 作为 Kubernetes Service 的负载均衡器都有其长处和毛病,具体应用哪种形式须要依据理论场景和需要进行衡量。
kube-proxy
kube-proxy 是一个网络代理,它监督 Kubernetes Service 的变动,而后自动更新本地的网络规定,以实现负载平衡和流量转发性能。
当 Kubernetes 中创立了一个 Service 对象时,kube-proxy 会依据 Service 的定义生成相应的虚构 IP 地址,并为该 IP 地址配置负载平衡规定,以将流量转发到后端 Pod 上。
除了负载平衡和流量转发的性能之外,kube-proxy 还负责保护 Kubernetes 集群中的网络拓扑构造,并为 Pod 调配 IP 地址。因而,kube-proxy 是 Kubernetes 集群中十分重要的组件之一,它确保了网络流量的顺畅和应用程序的可用性。
Kube-proxy 默认应用 iptables 作为 Service 的实现形式,上面能够看到 kube-proxy 的启动 Log:
tantianran@test-b-k8s-master:~$ kubectl logs kube-proxy-6bdwl -n kube-system
...
I0320 00:43:35.602674 1 server_others.go:206] "Using iptables Proxier" # 这条 log 通知你 应用的是 iptables 的代理模式
...
批改成 ipvs 模式
kube-proxy 反对两种负载平衡模式,默认是 iptables 模式,应用的模式能够在 kube-proxy 配置中进行指定,上面批改成 IPVS:
- 每个节点装置 ipvs 相干依赖
sudo apt-get install -y ipset ipvsadm linux-modules-extra-$(uname -r) # Ubuntu
yum install -y ipset ipvsadm kernel-modules-extra # CentOS
# 确认 IPVS 模块已加载,如果输入后果中蕴含 ip_vs 和 nf_conntrack_ipv4,则示意 IPVS 模块已加载。lsmod | grep -e ip_vs -e nf_conntrack_ipv4
确保在每个节点上都装置了这些软件包,并且它们的版本雷同,这样能力确保集群中的所有节点都具备 IPVS 的反对。
- 批改配置文件
如果 k8s 应用的是 kubeadm 搭建的。那么 kube-proxy 它的配置文件是默认交由 ConfigMap 进行治理的。在 Kubernetes 中,ConfigMap 是一种用于管理应用程序配置的对象,它将配置信息存储为键值对的模式,能够被挂载到容器中,或者通过环境变量的模式注入到容器中。
kube-proxy 应用的配置文件是通过一个名为 kube-proxy 的 ConfigMap 来治理的,这个 ConfigMap 的名称和命名空间默认为 kube-system。能够应用以下命令查看 kube-proxy 的 ConfigMap:
kubectl get configmap -n kube-system kube-proxy -o yaml
在编辑器中批改 config.conf.mode 的值为 ”ipvs”,如果不指定 mode,默认的模式就是 iptables
kubectl edit configmap kube-proxy -n kube-system
内容如下:
mode: "ipvs"
批改后,保留并退出即可,批改后的配置信息会被自动更新到 kube-proxy 的配置文件中,查看一下:
kubectl get configmap -n kube-system kube-proxy -o yaml | grep mode
- 接着删掉 kube-proxy 的 pod,删完后它会马上主动重建,重建后即能加载配置从而使 ipvs 失效:
kubectl get pod -n kube-system | grep kube-proxy | awk '{print $1}' | xargs kubectl delete pod -n kube-system
pod "kube-proxy-dh5rv" deleted
pod "kube-proxy-nt8qz" deleted
pod "kube-proxy-pkspb" deleted
- 创立一个 NodePort 类型的 Service:
tantianran@test-b-k8s-master:/etc/kubernetes$ kubectl create svc nodeport test-goweb --tcp=80:8090 --node-port=30010
service/test-goweb created
tantianran@test-b-k8s-master:/etc/kubernetes$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 114d
test-goweb NodePort 10.104.238.165 <none> 80:30010/TCP 8s
tantianran@test-b-k8s-master:/etc/kubernetes$
- 查看以后正在运行的虚构服务和实在服务器的信息:
tantianran@test-b-k8s-master:/etc/kubernetes$ sudo ipvsadm -Ln | grep 30010
TCP 172.17.0.1:30010 rr
TCP 192.168.11.13:30010 rr
TCP 10.244.82.0:30010 rr
tantianran@test-b-k8s-master:/etc/kubernetes$ sudo ipvsadm -Ln | grep 8090
-> 10.244.240.3:8090 Masq 1 0 0
-> 10.244.240.14:8090 Masq 1 0 0
-> 10.244.240.23:8090 Masq 1 0 0
-> 10.244.240.34:8090 Masq 1 0 0
-> 10.244.240.45:8090 Masq 1 0 0
-> 10.244.240.46:8090 Masq 1 0 0
-> 10.244.240.3:8090 Masq 1 0 0
-> 10.244.240.14:8090 Masq 1 0 0
-> 10.244.240.23:8090 Masq 1 0 0
-> 10.244.240.34:8090 Masq 1 0 0
-> 10.244.240.45:8090 Masq 1 0 0
-> 10.244.240.46:8090 Masq 1 0 0
-> 10.244.240.3:8090 Masq 1 0 0
-> 10.244.240.14:8090 Masq 1 0 0
-> 10.244.240.23:8090 Masq 1 0 0
-> 10.244.240.34:8090 Masq 1 0 0
-> 10.244.240.45:8090 Masq 1 0 0
-> 10.244.240.46:8090 Masq 1 0 0
-> 10.244.240.3:8090 Masq 1 0 0
-> 10.244.240.14:8090 Masq 1 0 0
-> 10.244.240.23:8090 Masq 1 0 0
-> 10.244.240.34:8090 Masq 1 0 0
-> 10.244.240.45:8090 Masq 1 0 0
-> 10.244.240.46:8090 Masq 1 0 0
tantianran@test-b-k8s-master:/etc/kubernetes$
- 看看是否失常拜访:
- 如果要改回应用 iptables 的代理模式,只需批改 kube-proxy 配置中的 mode 为空字符串,它就会默认应用 iptables
内容如下:
mode: ""
最初的总结
Kubernetes 中的 Service 是一个形象层,用于将一组 Pod 公开为单个网络端点。在理论部署中,Kubernetes 提供了两种不同的 Service 类型:ClusterIP 和 NodePort。这两种 Service 类型的实现形式不同,波及到两种不同的网络代理技术:iptables 和 IPVS。
- iptables
iptables 是一个基于 Linux 内核的网络数据包过滤工具,用于管制网络数据包的转发。在 Kubernetes 中,当创立一个 ClusterIP Service 时,kube-proxy 组件会主动为该 Service 创立一组 iptables 规定。这些规定将来自 Service IP 地址和端口的数据包转发到后端 Pod 的 IP 地址和端口。
iptables 规定的实现形式比较简单,然而当后端 Pod 数量较多时,iptables 规定数量也会随之减少,这可能会对 iptables 性能产生肯定的影响。此外,当 Pod 数量发生变化时,iptables 规定也须要实时更新,这也可能会导致肯定的提早。
- IPVS
IPVS 是一个高性能的网络代理工具,用于将来自客户端的申请转发到后端的服务。在 Kubernetes 中,能够应用 IPVS 来代替 iptables 作为 Service 的后端负载均衡器。
与 iptables 不同,IPVS 是基于内核模块的模式实现的。在 Kubernetes 中,kube-proxy 组件会主动加载 IPVS 内核模块,并应用 IPVS 来实现 Service 的后端负载平衡。IPVS 的劣势在于它能够高效地解决大规模的负载平衡,因而在大规模集群中应用 IPVS 能够进步集群的性能和稳定性。
须要留神的是,IPVS 的配置绝对于 iptables 来说要简单一些,须要额定的工具来治理。同时,IPVS 须要更多的内存和 CPU 资源,因而在应用 IPVS 时须要思考到集群的资源限度。
好了,本篇的分享就到这里。下一篇的话呢,我会持续在 k8s 中创立一个 deployment 和 service,并剖析 service 底层的 iptables 和 ipvs 的每一条策略是怎么的。辛苦大家放弃高度关注,感激!
本文转载于 WX 公众号不背锅运维:https://mp.weixin.qq.com/s/gqet-QabvxqnWhdxAOO6Cg