11.k8s之service和kube-proxy

转载
https://zhuanlan.zhihu.com/p/94418251
https://sq.163yun.com/blog/article/174981072898940928
https://draveness.me/kubernetes-service/

1.为什么需要kube-proxy和service

容器的特点就是快速创建、快速销毁。为了能够访问这些pod,需要引入负载均衡和VIP实现后端真实服务的自动转发和故障漂移。
这个负载均衡就是service,VIP就是service IP,service就是一个四层负载均衡。
k8s为了实现在集群所有的节点都能访问service,Kube-proxy默认会在所有的节点创建这个VIP,实现负载均衡

2.service

创建service需要ServiceControllerEndpointControllerkube-proxy,三大模块同时协作

2.1.ServiceController

当一个service对象状态发生变化的时候,Informer都会通知ServiceController,创建对应的服务

2.2.EndpointController

EndpointController会同时订阅Service和Pod的增删事件。其功能如下

负责生成和维护所有endpoint对象的控制器

负责监听service和对应pod的变化

监听到service被删除,则删除和该service同名的endpoint对象

监听到新的service被创建,则根据新建service信息获取相关pod列表,然后创建对应endpoint对象

监听到service被更新,则根据更新后的service信息获取相关pod列表,然后更新对应endpoint对象

监听到pod事件,则更新对应的service的endpoint对象,将podIp记录到endpoint中

3.kube-proxy

kube-proxy 负责service实现,实现了k8s内部service和外部node port到service的访问。
kube-proxy采用iptables的方式配置负载均衡,基于iptables的kube-proxy的主要职责包括两大块:一块是侦听service更新事件,并更新service相关的iptables规则,一块是侦听endpoint更新事件,更新endpoint相关的iptables规则(如 KUBE-SVC-链中的规则),然后将包请求转入endpoint对应的Pod。
在这里插入图片描述

3.1.kube-proxy之iptables实现原理

# kubectl get svc -o wide
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes-bootcamp-v1   ClusterIP   10.106.224.41   <none>        8080/TCP   163m

其中ClusterIP为10.106.224.41,我们可以验证这个IP在本地是不存在的,所以不要尝试去ping ClusterIP,它不可能通的

root@ip-192-168-193-172:~# ping -c 2 -w 2 10.106.224.41
PING 10.106.224.41 (10.106.224.41) 56(84) bytes of data.

--- 10.106.224.41 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1025ms

此时在Node节点192.168.193.172上访问该Service服务,首先流量到达的是OUTPUT链,这里我们只关心nat表的OUTPUT链:

# iptables-save -t nat | grep -- '-A OUTPUT'
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES

该链跳转到KUBE-SERVICES子链中:

# iptables-save -t nat | grep -- '-A KUBE-SERVICES'
...
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.106.224.41/32 -p tcp -m comment --comment "default/kubernetes-bootcamp-v1: cluster IP" -m tcp --dport 8080 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.106.224.41/32 -p tcp -m comment --comment "default/kubernetes-bootcamp-v1: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-RPP7DHNHMGOIIFDC

我们发现与之相关的两条规则:

  • 第一条:负责打标记MARK0x4000/0x4000,后面会用到这个标记
  • 第二条:负责跳到KUBE-SVC-RPP7DHNHMGOIIFDC子链

其中KUBE-SVC-RPP7DHNHMGOIIFDC子链规则如下:

# iptables-save -t nat | grep -- '-A KUBE-SVC-RPP7DHNHMGOIIFDC'
-A KUBE-SVC-RPP7DHNHMGOIIFDC -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-FTIQ6MSD3LWO5HZX
-A KUBE-SVC-RPP7DHNHMGOIIFDC -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-SQBK6CVV7ZCKBTVI
-A KUBE-SVC-RPP7DHNHMGOIIFDC -j KUBE-SEP-IAZPHGLZVO2SWOVD

查看KUBE-SEP-FTIQ6MSD3LWO5HZX子链规则:

# iptables-save -t nat | grep -- '-A KUBE-SEP-FTIQ6MSD3LWO5HZX'
-A KUBE-SEP-FTIQ6MSD3LWO5HZX -p tcp -m tcp -j DNAT --to-destination 10.244.1.2:8080

可见这条规则的目的是做了一次DNAT,DNAT目标为其中一个Endpoint,即Pod服务

由此可见子链KUBE-SVC-RPP7DHNHMGOIIFDC的功能就是按照概率均等的原则DNAT到其中一个Endpoint IP,即Pod IP,假设为10.244.1.2.此时相当于

192.168.193.172:xxxx -> 10.106.224.41:8080
                      |
                      |  DNAT
                      V
192.168.193.172:xxxX -> 10.244.1.2:8080

接着来到POSTROUTING链:

# iptables-save -t nat | grep -- '-A POSTROUTING'
-A POSTROUTING -m comment --comment "kubernetes postrouting rules" -j KUBE-POSTROUTING
# iptables-save -t nat | grep -- '-A KUBE-POSTROUTING'
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -m mark --mark 0x4000/0x4000 -j MASQUERADE

这两条规则只做了一件事只要标记为0x4000/0x4000包,一律做SANT,由于10.244.1.2默认是从flannel.1转发出去的,因此会把源IP改为flannel.1的IP10.244.0.0

192.168.193.172:xxxx -> 10.106.224.41:8080
                      |
                      |  DNAT
                      V
192.168.193.172:xxxx -> 10.244.1.2:8080
                      |
                      |  SNAT
                      V
10.244.0.0:xxxx -> 10.244.1.2:8080
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值