目录
1 Docker的网络模式介绍
1.1 Docker 的四种网络模式介绍
2 Docker的原生Bridge网络模式
2.1 Bridge网络模式的原理
2.2 如何查看docker网络接口
2.3 原生Bridge 网络模式
2.4 docker 网络的地址伪装
2.4.1 切换默认火墙
2.4.2 查询火墙默认放通规则
2.5 容器之间使用IP通讯的不稳定性
3 Docker的原生网络host
3.1 hosts网络的用法与介绍
3.2 示例
4 docker 原生网络none
4.1 Docker none 网络的介绍
4.2 用法示例
5 docker的自定义网络
5.1 自定义模式的三种驱动
5.2 自定义桥接网络
5.2.1 自定义桥接网络的介绍与原生网路的区别
5.2.2 基础用法示例
5.2.3 自定义地址和网关
5.3 容器间不同网段进行通信
5.3.1 剖析实现方式
5.3.2 用法示例
5.4 joined容器网络
5.4.1 joined 容器网络的介绍
5.4.2 joined 容器网络实现多容器耦合度
5.4.3 joined容器的基础示例
5.4.3 使用容器的耦合度部署轻量级项目phpmysqladmin
1 Docker的网络模式介绍
1.1 Docker 的四种网络模式介绍
当你安装docker时,它会自动创建三个网络,可使用如下命令查看:
[root@node-3 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
ac8b38642359 bridge bridge local
df54e2e2198f host host local
6634c3ba86ec none null local
host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。使用--net=host
指定。
Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。使用 --net=container:NAMEorID
指定。
None:该模式关闭了容器的网络功能。使用 --net=none
指定。
Bridge:此模式会为每一个容器分配、设置IP等。使用 --net=bridge
指定,默认设置。
2 Docker的原生Bridge网络模式
2.1 Bridge网络模式的原理
安装docker时会自动创建一个docker0网桥,运行容器时,可以使用docker run --network=<NETWORK>
选项指定容器应连接到哪个网络,否则Docker守护程序默认将容器连接到docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
Docker 随机分配一个本地未占用的私有网段( 在 RFC1918 中定义) 中的一个地址给docker0 接口。 此后启动的容器内的网口也会自动分配一个同一网段的地址。docker0的IP地址则为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中(bridge模式示意图如下图所示)。
- bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。
- 容器通过宿主机的NAT规则后可以访问外网
2.2 如何查看docker网络接口
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口
[root@node-3 ~]# ip link show type bridge
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:d1:db:ed:d8 brd ff:ff:ff:ff:ff:ff
veth36b6834 为容器使用的网卡
[root@node-3 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d1dbedd8 no veth36b6834
2.3 原生Bridge 网络模式
# 运行并进入容器
ocker-page]# docker run -it --name=webserver --network bridge busybox
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:17 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2282 (2.2 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# 进入到容器内部 ,尝试下网络是否可通
/ # ping www.baidu.com
PING www.baidu.com (36.155.132.3): 56 data bytes
64 bytes from 36.155.132.3: seq=0 ttl=127 time=28.658 ms
64 bytes from 36.155.132.3: seq=1 ttl=127 time=28.169 ms
^C
--- www.baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 28.169/28.413/28.658 ms# 查看网关为172.17.0.1 的这个网关
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0# 宿主机查看docker0网卡发现正是容器的网关
# 也就是说容器是通过宿主机的docker0网卡进行通信的
# 并且在系统内部还需要打开forward---也就是路由转发功能
# 通过docker0通过地址伪装使用的是eth0与外界通讯
[root@node-3 ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255inet6 fe80::42:d1ff:fedb:edd8 prefixlen 64 scopeid 0x20<link>ether 02:42:d1:db:ed:d8 txqueuelen 0 (Ethernet)RX packets 6 bytes 342 (342.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 12 bytes 1254 (1.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.239.30 netmask 255.255.255.0 broadcast 192.168.239.255inet6 fe80::d356:dc77:335a:c6b1 prefixlen 64 scopeid 0x20<link>ether 00:0c:29:32:ef:f1 txqueuelen 1000 (Ethernet)RX packets 216892 bytes 304516931 (290.4 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 38628 bytes 3556437 (3.3 MiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Local Loopback)RX packets 17 bytes 2045 (1.9 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 17 bytes 2045 (1.9 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0veth36b6834: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet6 fe80::80d2:77ff:fe7b:b173 prefixlen 64 scopeid 0x20<link>ether 82:d2:77:7b:b1:73 txqueuelen 0 (Ethernet)RX packets 6 bytes 426 (426.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 30 bytes 3286 (3.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.4 docker 网络的地址伪装
在 Docker 中,网络地址转换(Network Address Translation, NAT)或地址伪装
(IP Masquerading)是一种常见的网络配置,用于让容器内的应用能够通过宿主机的 IP 地址访问外部网络。这种配置通常是自动完成的,不需要用户显式设置。
在Rocky 9 中默认使用的是nrtable
2.4.1 切换默认火墙
可以切换成默认的火墙iptables 看得更直观一些
[root@node-3 ~]# grubby --update-kernel ALL --args iptables=true
# 重启系统
[root@node-3 ~]# reboot
2.4.2 查询火墙默认放通规则
重启过后查看火墙规则POSTROUTING
[root@node-3 ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER 0 -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)
target prot opt source destination Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER 0 -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE 0 -- 172.17.0.0/16 0.0.0.0/0 Chain DOCKER (2 references)
target prot opt source destination
RETURN 0 -- 0.0.0.0/0 0.0.0.0/0
2.5 容器之间使用IP通讯的不稳定性
# 开启一个webserver1 容器~]# docker run -it --name=webserver1 --network bridge busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:18 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2352 (2.2 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# 重新开启一个容器webserver2~]# docker run -it --name=webserver2 --network bridge busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:12 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1552 (1.5 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
发现网络分配的IP地址也是不一样的,但是等重新进入这个容器的时候会重新分配IP地址,这样的会导致IP地址及其不稳定,比如说停掉两个容器,再次开启容器,IP地址是按照顺序划分的,所以那个容器先开启就会分配比较前面的地址如先开 webserver2 就会将0.2分配给他,0.3就会分配给webserver。所以容器之间需要 通过主机名进行通信,不通过IP地址通信,因为这是个及其不稳定的东西
# webserver 容器
/ # ping webserver2
ping: bad address 'webserver2'
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.299 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.096 ms# webserver2 容器
/ # ping webserver
ping: bad address 'webserver'
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.063 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.099 ms
3 Docker的原生网络host
3.1 hosts网络的用法与介绍
- host网络模式需要在容器创建时指定 --network=host
- host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。Host模式示意图如下所示:
3.2 示例
docker-page]# docker run -it --name=test --network host busybox:latest
/ #
/ # ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:D1:DB:ED:D8 inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0inet6 addr: fe80::42:d1ff:fedb:edd8/64 Scope:LinkUP BROADCAST MULTICAST MTU:1500 Metric:1RX packets:6 errors:0 dropped:0 overruns:0 frame:0TX packets:12 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:342 (342.0 B) TX bytes:1254 (1.2 KiB)eth0 Link encap:Ethernet HWaddr 00:0C:29:32:EF:F1 inet addr:192.168.239.30 Bcast:192.168.239.255 Mask:255.255.255.0inet6 addr: fe80::d356:dc77:335a:c6b1/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:218750 errors:0 dropped:0 overruns:0 frame:0TX packets:39677 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:304792534 (290.6 MiB) TX bytes:3704615 (3.5 MiB)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:17 errors:0 dropped:0 overruns:0 frame:0TX packets:17 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:2045 (1.9 KiB) TX bytes:2045 (1.9 KiB)
4 docker 原生网络none
4.1 Docker none 网络的介绍
- none模式是指禁用网络功能,只有lo接口,在容器创建时使用
- --network=none指定
4.2 用法示例
[root@node-3 ~]# docker run --name=test3 -it --network=none busybox
/ # ifconfig
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
5 docker的自定义网络
5.1 自定义模式的三种驱动
自定义网络模式,docker提供了三种自定义网络驱动:
- bridge
- overlay
- macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,
overlay和macvlan是用于创建跨主机网络
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。
5.2 自定义桥接网络
5.2.1 自定义桥接网络的介绍与原生网路的区别
有了桥接网络为什么还需要自定义桥接网络了呢?
这是因为在默认的原生网络中在容器间是不能够使用主机名进行通信的,只能通过IP进行通讯,又因为docker网络的特殊性,哪个镜像先开启就会默认将先开启的镜像分配比较靠前的IP地址。所以IP地址会随着容器的重启重新分配,这是个及其不稳定的因数。所以为了解决这样的不稳定因素,可以使用自定义桥接网络
- 原生桥接网络不允许通过主机名来进行容器间的通讯
- 自定义桥接网络允许通过主机名进行容器间的通讯
5.2.2 基础用法示例
[root@node-3 ~]# docker run -it --name=test --network mynet1 busybox
/ # ifconfig
eth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:29 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:4034 (3.9 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# 重新开启一个会话在新建一个容器 命名为test2
[root@node-3 ~]# docker run -it --name=test2 --network=mynet1 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:00:03 inet addr:172.18.0.3 Bcast:172.18.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:25 errors:0 dropped:0 overruns:0 frame:0TX packets:6 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2778 (2.7 KiB) TX bytes:476 (476.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:4 errors:0 dropped:0 overruns:0 frame:0TX packets:4 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:220 (220.0 B) TX bytes:220 (220.0 B)# 在test 容器中
/ # ping test2
PING test2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.167 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.094 ms
# 在test2 容器中
/ # ping test
PING test (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.187 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.098 ms
在定义自定义桥接之后这里多了一张网卡
- docker引擎在分配ip时时根据容器启动顺序分配到,谁先启动谁用,是动态变更的
- 多容器互访用ip很显然不是很靠谱,那么多容器访问一般使用容器的名字访问更加稳定
- docker原生网络是不支持dns解析的,自定义网络中内嵌了dns
5.2.3 自定义地址和网关
自定义桥接网络模式还可以自定义地址和网关
~]# docker network create mynet2 --subnet 192.168.0.0/24 --gateway 192.168.0.100
84c8ed007ff557092ec8bd2b3e9030f141a95e0eaca6168d3d8843579b369a40~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
975b1b70061c bridge bridge local
df54e2e2198f host host local
32ab6318b6b4 mynet1 bridge local
84c8ed007ff5 mynet2 bridge local
6634c3ba86ec none null local~]# docker network inspect mynet2
[{"Name": "mynet2","Id": "84c8ed007ff557092ec8bd2b3e9030f141a95e0eaca6168d3d8843579b369a40","Created": "2024-08-29T16:55:33.479427177+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/24","Gateway": "192.168.0.100"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {},"Options": {},"Labels": {}}
]~]# docker run -it --name=test3 --network=mynet2 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:00:01 inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:29 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:4034 (3.9 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)/ # ping www.baidu.com
PING www.baidu.com (36.155.132.76): 56 data bytes
64 bytes from 36.155.132.76: seq=0 ttl=127 time=26.433 ms
64 bytes from 36.155.132.76: seq=1 ttl=127 time=26.306 ms2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 26.306/26.369/26.433 ms
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 0 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
但这也仅仅是同一块网卡进行通信,假如说需要所有的网卡都能保持通信需要以下操作
5.3 容器间不同网段进行通信
5.3.1 剖析实现方式
5.3.2 用法示例
先删除之前定义的容器与自定义的网络
~]# docker ps -a | awk -F " " '{if(NR>1)print $1}'
41dbfa7d6522
83ceaaf0605c
2f01f09d280d~]# docker rm -f `docker ps -a | awk -F " " '{if(NR>1)print $1}'`
41dbfa7d6522
83ceaaf0605c
2f01f09d280d[root@node-3 ~]# docker network rm mynet1
mynet1
[root@node-3 ~]# docker network rm mynet2
mynet2
[root@node-3 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
975b1b70061c bridge bridge local
df54e2e2198f host host local
6634c3ba86ec none null local
重新创建网络并命名指定为bridge网络
[root@node-3 ~]# docker network create mynet1 -d bridge
55e6dc0e31eec49e794b58a122dbd402fd6f68586bb10359acc4243af074cdd3[root@node-3 ~]# docker network create mynet2 -d bridge
d4f42d8c89f8a5c951a1b39607db1ea8467c7803f6a637b5d6010067776a9c11[root@node-3 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
975b1b70061c bridge bridge local
df54e2e2198f host host local
55e6dc0e31ee mynet1 bridge local
d4f42d8c89f8 mynet2 bridge local
6634c3ba86ec none null local
查看容器的火墙规则 ,发现在所有的容器之间已经禁止通讯了
[root@node-3 ~]# iptables -nLDOCKER-ISOLATION-STAGE-2 的作用
DOCKER-ISOLATION-STAGE-2 链主要用于处理容器之间的网络通信,
特别是在容器隔离方面。当容器之间进行通信时,数据包会经过这个链,
以便根据 Docker 的网络策略进行过滤。
启动网卡容器
# 定义 test1容器 使用mynet1 网卡~]# docker run -it --name=test1 --network=mynet1 busybox/ # ifconfig
eth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:37 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:5334 (5.2 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# 定义 test2容器 使用mynet2 网卡~]# docker run -it --name=test2 --network=mynet2 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:13:00:02 inet addr:172.19.0.2 Bcast:172.19.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:16 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1850 (1.8 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# 发现都是不能通讯的
/ # ping test2
ping: bad address 'test2'/ # ping test1
ping: bad address 'test1'
# 在test1容器上
# ctrl + pq 退出容器不停止
/ # read escape sequence# 通过 connect 指定给test1 分配一个网卡为mynet2 的网卡,
# 使得两个容器使用mynet2这张网卡在容器之间进行通信[root@node-3 ~]# docker network connect mynet2 test1
[root@node-3 ~]# docker attach test1 / # ifconfig
eth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:44 errors:0 dropped:0 overruns:0 frame:0TX packets:4 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:5908 (5.7 KiB) TX bytes:214 (214.0 B)eth1 Link encap:Ethernet HWaddr 02:42:AC:13:00:03 inet addr:172.19.0.3 Bcast:172.19.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:16 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2092 (2.0 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:4 errors:0 dropped:0 overruns:0 frame:0TX packets:4 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:354 (354.0 B) TX bytes:354 (354.0 B)
5.4 joined容器网络
5.4.1 joined 容器网络的介绍
- Joined容器一种较为特别的网络模式,在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名)
- 处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。
5.4.2 joined 容器网络实现多容器耦合度
~]# docker rm -f `docker ps -a | awk 'BGING{FS=" "}{if(NR>1) print $1}'`
0167f3278e99
29bd186868ee~]# docker run -it --name=web1 --network=mynet1 busybox:latest / # ifconfig
eth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:18 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2352 (2.2 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)# ctrl + pq 不停止退出
/ # read escape sequence# 使用container参数引用web1,相当于web2引用了web1的网卡~]# docker run -it --name=web2 --network container:web1 busybox# 发现web1 web2 使用的都是同一个网络172.18.0.2
/ # ifconfig
eth0 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.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:22 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:2632 (2.5 KiB) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
5.4.3 joined容器的基础示例
在使用joined容器网络模式中想要容器之间访问是通过回环接口去访问的,以下是一个实例
~]# docker run -it --name=nginx -d --network mynet1 -p 80:80 nginx:latest
4611fe46291f0f2c891706eb53d5b5ccc85cbe057bf0756ee8df5c2c105d5651[root@node-3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4611fe46291f nginx:latest "/docker-entrypoint.…" 6 seconds ago Up 6 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp nginx~]# docker run -it --name=centos --network container:nginx centos:7 # 进入了容器的内部,访问本地的localhost 环回发现是可以通讯的
# 也就是在joined容器网络模式中容器间访问是通过环回进行数据传输
[root@4611fe46291f /]# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
我们能发现在使用joined网络模式是可以通过本地环回去访问别的容器,但这有什么用呢?一般来说在业务的耦合度比较高的时候这种模式用得非常频繁,以下就是一个例子
5.4.3 使用容器的耦合度部署轻量级项目phpmysqladmin
phpMyAdmin 是一个流行的 Web 应用程序,用于管理 MySQL 数据库。可以使用 Docker 容易地部署 phpMyAdmin,这样就可以通过 Web 界面来管理 MySQL 数据库。
~]# docker run -d --name=mysqladmin --network mynet1 \
> -e PMA_ARBITRARY=1 \
> -p 80:80 phpmyadmin:latest
64499c461a4682e4819f1c93ad62dce87541ba255882ca518ddf864a5f862d67~]# docker run -d --name=mysql --network container:mysqladmin \
> -e MYSQL_ROOT_PASSWORD='shuyan' mysql:5.7
cd209810d30d5b8c05207a3e5063d201e41312b4e18356fdc674fda1ef725ece[root@node-3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd209810d30d mysql:5.7 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds mysql
64499c461a46 phpmyadmin:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp mysqladmin
浏览器打开即可就可以使用了
其实这有一个疑问为什么MySQL不需要暴露端口呢,而为什么没有暴露端口可以进行通讯呢?是因为在容器内他已经开放有端口了,并且因为joined网络模式的原因,他们处于同一网络中并且使用本地环回进行通讯,所以phpMySQLadmin可以对MySQL进行管理
也可以进入MySQL容器操作
[root@node-3 ~]# docker exec -it mysql bash