【k8s】2.k8s通信原理

前情提要~ docker的通信原理:【docker】2.dock网络-CSDN博客

目录

1. Pod网络

1.1 pod 中容器间的通信

1.2 同一节点中不同 pod 间的通信

1.3 不同节点间 pod 的通信

2. Service网络

2.1 4种service访问方式

2.1.1 ClusterIP 集群内访问模式

2.1.2 NodePort 集群外访问模式

2.1.3 LoadBalancer 云负载均衡器模式

2.1.4 ExternalName 模式

2.2 Kube-Proxy

2.2.1 user space(已弃用)

2.2.2 iptables(默认)

2.2.3 IPVS

2.3 DNS


1. Pod网络

1.1 pod 中容器间的通信

k8s 会在 pod 中首先创建一个名为 pause 的容器,为其他容器提供共享的基础设施。

pause容器很简单,就是创建了一个简易容器,执行了/pause命令,保持一个容器处于running:

10d393461904   registry.aliyuncs.com/google_containers/pause:3.5   "/pause"   30 hours ago    
  Up 30 hours    k8s_POD_traefik-68b9ccfc77-x8sqg_traefik_aa5b97bf-3db8-4b92-89a7-1fe551645e6a_0

pause 容器会创建一个网络命名空间,其他容器加入到 puase 容器中共享 pause 的网络,一个 pod 中所有的进出流量都是通过 pause 容器完成的,通过 localhost 相互通信。

pause 会在容器内创建一个 eth0 网卡,在宿主机创建一个 veth0 网卡,组成一个网卡接口对。

1.2 同一节点中不同 pod 间的通信

k8s 会在节点上建立一个虚拟网桥 docker0,为 pod 分配 ip,这些 ip 在一个网段上,可以通过 ip 寻址进行通信。(由docker0广播ARP请求,记录MAC表)

每生成一个 pod,节点上就会生成一个虚拟网卡 vethx,与 pod 中的 vethx 对应组成一个 veth 对。

通信过程:POD A 从 veth0 发出包,docker0 网桥从 veth1 接口收到这个包,然后 docker0 网桥查找转发表,将包从 veth0 发送,POD B 则在 veth1接口接收到包。

这一过程和docker桥接网络的原理是相同的。

1.3 不同节点间 pod 的通信

(1)Overlay 覆盖网络

在现有网络上建立一个虚拟网络,采用隧道封包技术,即把 pod 网络的数据包封装成 node 网络的数据包,到达目标 node 再解封,转发给节点内部的 pod 网络。(封包解包有性能开销)

Overlay 通常由网络插件来实现,如 Flannel、Calico(k8s都支持,可配),这些插件遵循 CNI 容器网络接口规范。

(2)封包

由于这些 pod 位于不同的物理节点上,需要一个机制来封装和传输数据,在报文中添加源地址、目标地址、端口号等信息,使得网络设备能够正确地识别和转发报文,确保它们能够正确地到达目标地址。并且由于不同的底层网络可能具有不同的协议和规则,通过封包构建一个统一的、抽象的通信层,实现底层网络兼容。

(3)Underlay网络

构件底层的物理网络,通过路由设备为 pod 网络单独划分网段,并配置路由器支持 pod 网络的转发。underlay 方案 k8s 也支持,但 k8s 更倾向于用 overlay,更抽象更灵活。

2. Service网络

2.1 4种service访问方式

2.1.1 ClusterIP 集群内访问模式

(1)虚拟的 ip

ClusterIP 用于提供集群内部可访问的虚拟 IP,这个 IP 仅集群内部可达。

Pod IP 是存在于某个网卡上的,但 Cluster IP 是一个完全虚拟的 IP,没有对应的网络设备。(所以 Cluster IP 无法被 ping

(2)服务注册和发现

在 Pod 实例发布时,Kubelet 会把服务的 PodIP 列表注册到 Master 节点。

在 Service 发布时,K8s 为服务分配 ClusterIP,相关信息也注册到 Master 节点。

Kube-Proxy 在每个节点上运行,监听 ClusterIP 和 PodIP 列表映射关系,改写本地的 linux iptables 转发规则,指示 iptables 在接收到目标为某个 ClusterIP 请求时,进行负载均衡并转发到对应的 PodIP 上。

当有 Pod 需要访问某个目标服务时,它通过 ClusterIP 发起调用,这个 ClusterIP 会被本地 iptables 机制截获,通过负载均衡,转发到目标 Pod。

(3)KubeDNS

客户端并不直接调服务的 ClusterIP,而是调用服务名,因为 ClusterIP 会变,只有服务名一般不变。

为了屏蔽 ClusterIP 的变化,k8s 在每个节点上引入了一个 KubeDNS 组件,记录服务名和 ClusterIP 之间映射关系。

(4)Service 关联 Pod

通过标签选择器选择一组相关的pod

2.1.2 NodePort 集群外访问模式

- NodePort 端口:

在集群每个节点上开放一个 NodePort 端口(范围30000~32767),和 ClusterIP 的 Port 映射在一起。

外部通过访问任一节点 IP + NodePort 发起调用,通过 Kube-Proxy 转发到 Service 抽象层,再转发到目标 Pod 上。

NodePort 本身没有为多个节点进行负载均衡能力,需要额外使用如 LoadBalancer 类型的 Service 或外部负载均衡器。

- 几种 Port:

containerPort:容器暴露的端口,在 Pod 中定义的

port:Service 暴露在集群内的端口,即 ClusterIP:port

nodePort:集群节点向外网暴露的接口,即 nodeIP:nodePort

targetPort:Pod 上的端口,与 containerPort 必须一致

2.1.3 LoadBalancer 云负载均衡器模式

在 NodePort 的基础上增加了云服务商提供的负载均衡器 Load-Balancer,并为 Service 分配一个外部IP地址。

使用该均衡器后进行访问时不需要再带着具体的 nodePort 值,k8s 会请求云平台(阿里云/腾讯云/AWS)上的负载均衡器服务,可以将流量自动分配到集群的不同节点上。

2.1.4 ExternalName 模式

提供集群内部访问外网的方式。

将集群外的服务(如 IP 地址或域名)映射到集群内的 DNS 中,集群内部就可以通过 Service 名称直接访问外部服务。

ExternalName 模式仅仅是一个 DNS 别名,并不涉及端口映射或负载均衡,不创建任何网络代理或转发规则。

2.2 Kube-Proxy

三种工作模式:

2.2.1 user space(已弃用)

kube-proxy 监听 service 和 endpoint 的变化,当有 service 创建时,所有节点的 kube-proxy 在节点上随机选择一个端口,在 iptables 中追加一条,把访问 service 的请求重定向到这个端口的,并监听这个端口的连接请求。

2.2.2 iptables(默认)

kube-proxy 监听 service 和 endpoint对象的变化,当有 servcie 创建时,kube-proxy 在 iptables 中追加新的规则。对 service 的每一个 endpoint,会在iptables中追加一条规则,将目的地址设置成真正的pod地址;再为 service 追加规则,设定动作为跳转到对应的 endpoint 的规则上。

如何查看iptables规则:Kubernetes-Training /02 Kubernetes 概念与实践.md

2.2.3 IPVS

iptables模式最主要的问题是在服务多时会产生太多 iptables 规则,非增量式更新会引入一定的时延,大规模情况下有明显的性能问题。IPVS是基于iptables,使用了hash表存储,性能更高。

2.3 DNS

为什么可以直接使用svc名称用作host访问呢?

查看以下pod的解析地址:

# kubectl  -n luffy exec -it myblog-7fb9874dd9-bsj6s cat /etc/resolv.conf
nameserver 10.96.0.10
search luffy.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

10.96.0.10是什么:

# kubectl -n kube-system get svc
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   3d20h

10.96.0.10这个地址是固定的,搭建任意集群都是这个地址。

pod启动时,kube-dns 服务的 cluster-ip 地址会被注入到 pod 的 resolve 解析配置中,这样就 svc 名就可以作为域名直接访问了。

同时,resolve会添加对应的 ns 的 search 域,也就是当需要跨 ns 访问时,只需添加上 ns 名称就可以了。

  • 44
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值