本文介绍 docker 的网络模式
docker 使用 linux 的 Namespaces 技术来进行资源隔离,其中网络使用 Network Namespace 来进行网络隔离。一个 Network Namespace 提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的 Network Namespace 隔离。
docker 网络模式
在使用 docker run 创建容器时,可以用 –net 选项指定容器的网络模式,有如下几种模式
host 模式
–net=host容器不使用独立的 Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
例如,在 10.10.101.105/24 的机器上用 host 模式启动一个含有 web 应用的 docker 容器,监听 tcp80 端口。在容器中执行任何类似 ifconfig 命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。
container 模式
–net=${CONTAINER}指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。
两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的,两个容器的进程可以通过 lo 网卡设备通信。none 模式
–net=none在这种模式下,docker 容器拥有自己的 Network Namespace,但是并不为 docker 容器进行任何网络配置。
这个 docker 容器没有网卡、IP、路由等信息。需要自己为 docker容器添加网卡、配置IP等。
bridge 模式
–net=bridgedocker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置IP等,并将一个主机上的 docker 容器连接到一个虚拟网桥上
自定义网络
–net=user_define_network使用用户自定义的网络模式
bridge 模式的拓扑
当 docker 服务启动时,会在宿主上创建一个 docker0 虚拟网桥,在此宿主上启动的容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样宿主上的所有容器就通过交换机连在了一个二层网络中,如下图。
容器创建时, docker 为会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主不同的 IP 地址和子网分配给 docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的IP使用。
docker 完成以上网络配置需要才下几步:
- 在主机上创建一对虚拟网卡 veth pair 设备(veth 设备总是成对出现,组成了一个数据的通道)
- docker 将veth pair设备的一端放在新创建的容器中,并命名为eth0;另一端放在主机中,以 veth65f9 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中
- 从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关
自定义网络
docker 的 network 子命令可以设置网络相关的配置
1 | # 列出所有的网络 |
1 | # 创建一个网络 |
1 | # 删除一个网络 |
1 | # 把容器接入到指定网络 |
1 | # 把容器从网络卸载下来 |
1 | # 查看网络的详细信息 |
各种网络场景(示例)
宿主外部访问容器
一般宿主外部不需要直接访问容器,而是通过 run 命令的 -p 选项将容器的端口映射到宿主的端口。宿主外部通过这个端口访问容器的服务。
容器访问宿主外部
容器可以直接通过宿主的网桥访问宿主外部网络
同一宿主下多个容器组网
使用同一个 bridge 下的容器就是在同一个子网中,容器可以互相联通。但如果不是同一个 bridge 下的容器,默认情况下是不互通的。
创建容器时,可以用 run 命令的 –hostname 选项和 –ip 选项指定容器的 hostname 和 ip
同时可以用 –add-host ${hostname}:${ip} 将条目加入到 /etc/hosts 文件中(只有用户定义的网络可以使用)
跨宿主容器网络
- 启动两台 docker 宿主 n1 和 n2,分别安装好 docker-engine 并确保两台宿主之间可以通过 IP 互相访问
- 在任务节点上创建网络 multi,例如在 n1 上执行
1 | docker network create -d overlay multi |
创建成功后,在 n1 和 n2 上都可以用 docker network ls 看到 multi 的网络信息
- 在 n1 上创建容器 c1, 在 n2 上创建容器 c2,分别用 –net mulit 指定连接到 multi 网络。通过 ping 可以测试出 c1 可以 ping 通 c2