Kubernetes Sevice工作模式由iptables改成ipvs

使用 IPVS 在大规模集群下有一定的性能优势,但是也是需要一定条件才能支持的,如果没有满足的话就会自动降级为使用iptables模式,当前环境就是一开始内核版本为3.10.0,系统为CentOS 7.6,内核升级为 4.1 版本才完全支持。

一、SVC 概述

1.1 代理模式概述

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟IP)的形式,而不是 ExternalName 的形式。

在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新了 iptables 代理,但并不是默认的运行模式。从 Kubernetes v1.2 起,默认就是iptables代理。在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理。在 Kubernetes 1.14 版本开始默认使用 ipvs 代理。

Kubernetes Sevice工作模式由iptables改成ipvs_第1张图片

1.2 IPVS 优势

为什么为 Kubernetes 选择 IPVS ?

随着 Kubernetes 的使用增长,其资源的可扩展性变得越来越重要。特别是,服务的可扩展性对于运行大型工作负载的开发人员/公司采用 Kubernetes 至关重要。

Kube-proxy 是服务路由的构建块,它依赖于经过强化攻击的 iptables 来实现支持核心的服务类型,如 ClusterIP 和 NodePort。 但是,iptables 难以扩展到成千上万的服务,因为它纯粹是为防火墙而设计的,并且基于内核规则列表。

尽管 Kubernetes 在版本v1.6中已经支持5000个节点,但使用 iptables 的 kube-proxy 实际上是将集群扩展到5000个节点的瓶颈。 一个例子是,在5000节点集群中使用 NodePort 服务,如果我们有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个 iptable 记录,这可能使内核非常繁忙。

另一方面,使用基于 IPVS 的集群内服务负载均衡可以为这种情况提供很多帮助。 IPVS 专门用于负载均衡,并使用更高效的数据结构(哈希表),允许几乎无限的规模扩张。

类型 用途介绍
rr 轮询调度
lc 最小连接数
dh 目标哈希
sh 源哈希
sed 最短期望延迟
nq 不排队调度

二、升级内核

如果已经内核版本已经大于4.1的可以忽略这一步骤,因为此内核版本可以完美的支持IPVS,以我当前内核版本为例,如果把Sevice模式由 iptables 改成 ipvs,可能会出现以下问题:

  • ipvs 指向的后端节点不对,如果重新 svc 删除重建又是对的
  • 当副本数量变动时,ipvs 不能立马感知到
  • 如果直接用域名访问  svc 时,会出现解析不了的情况
# 开始环境的系统信息
# uname -r 
3.10.0-1160.41.1.el7.x86_64
# cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
# 在 3.10 内核版本中改用ipvs,kube-proxy 会报如下错误

# kubectl -n kube-system logs kube-proxy-6pp2d
E0415 09:46:55.397466       1 proxier.go:1192] Failed to sync endpoint for service: 172.16.0.82:30080/TCP, err: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398639       1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398658       1 proxier.go:1533] Failed to sync endpoint for service: 10.10.1.35:30080/TCP, err: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
E0415 09:46:55.398751       1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[172 16 100 7 0 0 0 0 0 0 0 0 0 0 0 0]
...

2.1 内核包下载

1)  从阿里云上下载

Kubernetes Sevice工作模式由iptables改成ipvs_第2张图片 阿里云镜像仓库
Kubernetes Sevice工作模式由iptables改成ipvs_第3张图片 kernel-4.9

2.2  内核包安装

# 更新内核时,对系统的cpu的负载很高,因此建议一台一台更新

# yum install kernel-4.9.215-36.el7.x86_64.rpm -y
# init 6 

# uname -r
4.9.215-36.el7.x86_64

三、 更改模式

3.1 开启 ipvs

查看内核是否加载了 ipvs ,没有则加单独加载、安装。

# lsmod | grep -e ip_vs
ip_vs_sh               16384  0 
ip_vs_wrr              16384  0 
ip_vs_rr               16384  9 
ip_vs                 147456  15 ip_vs_wrr,ip_vs_rr,ip_vs_sh
nf_conntrack          106496  8 ip_vs,nf_conntrack_proto_sctp,nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_nat
libcrc32c              16384  2 ip_vs,xfs

# lsmod |grep nf_conntrack_ipv4
nf_conntrack_ipv4      16384  8 
nf_defrag_ipv4         16384  1 nf_conntrack_ipv4
nf_conntrack          106496  8 ip_vs,nf_conntrack_proto_sctp,nf_conntrack_ipv4,nf_conntrack_netlink,nf_nat_masquerade_ipv4,xt_conntrack,nf_nat_ipv4,nf_na

# cat > /etc/sysconfig/modules/ipvs.modules <

3.2 svc 模式修改

# kubectl edit configmap kube-proxy -n kube-system
...
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: "ipvs"                        # "" 改成 ipvs
    nodePortAddresses: null
    oomScoreAdj: null
...

configmap/kube-proxy edited

--
# 删除现有的 kube-proxy pod,相当于重启后才会变更成 ipvs
# kubectl get pods -n kube-system|grep kube-proxy
kube-proxy-6pp2d                          1/1     Running   1          8h
kube-proxy-mcfp6                          1/1     Running   1          8h
kube-proxy-qmdhp                          1/1     Running   1          8h

# kubectl delete pod/kube-proxy-6pp2d -n kube-system
pod "kube-proxy-6pp2d" deleted
# kubectl delete pod/kube-proxy-mcfp6-n kube-system
pod "kube-proxy-mcfp6" deleted
# kubectl delete pod/kube-proxy-qmdhp -n kube-system
pod "kube-proxy-qmdhp" deleted

3.3 查看验证

# kubectl -n kube-system logs kube-proxy-qmdhp|grep ipvs
I0415 10:48:49.984477       1 server_others.go:259] Using ipvs Proxier.

# 在 kube-proxy pod 看到如上信息后说明是启用ipvs的
# 测试使用的是 deployment 2个nginx, 一个 svc 指向 nginx pod

# 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:30080 rr
  -> 172.16.100.8:80              Masq    1      0          0         
  -> 172.16.100.197:80            Masq    1      0          0         
TCP  172.16.0.1:443 rr
  -> 10.10.1.35:6443              Masq    1      4          0         
TCP  172.16.0.10:53 rr
  -> 172.16.100.9:53              Masq    1      0          0         
  -> 172.16.100.10:53             Masq    1      0          0         
TCP  172.16.0.10:9153 rr
  -> 172.16.100.9:9153            Masq    1      0          0         
  -> 172.16.100.10:9153           Masq    1      0          0               
...

注意事项:ipvs 尚未稳定,请慎用;而且 --masquerade-all 选项与 Calico 安全策略控制不兼容,请酌情考虑使用(Calico 在做网络策略限制的时候要求不能开启此选项)

Reference:

https://blog.csdn.net/weixin_43936969/article/details/106175580
https://blog.csdn.net/qq_25854057/article/details/122469765
https://kubernetes.io/zh/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/

你可能感兴趣的:(Kubernetes,kubernetes,容器,Service)