一篇讲给自己听的k8s网络模型

2,405 阅读2分钟

不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。 ——文森特・梵高

k8s网络模型的实现,致力于解决一下场景:

  • 紧密耦合的容器到容器之间的通信
  • 抽象的Pod 到Pod之间的通信
  • Pod到Service之间的通信
  • 集群外部和内部组件之间的通信

同一个Pod内的容器之间的通信

  • 同一个Pod内的容器共享IP, 端口不同,可以直接通过localhost通信
  • 可以直接使用IPC进行通信(例如消息队列或者管道)

不同Pod内的容器通信

同一个Node上的Pod之间通信

  • 他们网段是一样的,都是从Docker0上分配的,同一个网桥,可以直接通信

  • 对于pod发送的非本地数据,都会通过Docker 0 路由中转到宿主机中

不同Node上的Pod之间通信

k8s在etcd 里面保存了所有正在运行的Pod的IP分配信息,要求这些Pod的IP地址在不能有冲突。(比如Flannel就能自动为不同的Node上的Docker0分配网段)。

不同Node上的两个Pod之间的通信,要达到两个条件:

  • 在整个k8s集群中对Pod的IP 进行统一分配,不能有冲突

  • 找到一种方法,将Pod的IP 和 所在的Node 的IP 进行关联

docker0网段和宿主机网卡是两个完全不同的IP网段, 只能通过宿主机物理网卡进行通信, 所以只能通过宿主机的IP地址进行通信。

Pod 和Service 之间的通信

Service是对Pod的抽象,为的是Pod能进行水平扩展, 从而可以通过Service来负载均衡的访问Pod。

客户端通过Service的虚拟IP地址访问Service, Service负责将请求转发到后端的Pod上,类似与反向代理

每一个Nodes上部署的kube-proxy会把对Service的访问,转发到后端的多个Pod上

Service的ClusterIP与NodePort等概念是kube-proxy通过Iptables的NAT转换实现的,对Cluster IP 和 Port的访问可以在任意的Node上运行,这是因为每个Node上的kube-proxy针对该Service都设置了相同的转发规则。

开源网络组件

Flannel

  • 给每个Node上的Docker容器分配互不冲突的IP地址
  • 在每个IP地址之间建立一个叠加网络,通过叠加网络原封不动的传递到目标容器内。
  • Flannel通过修改Docker的启动参数,把分配好的地址段参数传递过去
  • Flannel缺省采用的是UDP, 在大流量的情况下还要反复测试可用性

总结

了解了k8s网络模型是了解k8s内部通信机制的前提,下一篇将带大家了解k8s的服务发现的方式!