Docker网络管理及容器互联指南,涵盖bridge、host、overlay、macvlan、none五种模式及跨主机通信配置。
原文标题:Docker网络管理及容器互联
原文作者:牧羊人的方向
冷月清谈:
bridge模式是Docker默认的网络模式,为每个容器分配独立的网络命名空间和IP,并通过docker0虚拟网桥连接到主机网络。host模式则让容器与主机共享网络命名空间,直接使用主机的IP和端口。overlay模式用于跨主机的容器通信,通过虚拟网络将多个Docker主机连接在一起。macvlan模式为容器分配MAC地址,使其像物理设备一样出现在网络中。none模式下容器只有回环网络,需要手动配置网络。
文章通过具体的操作步骤和命令演示了如何创建和配置不同网络模式的容器,并测试了容器间的连通性。例如,在overlay模式下,文章演示了如何使用consul服务发现实现跨主机容器通信;在macvlan模式下,文章演示了如何配置网卡的混杂模式以及如何为容器分配IP地址。
此外,文章还介绍了如何连接同一主机内的多个容器,以及如何实现跨主机的容器通信。对于同一主机内的容器通信,文章演示了如何创建新的Docker网络并将多个容器连接到该网络中。对于跨主机的容器通信,文章提到了可以使用overlay和macvlan模式来实现。
怜星夜思:
2、overlay网络的实现依赖于服务发现,文章中使用了consul,那除了consul之外,还有哪些常用的服务发现工具可以用于Docker overlay网络?它们各自有什么特点?
3、文章中提到的五种网络模式,在实际应用中该如何选择?有没有一些通用的选择策略或建议?
原文内容
Docker网络有bridge、host、overlay、macvlan和none五种模式,本文对这几种网络模式进行验证并测试容器间的互联通信。
1、Docker网络管理
Docker有5种网络模式,在创建容器的时候指--net参数设定网络模式:
-
bridge桥接模式:默认模式,通常用于独立部署的容器之间的通信
-
host主机模式:对于独立部署容器,移除容器和Docker主机间的网络隔离,直接使用主机的网络
-
overlay模式:将多个Docker守护进程连接在一起,并使集群之间能够相互通信,也可以用于集群环境和独立部署容器之间的通信或者两个独立容器之间不同守护进程之间的通信
-
macvlan模式:为容器分配MAC地址,在网络上显示物理设备。Docker守护进程通过MAC地址将流量路由到容器中
-
none模式:Docker容器不会设置网络环境,容器内部只能使用loopback网络设备
在安装完docker以后,宿主机上会创建三个网络,分别是bridge网络,host网络,none网络,可以使用docker network ls命令查看:
[root@tango-01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
beae4c09945e bridge bridge local
7bbafde1931d host host local
56440e57a748 none null local
Bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
-
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。
-
为容器分配IP,Docker会选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的 IP 使用。如一般Docker会使用 172.17.0.0/16这个网段,并将 172.17.42.1/16分配给 docker0 网桥
Bridge桥接模式的实现原理主要如下:
-
Docker Daemon利用veth pair技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0和veth1。Veth pair技术的特性可以保证无论哪一个veth接收到网络报文,都会将报文传输给另一方
-
Docker Daemon将veth0附加到Docker Daemon创建的docker0网桥上,保证宿主机的网络报文可以发往veth0
-
Docker Daemon将veth1添加到Docker Container所属的namespace下,并被改名为eth0
如此一来,保证宿主机的网络报文如果发往veth0,则立即会被eth0接收,实现宿主机到Docker Container网络的联通性;同时保证Docker Container单独使用eth0,实现容器网络环境的隔离性。
1)列出当前主机网桥
[root@tango-01 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242857c0ccd no
virbr0 8000.52540010a078 yes virbr0-nic
2)查看当前 docker0 ip
[root@tango-01 ~]# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:85:7c:0c:cd txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
在容器运行时,每个容器都会分配一个特定的虚拟机口并桥接到docker0。每个容器都会配置同docker0 ip相同网段的专用ip地址,docker0的IP地址被用于所有容器的默认网关。
3)运行一个容器
[root@tango-01 ~]# docker run -it -d ubuntu:latest /bin/bash
ba6fc34e3c5404410fab232890a8f259408f87adca417ed4a5200fb144c5bea0
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba6fc34e3c54 ubuntu:latest "/bin/bash" 14 seconds ago Up 12 seconds keen_euclid
[root@tango-01 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242857c0ccd no veth9292ea4
virbr0 8000.52540010a078 yes virbr0-nic
以上, docker0扮演着ba6fc34e3c54这个容器的虚拟接口veth9292ea4 interface桥接的角色
如果使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。Host方式由于无需额外进行NAT转换,效率上会有提升,但是Docker容器网络环境的隔离会被弱化。
1)创建一个容器指定net为host
[root@tango-01 ~]# docker run --rm -d --network host --name my_nginx nginx:latest
73c935d570b0d42997845351bcff0a5834b9316df5f7386f09c68d2ab2ae87f6
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
73c935d570b0 nginx:latest "/docker-entrypoint.…" 23 seconds ago Up 22 seconds my_nginx
2)检查network interface
[root@tango-01 ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:6c:5d:b1 brd ff:ff:ff:ff:ff:ff
inet 192.168.112.10/24 brd 192.168.112.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::db02:8b2d:162f:fae8/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000
link/ether 52:54:00:10:a0:78 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 1000
link/ether 52:54:00:10:a0:78 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:85:7c:0c:cd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:85ff:fe7c:ccd/64 scope link
valid_lft forever preferred_lft forever
Overlay网络模式是在多个Docker主机中实现分布式网络,这种网络是在主机网络之上,允许跨容器之间的交互。Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
如图所示,容器使用overlay network实现两个跨主机通信的时候,overlay虚拟出一个网络veth1如ip地址为172.17.0.101。在overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器eth33这个地址,最终通过路由和交换,到达另一个服务器的ip地址。
要实现overlay网络,需要有一个服务发现,比如consul。如下图所示,Consul会定义一个ip地址池,比如10.0.2.0/24,容器的ip地址会从中获取。获取IP以后,容器会通过ens33来进行通信,这样就实现跨主机的通信。
1)环境准备
Hostname | 系统 | IP |
---|---|---|
tango-centos01 | Centos_x86_64 | 192.168.112.101 |
tango-centos02 | Centos_x86_64 | 192.168.112.102 |
2)系统配置
[root@tango-centos01 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@tango-centos02 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@tango-centos01 ~]# docker -v
Docker version 19.03.13, build 4484c46d9d
[root@tango-centos02 ~]# docker -v
Docker version 19.03.13, build 4484c46d9d
3)修改docker配置并重启
在docker daemon的配置文件/lib/systemd/system/docker.service添加cluster-store和cluster-advertise:cluster-store为consul 的地址、cluster-advertise为consul自己连接的地址
[root@tango-centos01 ~]# vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --cluster-store=consul://192.168.112.101:8500 --cluster-advertise=ens33:2376 --insecure-registry=0.0.0.0/0
[root@tango-centos01 ~]# vi /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --cluster-store=consul://192.168.112.101:8500 --cluster-advertise=ens33:2376 --insecure-registry=0.0.0.0/0
修改完后,需要重启docker
[root@tango-centos01 ~]# systemctl daemon-reload
[root@tango-centos01 ~]# systemctl restart docker
[root@tango-centos01 ~]# systemctl status docker
â— docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-10-14 09:22:23 CST; 32s ago
Docs: https://docs.docker.com
Main PID: 1533 (dockerd)
Memory: 37.7M
CGroup: /system.slice/docker.service
└─1533 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --cluster-store=consul://192.168.112.101:8500 --cluster-advertise=ens33:2376 --insecure-registry=0.0.0.0/0
[root@tango-centos02 ~]# systemctl daemon-reload
[root@tango-centos02 ~]# systemctl restart docker
[root@tango-centos02 ~]# systemctl status docker
â— docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-10-14 09:24:01 CST; 5s ago
Docs: https://docs.docker.com
Main PID: 1332 (dockerd)
Memory: 43.3M
CGroup: /system.slice/docker.service
└─1332 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --cluster-store=consul://192.168.112.102:8500 --cluster-advertise=ens33:2376 --insecure-registry=0.0.0.0/0
4)在tango-centos01主机上创建一个consul
[root@tango-centos01 ~]# docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server –bootstrap
[root@tango-centos01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04e635fbc613 progrium/consul "/bin/start -server …" 36 seconds ago Up 9 seconds 53/tcp, 53/udp, 8300-8302/tcp, 8400/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp consul
创建完后通过浏览器访问192.168.112.101:8500,可以看到这两台会自动注册上来,这样的话这两个主机之间就会进行通信。
5)在tango-centos01主机上创建一个overlay网络
[root@tango-centos01 ~]# docker network create -d overlay --subnet=10.0.2.1/24 ov_net1
2a60c89e7b700133e2c4f3af25965aef32a32734eaac53bf1512ef9b7ba3b9bb
[root@tango-centos01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
bbb3e163e60c bridge bridge local
839aec547da7 host host local
bc52bc1ec263 none null local
2a60c89e7b70 ov_net1 overlay global
第二台主机会自动进行通步,是因为信息存到consul中会自动同步信息
[root@tango-centos02 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f7f52367c834 bridge bridge local
0ab8d42e5106 host host local
11c97f656489 none null local
2a60c89e7b70 ov_net1 overlay global
6)创建一个使用overlay网络的容器
[root@tango-centos01 ~]# docker run -itd --name bbox1 --network ov_net1 busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
df8698476c65: Pull complete
Digest: sha256:7c223a633b51ef785537d73fbe549655089bdaa8a1cd25acf2de02bd0cdc3364
Status: Downloaded newer image for busybox:latest
36ee2a4181f443a7f7abb61afff75eb1d07e89838c0ac766b25e8946e0fd993d [root@tango-centos01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36ee2a4181f4 busybox "sh" 17 seconds ago Up 15 seconds bbox1
登陆进去查看ip地址是否是10.0.2.0的网段
[root@tango-centos01 ~]# docker exec -it bbox1 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:00:02:02
inet addr:10.0.2.2 Bcast:10.0.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1128 (1.1 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
它也具备一个nat网络模式,可以访问互联网
/ # ping www.baidu.com
PING www.baidu.com (14.215.177.39): 56 data bytes
64 bytes from 14.215.177.39: seq=0 ttl=127 time=37.144 ms
64 bytes from 14.215.177.39: seq=1 ttl=127 time=65.292 ms
64 bytes from 14.215.177.39: seq=2 ttl=127 time=93.848 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 37.144/65.428/93.848 ms
7)在tango-centos02上面同样创建一个overlay网路的容器。
[root@tango-centos02 ~]# docker run -itd --name bbox2 --network ov_net1 busybox
beac016541311fdb06cf2c89360bf7202f615e8e65ab974f299093cd35f99c37
[root@tango-centos02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
beac01654131 busybox "sh" 10 seconds ago Up 7 seconds bbox2
[root@tango-centos02 ~]# docker exec -it bbox2 sh
查看ip地址
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:00:02:03
inet addr:10.0.2.3 Bcast:10.0.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1128 (1.1 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
8)查看tango-centos01和tango-centos02的容器网络是否可以互通
/ # ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=64 time=0.687 ms
64 bytes from 10.0.2.2: seq=1 ttl=64 time=0.415 ms
64 bytes from 10.0.2.2: seq=2 ttl=64 time=0.360 ms
^C
--- 10.0.2.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.360/0.487/0.687 ms
/ # ping bbox1
PING bbox1 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=64 time=0.459 ms
64 bytes from 10.0.2.2: seq=1 ttl=64 time=0.397 ms
64 bytes from 10.0.2.2: seq=2 ttl=64 time=0.363 ms
^C
--- bbox1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.363/0.406/0.459 ms
到此,两台主机间的容器可以直接连通,通过overlay network网络模式实现容器跨主机间的通信。
有些应用需要直接连接到物理网络,这个时候可以使用macvlan为每个容器的 虚拟网络接口分配MAC地址。Macvlan 的优点是性能优异,因为无须端口映射或者额外桥接,可以直接通过主机接口(或者子接口)访问容器接口。但是,Macvlan 的缺点是需要将主机网卡(NIC)设置为混杂模式(Promiscuous Mode),这在大部分公有云平台上是不允许的。
如上图描述了Docker macvlan使用场景,假设物理网络上配置了两个VLAN:VLAN 100(10.0.2.0/24)和 VLAN 200(192.168.112.0/24)。我们希望创建一个新的容器接入VLAN 100,可以按照以下步骤进行配置:
1)创建一个名为 macvlan100 的 Macvlan 网络,该网络会连接到 VLAN 100
docker network create -d macvlan \
--subnet=10.0.2.0/24 \
--ip-range=10.0.2.0/25 \
--gateway=10.0.2.1 \
-o parent=eth0.100 \
macvlan100
该命令会创建 macvlan100 的网络以及 eth0.100子接口
2)创建容器部署到该网络中
docker container run -d --name Container1 --network macvlan100
这样就创建了基于macvlan网络模式的容器
如图以相同macvlan网络之间的容器跨主机通信为例,主要流程如下:
-
主机host1和host2分别创建macvlan网络,并创建子网段
-
容器内的eth0是由macvlan所在物理接口ens33创建的一个逻辑网口
-
当host1向host2发送数据包时,容器内的子网网卡会向它的网关发送一个mac地址请求
-
虚拟网关接受请求后会先查询本地的路由表查找发送目标,如果找不到它会转交给ens33来发ARP送广播,来获取目标IP地址是多少
-
host2收到ARP广播后它会查找本地是否存在目标IP地址,通过IP来获取指定IP的mac地址
-
获取mac地址后它会转发给宿主机host2的ens33网卡,然后通过宿主机网卡发送给host1的外网网卡,然后再转给容器内网卡
-
具体配置过程如下:
1)设置支持promisc
使用 tango-centos01和 tango-centos02上单独的网卡 ens33创建 macvlan。为保证多个 MAC地址的网络包都可以从 ens33通过,我们需要打开网卡的混杂模式(promisc)
[root@tango-centos01 ~]# ip link show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:92:e8:12 brd ff:ff:ff:ff:ff:ff
[root@tango-centos01 ~]# ip link set ens33 promisc on
[root@tango-centos01 ~]# ip link show ens33
2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:92:e8:12 brd ff:ff:ff:ff:ff:ff
[root@tango-centos02 ~]# ip link show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:37:f9:17 brd ff:ff:ff:ff:ff:ff
[root@tango-centos02 ~]# ip link set ens33 promisc on
[root@tango-centos02 ~]# ip link show ens33
2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:37:f9:17 brd ff:ff:ff:ff:ff:ff
2)创建macvlan网络MAC1
[root@tango-centos01 ~]# docker network create -d macvlan --subnet=10.0.2.0/24 --gateway=10.0.2.1 -o parent=ens33 MAC1
00b0a3987b677332b27a46bd612b45f923e4495b5d8ef4946d138377e7de8136
[root@tango-centos02 ~]# docker network create -d macvlan --subnet=10.0.2.0/24 --gateway=10.0.2.1 -o parent=ens33 MAC1
cbe5e638f842e656cc7b964395b5d8efa15a7511f6672b28fdfc6d711a25ffd6
注:与其他网络不同,docker 不会为 macvlan 创建网关,这里的网关应该是真实存在的,否则容器无法路由。
3)在 tango-centos01中运行容器 bbox1 并连接到MAC1
[root@tango-centos01 ~]# docker run -itd --name bbox1 --ip=10.0.2.10 --network MAC1 busybox
54fc97a5f3f4bc89b00f3602315161d6ab1bb19e67cf4564fdce944d23d4e27d
[root@tango-centos01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
54fc97a5f3f4 busybox "sh" 11 seconds ago Up 9 seconds bbox1
由于tango-centos01中的MAC1与tango-centos02中的MAC2本质上是独立的,为了避免自动分配造成IP冲突,我们最好通过 --ip 指定bbox1地址为10.0.2.10
4)在 tango-centos02中运行容器 bbox2,指定IP为10.0.2.11
[root@tango-centos02 ~]# docker run -itd --name bbox2 --ip=10.0.2.11 --network MAC1 busybox
26e37e629b0cd9a492a672a246de1004402570dfe994ad522cb58dad29ed3bb7
5)验证bbox1和bbox2的连通性
[root@tango-centos02 ~]# docker exec -it bbox2 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:00:02:0B
inet addr:10.0.2.11 Bcast:10.0.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:15 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:900 (900.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # ping 10.0.2.10
PING 10.0.2.10 (10.0.2.10): 56 data bytes
64 bytes from 10.0.2.10: seq=0 ttl=64 time=0.606 ms
64 bytes from 10.0.2.10: seq=1 ttl=64 time=0.288 ms
64 bytes from 10.0.2.10: seq=2 ttl=64 time=0.281 ms
^C
--- 10.0.2.10 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.281/0.391/0.606 ms
/ #
/ # ping bbox1
^C
/ #
注:bbox2能够ping到bbox1的I地址,但是无法解析”bbox1”的主机名。docker没有为macvlan 提供DNS服务,这点与overlay网络是不同的。
这个模式和前几个不同,在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器容器只有lo回环网络,没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等。
[root@tango-01 ~]# docker run -it --network=none busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/
2、Docker容器互联
Docker允许将同一个主机内多个容器连接在一起,共享连接信息。Docker连接会创建一个父子关系,其中父容器可以看到子容器的信息。
1)先创建一个新的 Docker网络net-test01
[root@tango-01 ~]# docker network create -d bridge net-test01
b95c87bb1d270e2df82d4397840e3a5fbf72a99c6a78cbdb8ed04a3a643467db
[root@tango-01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
56130a7ca84a bridge bridge local
7bbafde1931d host host local
b95c87bb1d27 net-test01 bridge local
56440e57a748 none null local
2)运行一个容器并连接到新建的 net-test01网络
[root@tango-01 ~]# docker run -itd --name test1 --network net-test01 ubuntu /bin/bash
058dbea3d7ba94d15f32b0d453362d4f24db32849a39f7eadecdb229c91173ac
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
058dbea3d7ba ubuntu "/bin/bash" 2 minutes ago Up 2 minutes test1
打开新的终端,再运行一个容器并加入到net-test01网络:
[root@tango-01 ~]# docker run -itd --name test2 --network net-test01 ubuntu /bin/bash
22c64450cb027ee3575e170eac2fda7632a84ed515149c21bc4d33af4fad783c
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22c64450cb02 ubuntu "/bin/bash" About a minute ago Up About a minute test2
058dbea3d7ba ubuntu "/bin/bash" 2 minutes ago Up 2 minutes test1
3)下面通过ping来证明test1容器和test2容器建立了互联关系
如果test1、test2容器内中无ping命令,则在容器内执行以下命令安装 ping:
apt-get update
apt install iputils-ping
在 test1 容器输入以下命令:
[root@tango-01 ~]# docker exec -it test1 /bin/bash
root@058dbea3d7ba:/# apt-get update
root@058dbea3d7ba:/# apt install iputils-ping
root@22c64450cb02:/# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from 22c64450cb02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from 22c64450cb02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from 22c64450cb02 (172.18.0.3): icmp_seq=3 ttl=64 time=0.033 ms
^C
--- test2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.029/0.030/0.033/0.001 ms
root@22c64450cb02:/#
同理在test2容器也会成功连接到test1
跨主机间的容器通信可以通过Overlay和Macvlan模式实现,参考内容:
-
Overlay网络实现跨主机通信
-
相同macvlan网络之间的容器通信
参考资料:
-
https://docs.docker.com/network/
-
http://www.dockone.io/article/2717
-
https://www.cnblogs.com/bakari/p/10893589.html