k8s的内部服务通信

首先看看 k8s 集群中内部各个服务互相访问的方法

 

Cluster IP

Kubernetes以Pod作为应用部署的最小单位。Kubernetes会根据Pod的声明对其进行调度,包括创建、销毁、迁移、水平伸缩等,因此Pod的IP地址不是固定的,不方便直接采用Pod IP对服务进行访问。

为解决该问题,Kubernetes提供了Service资源,Service对提供同一个服务的多个Pod进行聚合。一个Service提供一个虚拟的Cluster IP,后端对应一个或者多个提供服务的Pod。在集群中访问该Service时,采用Cluster IP即可,Kube-proxy负责将发送到Cluster IP的请求转发到后端的Pod上。

Kube-proxy是一个运行在每个节点上的go应用程序,支持三种工作模式:

userspace 模式

该模式下Kube-proxy会为每一个Service创建一个监听端口。发向Cluster IP的请求被Iptables规则重定向到Kube-proxy监听的端口上,Kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。 该模式下,Kube-proxy充当了一个四层Load balancer的角色。由于Kube-proxy运行在userspace中,在进行转发处理时会增加两次内核和用户空间之间的数据拷贝,效率较另外两种模式低一些;好处是当后端的Pod不可用时,Kube-proxy可以重试其他Pod。

 

iptables 模式

为了避免增加内核和用户空间的数据拷贝操作,提高转发效率,Kube-proxy提供了iptables模式。在该模式下,Kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。 该模式下Kube-proxy不承担四层代理的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

ipvs 模式

该模式和iptables类似,Kube-proxy监控Pod的变化并创建相应的ipvs rules。ipvs也是在kernel模式下通过netfilter实现的,但采用了hash table来存储规则,因此在规则较多的情况下,Ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。如果要设置Kube-proxy为ipvs模式,必须在操作系统中安装IPVS内核模块。

 

现在有两台服务器:

  master: 10.0.20.4

  node1: 10.0.20.11

在 iptables 模式下看看 kube-dns 究竟是怎么利用 iptables 来进行解析ip的

[root@master ~]# kubectl get svc -n kube-system -o wide
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE   SELECTOR
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   2d    k8s-app=kube-dns

查看 kube-system 命名空间中所有的 pod 名字

[root@master ~]# kubectl get pods -n kube-system -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
coredns-66bff467f8-4lw92         1/1     Running   0          2d    10.32.0.3    master   <none>           <none>
coredns-66bff467f8-dt56k         1/1     Running   0          2d    10.32.0.4    master   <none>           <none>
etcd-master                      1/1     Running   0          2d    10.0.20.4    master   <none>           <none>
kube-apiserver-master            1/1     Running   0          2d    10.0.20.4    master   <none>           <none>
kube-controller-manager-master   1/1     Running   0          2d    10.0.20.4    master   <none>           <none>
kube-proxy-kqc5s                 1/1     Running   0          2d    10.0.20.4    master   <none>           <none>
kube-proxy-x8r85                 1/1     Running   0          47h   10.0.20.11   node1    <none>           <none>
kube-scheduler-master            1/1     Running   0          2d    10.0.20.4    master   <none>           <none>
weave-net-ftqmw                  2/2     Running   0          2d    10.0.20.4    master   <none>           <none>
weave-net-wlkkf                  2/2     Running   0          47h   10.0.20.11   node1    <none>           <none>

上面可以看到 kube-dns 是一个 service,背后的 pod 分别是 coredns-66bff467f8-4lw92 和 coredns-66bff467f8-dt56k

所以

service cluster-ip:10.96.0.10

pod ip:10.32.0.3 和 10.32.0.4

其中 10.96.0.10 作为集群ip,所有node上都可以进行访问,那么我们去 node1 上进行查看相关的 iptables 是怎样的

[root@master ~]# iptables-save
......

# 对于 kube-dns 的 service 的iptables
# tcp端口 53 转发到 KUBE-SVC-ERIFXISQEP7F7OF4 规则链
# tcp端口 9153 转发到 KUBE-SVC-JD5MR3NA4I4DYORP 规则链
# udp端口 53 转发到 KUBE-SVC-TCOU7JCQXEZGVUNU 规则链
-A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp cluster IP" -m tcp --dport 53 -j KUBE-SVC-ERIFXISQEP7F7OF4
-A KUBE-SERVICES -d 10.96.0.10/32 -p tcp -m comment --comment "kube-system/kube-dns:metrics cluster IP" -m tcp --dport 9153 -j KUBE-SVC-JD5MR3NA4I4DYORP
-A KUBE-SERVICES -d 10.96.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU

# 以tcp端口53查看 KUBE-SVC-ERIFXISQEP7F7OF4 规则链
# 将从规则链 KUBE-SVC-ERIFXISQEP7F7OF4 上过来的流量进行50%的分发到 KUBE-SEP-S4MK5EVI7CLHCCS6
-A KUBE-SVC-ERIFXISQEP7F7OF4 -m comment --comment "kube-system/kube-dns:dns-tcp" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-S4MK5EVI7CLHCCS6
# 其他的流量分发到 KUBE-SEP-ZT5TVM6PMFDFQAMO
-A KUBE-SVC-ERIFXISQEP7F7OF4 -m comment --comment "kube-system/kube-dns:dns-tcp" -j KUBE-SEP-ZT5TVM6PMFDFQAMO

# 查看 KUBE-SEP-S4MK5EVI7CLHCCS6 规则链
# 将流量重定向到 Pod 10.32.0.3:53
-A KUBE-SEP-S4MK5EVI7CLHCCS6 -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp" -m tcp -j DNAT --to-destination 10.32.0.3:53

Kube-proxy并不会直接接收该主机端口进入的流量,而是会创建相应的Iptables规则,并通过Iptables将从该端口收到的流量直接转发到后端的Pod中。

 

posted @ 2022-05-30 09:59  Blackbinbin  阅读(1697)  评论(0编辑  收藏  举报