前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kube-proxy详解

kube-proxy详解

作者头像
SY小站
发布2020-06-15 15:26:41
2K0
发布2020-06-15 15:26:41
举报
文章被收录于专栏:SY小站的专栏SY小站的专栏

1. 前言

kube-proxy 的转发模式可以通过启动参数–proxy-mode进行设置,有userspace、iptables、IPVS等可选项。

usersapce这里就不做赘述了, 由于转发是在用户态。所以效率不高,且容易丢包。所以被废弃了。

2. iptables模式

代码语言:javascript
复制
在这种模式下缺点就是在大规模的集群中,iptables添加规则会有很大的延迟。因为使用iptables,每增加一个svc都会增加一条iptables的chain。并且iptables修改了规则后必须得全部刷新才可以生效。

iptables是用户态应用程序,通过配置NetFilter规则表构建Linux内核防火墙。

iptables模式与userspace模式最大的区别在于,kube-proxy 利用iptables的DNAT模块,实现了Service 入口到Pod实际地址的转换,免去了一次内核态到用户态的切换。

2.1 例子

以下面Service为例,分析kube-proxy创建的iptables规则。

代码语言:javascript
复制
apiVersion: v1
kind: Service
meadata:
  labels:
    name: tomcat
  name: tomcat
space:
  ports:
    - port: 6080
      targetPort: 6080
      nodePort: 30005
  type: NodePort
  selector:
    app: tomcat

如上所示,在本例中我们创建了一个NodePort类型名为tomcat的服务。该服务的端口为6080,NodePort为30005,对应后端Pod的端口也为6080。虽然没有显示,但是它的Cluster IP为10.254.0.40。tomcat服务有两个后端Pod,IP分别是192.168.20.1和192.168.20.2。

kube-proxy 为该服务创建的iptables规则如下:

代码语言:javascript
复制
# iptables -S -t nat
-A PREROUTING -m -comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT -m -comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A POSTROUTING -m -comment --comment "kubernetes postrouting rules " -j KUBE-POSTROUTING
-A KUBE-MARK-MASQ -j MARK  --set-xmark  0x4000/0x4000

-A KUBE-NODEPORTS -p tcp -m -comment --comment "default/tomcat:"\
-m tcp --dport 30005  -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m -comment --comment "default/tomcat:"\
-m -tpc --dport 30005 -j KUBE-SVC-67RLXXX

-A KUBE-SEP-ID6YXXX -s 192.168.20.1/32 -m -comment --comment "default/tomcat:"\
-j KUBE-MARK-MASQ
-A KUBE-SEP-ID6YXXX -p tcp -m -comment --comment "default/tomcat:"\
-m tcp -j DANT --to-destination 192.168.20.1:6080

-A KUBE-SEP-IN2YXXX -s 192.168.20.2/32 -m -comment --comment "default/tomcat:"\
-j KUBE-MARK-MASQ
-A KUBE-SEP-IN2YXXX -p tcp -m -comment --comment "default/tomcat:"\
-m tcp -j DANT --to-destination 192.168.20.2:6080

-A KUBE-SERVICES -d 10.254.0.40/32 -p tcp -m -comment --comment \
"default/tomcat: cluster ip" -m tcp --dport 6080 -j KUBE-SVC-67RLXXX
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeport; NOTE: this must be the \
last rule in this chain " -m addrtype  --dst-type LOCAL -j KUBE-NODEPORTS

-A KUBE-SVC-67RLXXX  -m comment --comment "default/tomcat:" -m \
statistic --mode random --probability 0.500000000 -j KUBE-SEP-ID6YXXX
-A KUBE-SVC-67RLXXX -m comment --comment "default/tomcat:" -j \
KUBE-SEP-IN2YXXX
...

逐条分析。首先,如果是通过节点的30005端口访问NodePort,则会进入以下链,kube-proxy针对NodePort流量入口创建了KUBE-NODEPORTS 链。在我们这个例子中,KUBE-NODEPORTS 链进一步跳转到KUBE-SVC-67RLXXX链。

代码语言:javascript
复制
-A KUBE-NODEPORTS -p tcp -m -comment --comment "default/tomcat:"\
-m tcp --dport 30005  -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m -comment --comment "default/tomcat:"\
-m -tpc --dport 30005 -j KUBE-SVC-67RLXXX

再看下面的规则,这里采用了iptables的random模块,使连接有50%的概率进入KUBE-SEP-ID6YXXX链,50%的概率进入KUBE-SEP-IN2YXXX链。因此,kube-proxy的iptables模式采用随机数实现了服务的负载均衡。

代码语言:javascript
复制
-A KUBE-SVC-67RLXXX  -m comment --comment "default/tomcat:" -m \
statistic --mode random --probability 0.500000000 -j KUBE-SEP-ID6YXXX
-A KUBE-SVC-67RLXXX -m comment --comment "default/tomcat:" -j \
KUBE-SEP-IN2YXXX

KUBE-SEP-ID6YXXX 链的具体作用就是将请求通过DNAT发送到192.168.20.1的6080端口。

代码语言:javascript
复制
-A KUBE-SEP-ID6YXXX -s 192.168.20.1/32 -m -comment --comment "default/tomcat:"\
-j KUBE-MARK-MASQ
-A KUBE-SEP-ID6YXXX -p tcp -m -comment --comment "default/tomcl-service:"\
-m tcp -j DANT --to-destination 192.168.20.1:6080

当然,做完dnat后也需要snat

代码语言:javascript
复制
客户端C发起对一个服务S的访问,假设目的地址是(C,VIP),那么客户端期待得到的回程报文的源地址是VIP。即回程报文的源和目的地址应该是(VIP,C)。当网络报文经过网关(Linux内核的netfilter,包括iptables和IPVS director)进行一次DNAT后,报文的源和目的地址对呗修改成了(C,S)。当报文送到服务端S后,服务端一看报文源地址是C,便直接把响应报文返回给C,此时响应报文的源目的地址对是(S,C)。这与客户端期待报文源和目的地址不匹配,客户端收到后悔简单丢弃该报文。
因此,当报文不直接送达后端服务器,而是访问虚IP,经过一次中间网关(不管是虚拟网关还是实际网关)时,都需要在网关处做一次SANT,把报文的源IP改成网关IP地址,以便回程报文回到该网关。再让该网关把回程报文目的修改成客户端C的IP地址,源地址改成虚IP。

2.2 结果显示

综上所述,iptables模式最主要的链是KUBE-SERVICES、KUBE-SVC-和KUBE-SEP-

  • KUBE-SERVICES 链是访问集群内服务的数据包入口点,它会根据匹配到的目标IP:port将数据包分发到相应的KUBE-SVC-*链
  • KUBE-SVC-链相对于一个负载均衡器,它会将数据平均分发到KUBE-SEP-链,每个KUBE-SVC-链后面的KUBE-SEP-都和Service的后端Pod数量一样。
  • KUBE-SEP-*链通过DNAT将连接目的地址和端口从Service的IP:port替换为后端Pod的IP:port,从而将流量转发到相应的Pod。

iptables模式与userspace模式相比,虽然在稳定性和性能上均有不小的提升,但因为iptables使用NAT完成转发,也存在不可忽视的性能损耗。另外,当集群中存在上万服务时,Node上的iptables rules会非常庞大,对管理是个不小的负担,性能还会大打折扣。

3. ipvs模式

IPVS是LVS的负载均衡模块,亦基于netfilter,但比iptables性能更高,具备更好的可扩展性。kube-proxy的IPVS模式在kubernetes1.11版本达到稳定。

先来了解一下为什么添加IPVS的原因,随着kubernetes集群规模的增长,其资源的可扩展性变得越来越重要,特别是对那些运行大型工作负载的企业,其服务的可扩展性尤其重要。要知道,iptables难以扩展到支持成千上万的服务,它纯粹是为防火墙设计的,并且底层路由表的实现是链表,对路由规则的增删改查操作都要涉及便利一次链表。

尽管kubernetes 1.6版本已经支持5000节点,但使用iptables模式的kube-proxy实际上是将集群扩展到5000节点的最大瓶颈。假设,我们有1000个服务,每个服务有10个后端Pod,将会在工作节点上至少产生10000*N(N>=4)个iptables记录,这可能使内核非常繁忙的处理每次iptables规则的刷新。

并且,使用IPVS做集群内服务的负载均衡可以解决iptables带来的性能问题。IPVS专门用于负载均衡,并使用更高效的数据结构(散列表),允许几乎无限的规模扩张。

3.1 IPVS的工作原理

IPVS是Linux内核实现的四层负载均衡,是LVS负载均衡模块的实现。IPVS基于netfilter的散列表,相对于同样基于netfilter框架的iptables有更好的性能表现和扩展性。

IPVS支持TCP、UDP、SCTP、IPv4、IPv6等协议,也支持多种负载均衡策略,例如rr、wrr、lc、wlc、sh、dh、lblc等。IPVS通过persistent connection 调度算法原生支持会话保持功能。

LVS工作原理,简单来说。当外机的数据包首先经过netfilter的PERROUTING链,然后经过一次路由抉择到达INPUTU链,再做一次DNAT后经过FORWARD链离开本机网络路由协议栈。由于IPVS的DNAT是发生在netfilter的INPUT链,因此如何让网络报文经过INOUT链在IPVS中就变得非常重要。一般有两种解决方法,一种是把服务的虚IP写到本机的本地内核路由表中;另一种方法是在本机创建一个dunmmy网卡。然后把服务的虚IP绑定到该网卡上。kubernetes使用的是后者。

IPVS支持三种负载均衡模式:Direct Routing(简称DR),Tunneling(也称ipip模式)和NAT(也称Masq模式)

注:虽有一些版本的IPVS,例如华为和阿里自己维护的分支支持fullNAT,及同时支持SNAT和DNAT,但是Linux内核原生版本的IPVS只做DNAT,不做SNAT。因此在kubernetes service 的某些场景下,我们仍然需要iptables。

3.1.1 DR

IPVS的DR模式是最广泛的IPVS模式,它工作在L2,即通过Mac地址做LB,而非IP地址。在DR模式下,回程报文不会经过IPVS director 而是直接返回给客户端。因此,DR在带来高性能的同时,对网络也有一定的限制,及要求IPVS的director 和客户端在同一个局域网。另外,比较遗憾的是,DR不支持端口映射,无法支持kubernetes service的所有场景。

3.1.2 TUNNELING

IPVS的Tunneling模式就是用IP包封装IP包,因此也称ipip模式。Tunneling模式下的报文不经过IPVS director,而是直接回复给客户端。Tunneling模式统一不支持端口映射,因此很难被用在kubernetes的service场景中。

3.1.3 NAT

IPVS的NAT模式支持端口映射,回程报文需要经过IPVS director,因此也称Masq(伪装)模式。kubernetes在用IPVS实现Service时用的正式NAT模式。当使用NAT模式时,需要注意对报文进行一次SNAT,这也是kubernetes使用IPVS实现Service的微妙之处。

3.2 kube-proxy IPVS参数

在运行基于IPVS的kube-proxy时,需要注意以下参数:

  • –proxy-mode:除了现有的userspace和iptables模式,IPVS模式通过–proxymode=ipvs进行配置。
  • –ipvs-scheduler:用来指定ipvs负载均衡算法,如果不配置则默认使用round-robin(rr)算法。
代码语言:javascript
复制
如果不配置则默认使用round-robin(rr)算法。支持配置的负载均衡算法有:
        — rr:轮询,这种算法是最简单的,就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器,不管后端 RS 配置和处理能力,非常均衡地分发下去。
        — lc:最小连接,这个算法会根据后端 RS 的连接数来决定把请求分发给谁,比如 RS1 连接数比 RS2 连接数少,那么请求就优先发给 RS1 
        — dh:目的地址哈希,该算法是根据目标 IP 地址通过散列函数将目标 IP 与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标 IP 的请求会固定发给该服务器。
        — sh:原地址哈希,与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。
        — sed:最短时延
        (未来。kube-proxy可能实现在service的annotations 配置负载均衡策略,这个功能应该只能在IPVS模式下才支持)
  • –cleanup-ipvs:类似于–cleanup-iptables参数。如果设置为true,则清除在IPVS模式下创建的IPVS规则;
  • –ipvs-sync-period:表示kube-proxy刷新IPVS规则的最大间隔时间,例如5秒。1分钟等,要求大于0;
  • –ipvs-min-sync-period:表示kube-proxy刷新IPVS规则最小时间间隔,例如5秒,1分钟等,要求大于0
  • –ipvs-exclude-cidrs:用于清除IPVS规则时告知kube-proxy不要清理该参数配置的网段的IPVS规则。因为我们无法区别某条IPVS规则到底是kube-proxy创建的,还是其他用户进程的,配置该参数是为了避免删除用户自己的IPVS规则。
代码语言:javascript
复制
一旦创建一个Service和Endpoint,IPVS模式的kube-proxy会做以下三件事:
1)确保一块dummy网卡(kube-ipvs0)存在,为什么要创建dummy网卡?因为IPVS的netfilter钩子挂载INPUT链,我们需要把Service的访问绑定在dummy网卡上让内核“觉得”虚IP就是本机IP,进而进入INPUT链。
2)把Service的访问IP绑定在dummy网卡上
3)通过socket调用,创建IPVS的virtual server和real server,分别对应kubernetes的Service和Endpoint。

3.3 IPVS模式中的iptables和ipset

IPVS用于流量转发,它无法处理kube-proxy中的其他问题,例如包过滤、SNAT等。具体来说,IPVS模式的kube-proxy将在以下4中情况依赖iptables

  • kube-proxy 配置启动参数masquerade-all=true,即集群中所有经过Kube-proxy的包都将做一次SNAT
  • kube-proxy 启动参数指定集群IP地址范围
  • 支持Load Balance 类型的服务,用于配置白名单
  • 支持NodePort类型的服务,用于在包跨节点前配置MASQUERADE,类似于上文提到的iptables模式

我们不想创建太多的iptables规则,因此使用了ipset减少iptables规则,使得不管集群内有多少服务,IPVS模式iptables规则的总数在5条以内。

参考链接

  • https://kubernetes.io/docs/concepts/services-networking/service/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SY技术小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. iptables模式
  • 2.1 例子
  • 2.2 结果显示
  • 3. ipvs模式
  • 3.1 IPVS的工作原理
  • 3.1.1 DR
  • 3.1.2 TUNNELING
  • 3.1.3 NAT
  • 3.2 kube-proxy IPVS参数
  • 3.3 IPVS模式中的iptables和ipset
  • 参考链接
相关产品与服务
NAT 网关
NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档