运行Docker容器时, 有不同的网络选项可供选择。
在主机上安装Docker后,默认情况下, 它会创建一个名为Bridge的内部专用网络.
Docker使用名称Bridge来调用网络,但在主机上, 网络是使用名称Docker0创建得.
docker network ls
ip link
Docker在内部使用了network namespace
ip link add docker0 type bridge
创建容器时, Docker都会为其创建一个网络名称空间。
Docker在内部创建了一条虚拟cable, 接口的一端连接到本地网桥,即Docker0;另一端连接到容器。
建立端口映射:Docker创建一个NAT规则。使用IPtables, 在NAT表中创建一个条目,将规则附加到预路由Docker链中, 以将目的端口从8080更改为80。
Docker 的网络方案简单有效,但问题是它只局限在单机环境里工作,跨主机通信非常困难(需要做端口映射和网络地址转换)。
回顾了docker中网络命名空间的工作原理,
除了docker,其他容器解决方案也以同样的方式解决了网络问题,如rkt或Mesos。kubernetes从其中抽出共同的部分移到了一个标准下。
kubernetes定义了Container Networking Interface标准, 包含了应如何开发程序以解决容器运行时环境中的网络问题。这些程序被称为插件。CNI定义了如何开发插件以及容器运行时如何调用它们。
CNI为容器运行时和插件定义了一组职责。
CNI要求,容器运行时实现:
CNI要求,插件支持
只要容器运行时和插件遵守CNI标准,任何容器运行时都应该能够与任何插件兼容。
CNI附带了一组支持的插件:
第三方厂商提供了其他插件:
所有这些容器运行时都实现了CNI标准, 因此它们中的任何一个都可以与这些插件中的任何一个一起工作。
但Docker不实现CNI。Docker有自己的一套标准, 称为CNM container network model。因此这些插件不与Docker原生集成.
由于不能将Docker与CNI一起使用,Kubernetes额外调用自己的Bridge插件。
当Kubernetes调用Docker容器运行时,会先在None网络上创建容器。然后, 调用已配置的CNI插件,负责其余的配置。
CNI插件由Kubernetes中负责创建容器的kubelet组件调用,因为kubelet组件须在创建容器后调用相应的网络插件。
CNI插件配置在集群中每个节点上的kubelet.service文件中。
ps -aux | grep kubelet
# cni-bin-dir cni-conf-dir network-plugin
ls /opt/cni/bin/
# bandwidth calico dhcp firewall host-device install loopback portmap sbr tuning vrf
# bridge calico-ipam dummy flannel host-local ipvlan macvlan ptp static vlan
ls /etc/cni/net.d/
# 10-canal.conflist calico-kubeconfig
CNI 插件可以分成Overlay,Route,Underlay三种。