在k8s中,提供相同服务的一组pod可以抽象成一个service,通过service提供的统一入口对外提供服务,每个service都有一个虚拟IP地址(clusterip)和端口号供客户端访问。

Kube-proxy存在于各个node节点上,主要用于Service功能的实现,具体来说,就是实现集群内的客户端pod访问service,或者是集群外的主机通过NodePort等方式访问service。

kube-proxy默认使用的是iptables模式,通过各个node节点上的iptables规则来实现service的负载均衡,但是随着service数量的增大,iptables模式由于线性查找匹配、全量更新等特点,其性能会显著下降。

从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。

下面我们先来学习一下IPVS的相关知识

IPVS是LVS的核心组件,是一种四层负载均衡器。IPVS具有以下特点:
与Iptables同样基于Netfilter,但使用的是hash表;
支持TCP, UDP,SCTP协议,支持IPV4,IPV6;
支持多种负载均衡策略:rr, wrr, lc, wlc, sh, dh, lblc…
支持会话保持;

LVS主要由两部分组成:
ipvs(ip virtual server):即ip虚拟服务,是工作在内核空间上的一段代码,主要是实现调度的代码,它是实现负载均衡的核心。
ipvsadm: 工作在用户空间,负责为ipvs内核框架编写规则,用于定义谁是集群服务,谁是后端真实服务器。我们可以通过ipvsadm指令创建集群服务

# ipvsadm -A -t 192.168.2.xx:80 -s rr //创建一个DR,并指定调度算法采用rr。
# ipvsadm -a -t 192.168.2.xx:80 -r 192.168.10.xx 
# ipvsadm -a -t 192.168.2.xx:80 -r 192.168.11.xx //添加两个RS

IPVS基于Netfilter, Netfilter 中制定了数据包的五个挂载点(Hook Point),这5个挂载点分别是PRE_ROUTING、INPUT、OUTPUT、FORWARD、POST_ROUTING,如下图所示,IPVS工作在其中的INPUT链上。

kube-proxy配置 ipvs模式

当客户端的请求到达负载均衡器的内核空间时,首先会到达PREROUTING链。
当内核发现请求数据包的目的地址是本机时,将数据包送往INPUT链。
当数据包到达INPUT链时,首先会被IPVS检查,如果数据包里面的目的地址及端口没有在IPVS规则里面,那么这条数据包将被放行至用户空间。
如果数据包里面的目的地址及端口在IPVS规则里面,那么这条数据报文的目的地址被修改为通过负载均衡调度算法选好的后端服务器(DNAT),并送往POSTROUTING链。
最后经由POSTROUTING链发往后端服务器。

下面我们来配置kube-proxy模式为IPVS

一、开启node节点的内核参数

# grep -v '^#' /etc/sysctl.conf    
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# sysctl -p

二、安装ipvs相关软件包

# yum -y install ipvsadm ipset

三、修改kube-proxy启动脚本

# cat /usr/lib/systemd/system/kube-proxy.service   
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/sbin/kube-proxy \
  --bind-address=192.168.1.23 \
  --hostname-override=server23 \
  --cluster-cidr=172.35.0.0/16 \
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
  --masquerade-all \
  --feature-gates=SupportIPVSProxyMode=true \
  --proxy-mode=ipvs \
  --ipvs-min-sync-period=5s \
  --ipvs-sync-period=5s \
  --ipvs-scheduler=rr \
  --logtostderr=true \
  --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

四、重启服务与验证

# systemctl daemon-reload
# systemctl restart kube-proxy

kube-proxy配置 ipvs模式
kube-proxy配置 ipvs模式