『黑马程序员』网络模型来龙去脉,Kubernetes


『黑马程序员』网络模型来龙去脉,Kubernetes
文章图片
容器网络发端于Docker的网络 。 Docker使用了一个比较简单的网络模型 , 即内部的网桥加内部的保留IP 。 这种设计的好处在于容器的网络和外部世界是解耦的 , 无需占用宿主机的IP或者宿主机的资源 , 完全是虚拟的 。
【『黑马程序员』网络模型来龙去脉,Kubernetes】它的设计初衷是:当需要访问外部世界时 , 会采用SNAT这种方法来借用Node的IP去访问外面的服务 。 比如容器需要对外提供服务的时候 , 所用的是DNAT技术 , 也就是在Node上开一个端口 , 然后通过iptable或者别的某些机制 , 把流导入到容器的进程上以达到目的 。
该模型的问题在于 , 外部网络无法区分哪些是容器的网络与流量、哪些是宿主机的网络与流量 。 比如 , 如果要做一个高可用的时候 , 172.16.1.1和172.16.1.2是拥有同样功能的两个容器 , 此时我们需要将两者绑成一个Group对外提供服务 , 而这个时候我们发现从外部看来两者没有相同之处 , 它们的IP都是借用宿主机的端口 , 因此很难将两者归拢到一起 。
『黑马程序员』网络模型来龙去脉,Kubernetes
文章图片
在此基础上 , Kubernetes提出了这样一种机制:即每一个Pod , 也就是一个功能聚集小团伙应有自己的“身份证” , 或者说ID 。 在TCP协议栈上 , 这个ID就是IP 。
这个IP是真正属于该Pod的 , 外部世界不管通过什么方法一定要给它 。 对这个PodIP的访问就是真正对它的服务的访问 , 中间拒绝任何的变造 。 比如以10.1.1.1的IP去访问10.1.2.1的Pod , 结果到了10.1.2.1上发现 , 它实际上借用的是宿主机的IP , 而不是源IP , 这样是不被允许的 。 Pod内部会要求共享这个IP , 从而解决了一些功能内聚的容器如何变成一个部署的原子的问题 。
剩下的问题是我们的部署手段 。 Kubernetes对怎么实现这个模型其实是没有什么限制的 , 用underlay网络来控制外部路由器进行导流是可以的;如果希望解耦 , 用overlay网络在底层网络之上再加一层叠加网 , 这样也是可以的 。 总之 , 只要达到模型所要求的目的即可 。
Pod究竟如何上网
容器网络的网络包究竟是怎么传送的?
『黑马程序员』网络模型来龙去脉,Kubernetes
文章图片
我们可以从以下两个维度来看:
协议层次网络拓扑1.协议层次它和TCP协议栈的概念是相同的 , 需要从两层、三层、四层一层层地摞上去 , 发包的时候从右往左 , 即先有应用数据 , 然后发到了TCP或者UDP的四层协议 , 继续向下传送 , 加上IP头 , 再加上MAC头就可以送出去了 。 收包的时候则按照相反的顺序 , 首先剥离MAC的头 , 再剥离IP的头 , 最后通过协议号在端口找到需要接收的进程 。
2.网络拓扑一个容器的包所要解决的问题分为两步:第一步 , 如何从容器的空间(c1)跳到宿主机的空间(infra);第二步 , 如何从宿主机空间到达远端 。
我个人的理解是 , 容器网络的方案可以通过接入、流控、通道这三个层面来考虑 。
第一个是接入 , 就是说我们的容器和宿主机之间是使用哪一种机制做连接 , 比如Veth+bridge、Veth+pair这样的经典方式 , 也有利用高版本内核的新机制等其他方式(如mac/IPvlan等) , 来把包送入到宿主机空间;第二个是流控 , 就是说我的这个方案要不要支持NetworkPolicy , 如果支持的话又要用何种方式去实现 。 这里需要注意的是 , 我们的实现方式一定需要在数据路径必经的一个关节点上 。 如果数据路径不通过该Hook点 , 那就不会起作用;第三个是通道 , 即两个主机之间通过什么方式完成包的传输 。 我们有很多种方式 , 比如以路由的方式 , 具体又可分为BGP路由或者直接路由 。 还有各种各样的隧道技术等等 。 最终我们实现的目的就是一个容器内的包通过容器 , 经过接入层传到宿主机 , 再穿越宿主机的流控模块(如果有)到达通道送到对端 。 3.一个最简单的路由方案:Flannel-host-gw这个方案采用的是每个Node独占网段 , 每个Subnet会绑定在一个Node上 , 网关也设置在本地 , 或者说直接设在cni0这个网桥的内部端口上 。 该方案的好处是管理简单 , 坏处就是无法跨Node迁移Pod 。 就是说这个IP、网段已经是属于这个Node之后就无法迁移到别的Node上 。


推荐阅读