把 K8S 里几个网络层面的问题串一遍:三类网段的关系、Pod 之间怎么通信、Service 的地址为什么是虚拟的。概念笔记,不涉及插件部署。
节点网络、集群网络、Pod 网络
Service 的地址和 Pod 的地址不在同一个网段。Pod 地址配置在容器自己的网络名称空间里,是真实可 ping 通的;Service 地址是虚拟的,只存在于各节点 iptables/ipvs 规则里。整体上三层:节点网络、集群网络、Pod 网络。外部访问进来先落到节点网络,由节点网络代理到集群网络,再到 Pod 网络。
Pod 内部与跨主机容器
同一个 Pod 内的多个容器共享网络名称空间,容器间走 lo 本地通信即可。
不同宿主机上的两个 Docker 容器,如果内部 IP 相同,就无法直接通信。跨节点容器通信的原理:节点 1 的容器发出请求,先经 SNAT 把源地址转换成宿主机地址再发给节点 2,节点 2 经 DNAT 转交给目标容器。
防止地址冲突的办法:每台宿主机建 docker0 桥时指定不同网段,比如节点 1 用 172.17.1.x,节点 2 用 172.17.2.x。
Pod 之间、Service 与 Pod
跨主机的 Pod 互通靠 Overlay Network(叠加网络),用隧道方式转发二层报文。但 K8S 里考虑到 Pod 生命周期太短,Pod 之间不直接通信,而是 Service 挡在前面转发。
Service 和 Pod 属于不同网络,通信方式:Service 地址就挂在宿主机的 iptables 规则上,容器把报文目标地址指向网关(一般是 docker0 桥地址)就行,每台宿主机都要有对应的 iptables 或 ipvs 规则。
两个连带问题:Pod 发生变化,Service 靠标签选择器感知;所有节点上的规则同步,由每个节点上的守护组件 kube-proxy 负责维护。
这一切 K8S 本身不提供
以上网络打通依赖第三方插件,K8S 通过 CNI(容器网络接口)接入外部网络方案,目前用得最多的是 flannel。
















暂无评论内容