kube-proxy的ipvs模式解读

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: IPVS 这篇文章主要讲述: 什么是IPVS? IPVS 和 IPTABLES 区别 如何设置kube-proxy按照ipvs模式运行和故障排查 什么是IPVS IPVS(IP虚拟服务器)实现传输层负载平衡,通常称为第4层LAN交换,是Linux内核的一部分。

IPVS

这篇文章主要讲述:

  • 什么是IPVS?
  • IPVS 和 IPTABLES 区别
  • 如何设置kube-proxy按照ipvs模式运 行和故障排查

什么是IPVS

IPVS(IP虚拟服务器)实现传输层负载平衡,通常称为第4层LAN交换,是Linux内核的一部分。

IPVS在主机上运行,​​在真实服务器集群前充当负载均衡器。 IPVS可以将对基于TCP和UDP的服务的请求定向到真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。

IPVS vs. IPTABLES

IPVS模式在Kubernetes v1.8中引入,并在v1.9中进入了beta。 IPTABLES模式在v1.1中添加,并成为自v1.2以来的默认操作模式。 IPVS和IPTABLES都基于netfilter。 IPVS模式和IPTABLES模式之间的差异如下:

  • IPVS为大型集群提供了更好的可扩展性和性能。
  • IPVS支持比iptables更复杂的负载平衡算法(最小负载,最少连接,位置,加权等)。
  • IPVS支持服务器健康检查和连接重试等。

什么时候ipvs会降级到iptables

IPVS proxier将使用iptables,在数据包过滤,SNAT和支持NodePort类型的服务这几个场景中。具体来说,ipvs proxier将在以下4个场景中回归iptables。

kube-proxy 启动项设置了 –masquerade-all=true

如果kube-proxy以--masquerade-all = true开头,则ipvs proxier将伪装访问服务群集IP的所有流量,其行为与iptables proxier相同。假设有一个群集IP 10.244.5.1和端口8080的服务,那么ipvs proxier安装的iptables应该如下所示。

# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain POSTROUTING (policy ACCEPT) target prot opt source destination  KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */ Chain KUBE-POSTROUTING (1 references) target prot opt source destination  MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000 Chain KUBE-MARK-DROP (0 references) target prot opt source destination  MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references) target prot opt source destination  MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references) target prot opt source destination  KUBE-MARK-MASQ tcp -- 0.0.0.0/0 10.244.5.1 /* default/foo:http cluster IP */ tcp dpt:8080 
在kube-proxy启动中指定集群CIDR

如果kube-proxy以--cluster-cidr = <cidr>开头,则ipvs proxier将伪装访问服务群集IP的群集外流量,其行为与iptables proxier相同。假设kube-proxy随集群cidr 10.244.16.0/24提供,服务集群IP为10.244.5.1,端口为8080,则ipvs proxier安装的iptables应如下所示。

# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain POSTROUTING (policy ACCEPT) target prot opt source destination  KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */ Chain KUBE-POSTROUTING (1 references) target prot opt source destination  MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000 Chain KUBE-MARK-DROP (0 references) target prot opt source destination  MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references) target prot opt source destination  MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references) target prot opt source destination  KUBE-MARK-MASQ tcp -- !10.244.16.0/24 10.244.5.1 /* default/foo:http cluster IP */ tcp dpt:8080
为LB类型服务指定Load Balancer Source Ranges

当服务的LoadBalancerStatus.ingress.IP不为空并且指定了服务的LoadBalancerSourceRanges时,ipvs proxier将安装iptables,如下所示。
假设服务的LoadBalancerStatus.ingress.IP为10.96.1.2,服务的LoadBalancerSourceRanges为10.120.2.0/24。

# iptables -t nat -nL

Chain PREROUTING (policy ACCEPT)
target prot opt source destination 
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */

Chain OUTPUT (policy ACCEPT)
target prot opt source destination 
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination 
KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */

Chain KUBE-POSTROUTING (1 references)
target prot opt source destination 
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000

Chain KUBE-MARK-DROP (0 references)
target prot opt source destination 
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000 Chain KUBE-MARK-MASQ (6 references)
target prot opt source destination 
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000 Chain KUBE-SERVICES (2 references)
target prot opt source destination 
ACCEPT tcp -- 10.120.2.0/24 10.96.1.2 /* default/foo:http loadbalancer IP */ tcp dpt:8080 DROP tcp -- 0.0.0.0/0 10.96.1.2 /* default/foo:http loadbalancer IP */ tcp dpt:8080
支持 NodePort type service

为了支持NodePort类型的服务,ipvs将在iptables proxier中继续现有的实现。例如,

# kubectl describe svc nginx-service Name: nginx-service ... Type: NodePort IP: 10.101.28.148 Port: http 3080/TCP NodePort: http 31604/TCP Endpoints: 172.17.0.2:80 Session Affinity: None 
# iptables -t nat -nL [root@100-106-179-225 ~]# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain OUTPUT (policy ACCEPT) target prot opt source destination  KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ Chain KUBE-SERVICES (2 references) target prot opt source destination  KUBE-MARK-MASQ tcp -- !172.16.0.0/16 10.101.28.148 /* default/nginx-service:http cluster IP */ tcp dpt:3080 KUBE-SVC-6IM33IEVEEV7U3GP tcp -- 0.0.0.0/0 10.101.28.148 /* default/nginx-service:http cluster IP */ tcp dpt:3080 KUBE-NODEPORTS all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL Chain KUBE-NODEPORTS (1 references) target prot opt source destination  KUBE-MARK-MASQ tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp dpt:31604 KUBE-SVC-6IM33IEVEEV7U3GP tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp dpt:31604 Chain KUBE-SVC-6IM33IEVEEV7U3GP (2 references) target prot opt source destination KUBE-SEP-Q3UCPZ54E6Q2R4UT all -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ Chain KUBE-SEP-Q3UCPZ54E6Q2R4UT (1 references) target prot opt source destination  KUBE-MARK-MASQ all -- 172.17.0.2 0.0.0.0/0 /* default/nginx-service:http */ DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/nginx-service:http */ tcp to:172.17.0.2:80

以 ipvs 模式 运行kube-proxy

前提条件

确保IPVS需要内核模块

ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4
  • 检查上诉已编译到节点内核中。使用
grep -e ipvs -e nf_conntrack_ipv4 /lib/modules/$(uname -r)/modules.builtin

如果编译成内核,则得到如下结果。

kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
kernel/net/netfilter/ipvs/ip_vs.ko
kernel/net/netfilter/ipvs/ip_vs_rr.ko
kernel/net/netfilter/ipvs/ip_vs_wrr.ko
kernel/net/netfilter/ipvs/ip_vs_lc.ko
kernel/net/netfilter/ipvs/ip_vs_wlc.ko
kernel/net/netfilter/ipvs/ip_vs_fo.ko
kernel/net/netfilter/ipvs/ip_vs_ovf.ko
kernel/net/netfilter/ipvs/ip_vs_lblc.ko
kernel/net/netfilter/ipvs/ip_vs_lblcr.ko
kernel/net/netfilter/ipvs/ip_vs_dh.ko
kernel/net/netfilter/ipvs/ip_vs_sh.ko
kernel/net/netfilter/ipvs/ip_vs_sed.ko
kernel/net/netfilter/ipvs/ip_vs_nq.ko
kernel/net/netfilter/ipvs/ip_vs_ftp.ko
  • 是否被加载
# load module <module_name> modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 # to check loaded modules, use lsmod | grep -e ipvs -e nf_conntrack_ipv4
# or cut -f1 -d " " /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4

在使用IPVS模式之前,还应在节点上安装ipset等软件包。

如果不满足这些要求,Kube-proxy将回退到IPTABLES模式。

kubeadm 安装的集群

默认情况下,Kube-proxy将在kubeadm部署的集群中以iptables模式运行。

如果您将kubeadm与配置文件一起使用,则可以在kubeProxy字段下指定ipvs模式,添加SupportIPVSProxyMode:true。

kind: MasterConfiguration apiVersion: kubeadm.k8s.io/v1alpha1 ... kubeProxy: config: featureGates: SupportIPVSProxyMode=true mode: ipvs ...

如果您使用的是Kubernetes v1.8,您还可以在kubeadm init命令中添加标志--feature-gates = SupportIPVSProxyMode = true(自v1.9起不推荐使用)

kubeadm init --feature-gates=SupportIPVSProxyMode=true

PS

如果成功启用了ipvs模式,你应该看到ipvs代理规则(使用ipvsadm)例如:

# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
 -> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.1:443 rr persistent 10800
 -> 192.168.0.1:6443 Masq 1 1 0

当本地群集运行时,kube-proxy日志中会出现类似的日志(例如,本地群集的/tmp/kube-proxy.log):

Using ipvs Proxier.

然而没有ipvs代理规则或有以下日志则表明kube-proxy无法使用ipvs模式:

Can't use ipvs proxier, trying iptables proxier
Using iptables Proxier.

调试和排查

检查ipvs 代理规则

用户可以使用ipvsadm工具检查kube-proxy是否正确维护IPVS规则。例如,我们在集群中有以下服务:

# kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1d
kube-system kube-dns ClusterIP  10.0.0.10 <none>  53/UDP,53/TCP 1d

我们应该能看到如下的规则:

 # ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
 -> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.1:443 rr persistent 10800
 -> 192.168.0.1:6443 Masq 1 1 0
TCP 10.0.0.10:53 rr
 -> 172.17.0.2:53 Masq 1 0 0
UDP 10.0.0.10:53 rr
 -> 172.17.0.2:53 Masq 1 0 0 

为什么kube-proxy不能以ipvs模式启动

  • Enable IPVS feature gateway

对于Kubernetes v1.10及更高版本,功能门SupportIPVSProxyMode默认设置为true。但是,您需要在v1.10之前为Kubernetes明确启用--feature-gates = SupportIPVSProxyMode = true。

  • 指定proxy-mode=ipvs

检查kube-proxy模式是否已设置为ipvs

  • 安装所需的内核模块和包

检查是否已将ipvs所需的内核模块编译到内核和软件包中。

本文转自SegmentFault-kube-proxy的ipvs模式解读

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
Kubernetes 容器 Perl
使用kube-proxy让外部网络访问K8S service的ClusterIP
配置方式 kubernetes版本大于或者等于1.2时,外部网络(即非K8S集群内的网络)访问cluster IP的办法是: 修改master的/etc/kubernetes/proxy,把KUBE_PROXY_ARGS=”“改为KUBE_PROXY_ARGS=”–proxy-mode=userspace” 重启kube-proxy服务 在核心路由设备或者源主机上添加一条路由,访问cluster IP段的路由指向到master上。
4495 0
|
4月前
|
存储 Kubernetes 负载均衡
在K8S中,Kube-Proxy为什么使用ipvs,而不使用iptables?
在K8S中,Kube-Proxy为什么使用ipvs,而不使用iptables?
|
4月前
|
Kubernetes 负载均衡 API
在K8S中,Kube-proxy有什么功能?
在K8S中,Kube-proxy有什么功能?
|
4月前
|
Kubernetes 负载均衡 API
在K8S中,kube-proxy ipvs 原理是什么?
在K8S中,kube-proxy ipvs 原理是什么?
|
4月前
|
Kubernetes 负载均衡 监控
在K8S中,kube-proxy的工作模式是什么?
在K8S中,kube-proxy的工作模式是什么?
|
4月前
|
存储 Kubernetes 负载均衡
在K8S中,kube-proxy ipvs 和 iptables 有何异同?
在K8S中,kube-proxy ipvs 和 iptables 有何异同?
|
4月前
|
Kubernetes 负载均衡 监控
在K8S中,kube-proxy 作用是什么?
在K8S中,kube-proxy 作用是什么?
|
负载均衡 Kubernetes 网络协议
kubernetes--kube-proxy组件深入理解
每台机器上都运行一个kube-proxy服务’它监听API server中service和endpoint的变化情 况,并通过iptables等来为服务配置负载均衡(仅支持TCP和UDP)
433 0
|
Kubernetes 容器 Perl
kubeadm安装集群的时候kube-proxy是如何安装的
最近升级k8s集群时遇到这个问题,集群是使用kuberadm自动化脚本安装的,之前一直认为kubeadm安装的集群这些组件除了kubelet都是静态pod跑起来的。其实kube-proxy并不是.
330 0
|
Kubernetes 负载均衡 网络协议
Kubernetes 【网络组件】kube-proxy使用详解
Kubernetes 【网络组件】kube-proxy使用详解
Kubernetes 【网络组件】kube-proxy使用详解