Kubernetes 网络权威指南:基础、原理与实践

我们在使用 docker run 命令创建 Docker 容器时,可以使用 --network选项指定容器的网络模式。

Docker 有以下4种网络模式:

  • bridge 模式,通过--network=bridge 指定;

  • host 模式,通过--network=host 指定;

  • container 模式,通过--network=container:NAME_or_ID 指定,即joiner 容器;

  • none模式,通过--network=none指定。

在安装完 Docker 之后,Docker Daemon 会在宿主机上自动创建三个网络,分别是 bridge 网络、host 网络和 none 网络,可以使用docker network ls命令查看。

1.1、bridge 模式

Docker 在安装时会创建一个名为 docker0 的 Linux 网桥。 bridge 模式是 Docker 默认的网络模式,在不指定--network 的情况下,Docker 会为每一个容器分配 network namespace、设置 IP 等,并将 Docker 容器连接到 docker0 网桥上。严谨的表述是,创建的容器的 veth pair 中的一端桥接到 docker0 上。

在默认情况下, docker0 的 IP 地址均为 172.17.0.1 (除非在 Docker Daemon 启动时自行配置),而接到 docker0 上的 Docker 容器的 IP 地址范围是172.17.0.0/24。连接在 docker0 上的所有容器的默认网关均为 docker0, 即访问非本机容器网段要经过 docker0 网关转发,而同主机上的容器(同网段)之间通过广播通信。

bridge 模式为 Docker 容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,使容器和容器、容器和宿主机之间能实现网络隔离。

1.2、host 模式

连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。 host 模式下容器将不会获得独立的 network namespace,而是和宿主机共用一个 network namespace 。容器将不会虚拟出自己的网 卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。

host 模式下的容器可以看到宿主机的所有网卡信息,甚至可以直接使用宿主机 IP 地址和主机名与外界通信,无须额外进行 NAT,也无须通过 Linux bridge 进行转发或者进行数据包的封装。

host 模式有利有弊,优点是没有性能损耗且配置方便,缺点也很明显,例如:容器没有隔离、独立的网络栈,容器因与宿主机共用网络栈而争抢网络资源,并且容器崩溃也可能使主机崩溃,导致网络的隔离性不好;端口资源冲突,宿主机上已经使用的端口就不能再用了。

1.3、container 模式

创建容器时使用 --network=container:NAME_or_ID 模式,在创建新的容器时指定容器的网络和一个已经存在的容器共享一个 network namespace,但是并不为 Docker 容器进行任何网络配置,这个 Docker容器没有网卡、 IP、路由等信息,需要手动为 Docker容器添加网卡、配置 IP 等。

需要注意的是,container 模式指定新创建的容器和已经存在的任意一个容器共享一个 network namespace,但不能和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、 端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

Kubernetes 的 Pod 网络采用的就是 Docker 的 container 模式网络

1.4、none 模式

none 模式下的容器只有 lo 回环网络,没有其他网卡。 none模式网络可以在容器创建时通过 --network=none 指定。这种类型的网络没有办法联网,属于完全封闭的网络。唯一的用途是客户有充分的自由度做后续的配置。

这种模式下的 Docker 容器拥有自己的 network namespace,但是并不为 Docker容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、 IP、路由等信息,需要我们自己为 Docker 容器添加网卡、配置 IP 等。