kube-proxy 运行在每个节点上,监听 API Server 中服务对象的变化,再通过管理 IPtables 来实现网络的转发。
Kube-Proxy 不同的版本可支持三种工作模式:
UserSpace
k8s v1.2 后就已经淘汰
IPtables
目前默认方式
IPVS
需要安装ipvsadm、ipset 工具包和加载 ip_vs 内核模块
启动脚本:
[Unit] Description=Kubernetes Kube-Proxy Server Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=network.target [Service] # kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 # kube-proxy 会对访问 Service IP 的请求做 SNAT,这个特性与calico 实现 network policy冲突,因此禁用 WorkingDirectory=/var/lib/kube-proxy ExecStart=/usr/bin/kube-proxy \ --bind-address=172.16.99.124 \ --hostname-override=172.16.99.124 \ --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \ --logtostderr=true \ --proxy-mode=iptables Restart=on-failure RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target
iptables:
Kube-Proxy 监听 Kubernetes Master 增加和删除 Service 以及 Endpoint 的消息。对于每一个 Service,Kube
Proxy 创建相应的 IPtables 规则,并将发送到 Service Cluster IP 的流量转发到 Service 后端提供服务的 Pod 的相
应端口上。 注: 虽然可以通过 Service 的 Cluster IP 和服务端口访问到后端 Pod 提供的服务,但该 Cluster IP 是
Ping 不通的。 其原因是 Cluster IP 只是 IPtables 中的规则,并不对应到一个任何网络设备。 IPVS 模式的 Cluster
IP 是可以 Ping 通的。
IPVS:
kubernetes从1.9开始测试支持ipvs(Graduate kube-proxy IPVS mode to beta),https://github.com/kubernetes/
kubernetes/blob/master/CHANGELOG-1.9.md#ipvs,从1.11版本正式支持ipvs(IPVS-based in-cluster load
balancing is now GA),https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#ipvs。
IPVS 相对 IPtables 效率会更高一些,使用 IPVS 模式需要在运行 Kube-Proxy 的节点上安装 ipvsadm、ipset 工具
包和加载 ip_vs 内核模块,当 Kube-Proxy 以 IPVS 代理模式启动时,Kube-Proxy 将验证节点上是否安装了 IPVS 模
块,如果未安装,则 Kube-Proxy 将回退到 IPtables 代理模式。
使用IPVS模式,Kube-Proxy会监视Kubernetes Service对象和Endpoints,调用宿主机内核Netlink接口以
相应地创建IPVS规则并定期与Kubernetes Service对象 Endpoints对象同步IPVS规则,以确保IPVS状态与
期望一致,访问服务时,流量将被重定向到其中一个后端 Pod,IPVS使用哈希表作为底层数据结构并在内核空间
中工作,这意味着IPVS可以更快地重定向流量,并且在同步代理规则时具有更好的性能,此外,IPVS 为负载均
衡算法提供了更多选项,例如:rr (轮询调度)、lc (最小连接数)、dh (目标哈希)、sh (源哈希)、sed (最
短期望延迟)、nq(不排队调度)等。
实战修改kube-proxy
修改iptables为ipvs(要修改所有master和node节点)
root@k8s-n2:~# cat /etc/systemd/system/kube-proxy.service
[Unit] Description=Kubernetes Kube-Proxy Server Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=network.target [Service] # kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 # kube-proxy 会对访问 Service IP 的请求做 SNAT,这个特性与calico 实现 network policy冲突,因此禁用 WorkingDirectory=/var/lib/kube-proxy ExecStart=/usr/bin/kube-proxy \ --bind-address=172.16.99.124 \ --hostname-override=172.16.99.124 \ --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \ --logtostderr=true \ --proxy-mode=ipvs Restart=on-failure RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target
root@k8s-n2:~# systemctl daemon-reload
root@k8s-n2:~# systemctl restart kube-proxy
root@k8s-n2:~# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 127.0.0.1:30001 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 172.16.99.124:30001 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 172.16.100.24:30001 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 172.17.0.1:30001 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 172.31.111.192:30001 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 10.20.0.1:443 rr -> 172.16.99.121:6443 Masq 1 0 0 TCP 10.20.95.6:8086 rr -> 172.31.111.217:8086 Masq 1 0 0 TCP 10.20.138.198:80 rr -> 172.31.215.91:8082 Masq 1 0 0 TCP 10.20.161.23:443 rr -> 172.31.215.80:8443 Masq 1 0 0 TCP 10.20.222.142:80 rr -> 172.31.215.90:3000 Masq 1 0 0 TCP 10.20.254.254:53 rr -> 172.31.111.209:53 Masq 1 0 0 UDP 10.20.254.254:53 rr -> 172.31.111.209:53 Masq 1 0 0