
16.Kubernetes网络模型
1.docker的网络
docker 使用了一个比较简单的网络模型,即内部的网桥加内部的保留 IP。这种设计的好处在于容器的网络和外部世界是解耦的,无需占用宿主机的 IP 或者宿主机的资源,完全是虚拟的。它的设计初衷是:当需要访问外部世界时,会采用 SNAT 这种方法来借用 Node 的 IP 去访问外面的服务。比如容器需要对外提供服务的时候,所用的是 DNAT 技术,也就是在 Node 上开一个端口,然后通过 iptable 或者别的某些机制,把流导入到容器的进程上以达到目的。
在此基础上,Kubernetes 提出了这样一种机制:即每一个 Pod,也就是一个功能聚集小团伙应有自己的“身份证”,或者说 ID。在 TCP 协议栈上,这个 ID 就是 IP。
这个 IP 是真正属于该 Pod 的,外部世界不管通过什么方法一定要给它。对这个 Pod IP 的访问就是真正对它的服务的访问,中间拒绝任何的变造。比如以 10.1.1.1 的 IP 去访问 10.1.2.1 的 Pod,结果到了 10.1.2.1 上发现,它实际上借用的是宿主机的 IP,而不是源 IP,这样是不被允许的。Pod 内部会要求共享这个 IP,从而解决了一些功能内聚的容器如何变成一个部署的原子的问题。
2.Pod如何上网
网络包不会自己飞,只能一步一步爬
1)协议层次,需要从L2层(mac寻址) 到L3层(Ip寻址)到L4(4层协议+端口)
2)网络拓扑,需要从容器空间到宿主机空间到远端
容器网络的方案可以通过接入、流控、通道这三个层面来考虑。
- 第一个是接入,就是说我们的容器和宿主机之间是使用哪一种机制做连接,比如 Veth + bridge、Veth + pair 这样的经典方式,也有利用高版本内核的新机制等其他方式(如 mac/IPvlan 等),来把包送入到宿主机空间;
- 第二个是流控,就是说我的这个方案要不要支持 Network Policy,如果支持的话又要用何种方式去实现。这里需要注意的是,我们的实现方式一定需要在数据路径必经的一个关节点上。如果数据路径不通过该 Hook 点,那就不会起作用;
- 第三个是通道,即两个主机之间通过什么方式完成包的传输。我们有很多种方式,比如以路由的方式,具体又可分为 BGP 路由或者直接路由。还有各种各样的隧道技术等等。最终我们实现的目的就是一个容器内的包通过容器,经过接入层传到宿主机,再穿越宿主机的流控模块(如果有)到达通道送到对端。
3.Service如何工作
首先是由一群 Pod 组成一组功能后端,再在前端上定义一个虚 IP 作为访问入口。一般来说,由于 IP 不太好记,我们还会附赠一个 DNS 的域名,Client 先访问域名得到虚 IP 之后再转成实 IP。Kube-proxy 则是整个机制的实现核心,它隐藏了大量的复杂性。它的工作机制是通过 apiserver 监控 Pod/Service 的变化(比如是不是新增了 Service、Pod)并将其反馈到本地的规则或者是用户态进程。