1 Docker网络原理
Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。这里就涉及到两个新的概念。
1.1 网络命名空间
命名空间,通常用以区分不同范畴内的各种资源。而Linux的网络命名空间(network namespace)用以在一个Linux主机上创建出多个隔离的网络环境(iptables规则表、路由规则表、网络设备列表),构建虚拟网络。
1.2 虚拟网络设备
由于不同的网络命名空间之间是相互隔离的,所以不同的网络命名空间之间并不能直接通信。但是有时候,我们又需要从一个网络命名空间中访问另一个网络命名空间中的网络,这就需要用到虚拟网络设备。
虚拟网络设备(Virtual Network Device,veth)是一种抽象的网络设备,类似网络管道,用以在不同的网络命名空间之间建立传输隧道,也可以用以创建网桥以连接到多个其他网络命名空间。veth是一种虚拟的网络设备,总是被成对地创建,并且一对veth永远是连通的,所以veth一般被称之为veth pair。
Docker就是使用虚拟网络设备对,在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通来实现不同容器之间的通信。
每个容器之间并不是直接通过 虚拟网络设备对 来进行连接的,而是在主机上创建一个名为 docker0 的 网桥,然后通过 虚拟网络设备对 来将各个容器连接到 网桥 上。网桥 有将多个 网络设备 连接起来的能力,就如现实中的 交换机 一样。
2 Docker网络模式
Docker有四种网络模式,分别是Bridge(创建容器默认连接到此网络)、 None 、Host、Container
Host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
Bridge | 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。 |
None | 该模式关闭了容器的网络功能。 |
Container | 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。 |
自定义网络 | 略 |
2.1 Bridge模式
Bridge模式是 docker 的默认网络模式。当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从docker0子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。
创建一个新的 Docker 网络,运行容器并连接到新建的 my-net 网络:
docker network create -d bridge my-net docker run -it --rm --name busybox1 --network my-net busybox sh docker run -it --rm --name busybox2 --network my-net busybox sh
2.2 Host模式
启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
docker run -tid --net=host --name docker_host1 ubuntu-base:v3
2.3 Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
docker run -tid --net=container:docker_bri1 --name docker_con1 ubuntu-base:v3
2.4 None模式
使用none模式,Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。
docker run -tid --net=none --name docker_non1 ubuntu-base:v3