背景说明
容器网络实质上也是由Docker为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块,Docker默认提供了多种网络模式。
[root@vm2 ~]# docker info -f {{.Plugins.Network}}
[bridge host ipvlan macvlan null overlay]
[root@vm2 ~]#
解决方案
官方文档
https://docs.docker.com/network/
模式查看
Docker安装的时候默认会创建三个不同的网络。
[root@vm2 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
801380e310dd bridge bridge local
4a5006c650f6 host host local
a027c870d158 none null local
[root@vm2 ~]#
无网模式
通过参数—network=none指定
[root@vm2 ~]# docker run --network=none -it centos
[root@bc43c569cfa7 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
[root@bc43c569cfa7 /]#
[root@bc43c569cfa7 /]# ping 192.168.184.142
connect: Network is unreachable
采用此种模式,容器内部只能使用loopback网络设备,无法和其他设备进行网络通信,此时容器是一个封闭容器,不参与网络通信可以有效保证容器的安全性。
后期可以通过相关命令将容器添加到已有的自定义网络中
主机模式
通过参数—network=host指定,使用主机网络模式时,容器网络将直接绑定到主机网络上,没有网络隔离,但是其他文件系统、进程列表等均进行了隔离,外界可以直接访问容器。
容器复用主机的网络命名空间,其他独立与主机的。
[root@vm2 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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 group default qlen 1000
link/ether 00:0c:29:43:2c:2d brd ff:ff:ff:ff:ff:ff
inet 192.168.184.142/24 brd 192.168.184.255 scope global noprefixroute dynamic ens33
valid_lft 1616sec preferred_lft 1616sec
inet6 fe80::1d72:8c06:652b:cc91/64 scope link tentative noprefixroute dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::2452:200d:395f:968a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:e2:2f:29:69 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
[root@vm2 ~]# ip route
default via 192.168.184.2 dev ens33 proto dhcp metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.184.0/24 dev ens33 proto kernel scope link src 192.168.184.142 metric 100
[root@vm2 ~]# docker run -it --network=host centos /bin/bash
[root@vm2 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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 group default qlen 1000
link/ether 00:0c:29:43:2c:2d brd ff:ff:ff:ff:ff:ff
inet 192.168.184.142/24 brd 192.168.184.255 scope global dynamic noprefixroute ens33
valid_lft 1583sec preferred_lft 1583sec
inet6 fe80::1d72:8c06:652b:cc91/64 scope link dadfailed tentative noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::2452:200d:395f:968a/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:e2:2f:29:69 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
[root@vm2 /]# ip route
default via 192.168.184.2 dev ens33 proto dhcp metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.184.0/24 dev ens33 proto kernel scope link src 192.168.184.142 metric 100
[root@vm2 /]#
分析如上命令主机网络地址:192.168.184.142/24,容器网络地址:192.168.184.142/24 注意进入容器后的命令前缀为: [root@vm2 /]# 主机和容器共享网络设备和路由表
尝试启动一个Nginx容器服务
[root@vm2 ~]# docker run -d nginx
54a8cfcde386d48f61e3ba7bed0cd61e3371c3e24d7ebf6fec11c6c51ff0388a
[root@vm2 ~]#
[root@vm2 ~]# curl http://localhost:80
curl: (7) Failed connect to localhost:80; Connection refused
[root@vm2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
54a8cfcde386 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 80/tcp awesome_brattain
[root@vm2 ~]# docker exec 54a8 /bin/bash
[root@vm2 ~]# docker exec -it 54a8 /bin/bash
root@54a8cfcde386:/# curl http://localhost:80
<!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>
root@54a8cfcde386:/#
端口没有进行映射时,无法通过主机IP进行访问,容器内部可以访问其端口
指定端口映射启动Nginx容器服务
[root@vm2 ~]# docker run -d -p 8080:80 nginx
ca4c47c41f4015f9150400a60d4460db3ed65d032197e3a72b5d903580ec8e46
[root@vm2 ~]#
[root@vm2 ~]# curl http://localhost:8080
<!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>
[root@vm2 ~]#
指定端口映射可以正常访问容器服务
容器模式
容器模式并不是一个标准的容器网络类型,相当于多个容器共用一个网络命名空间,提供给一个网卡和docker0网桥进行通信。
创建docker1容器并查看网络地址
[root@vm2 ~]# docker run -it -d --name docker1 centos
96af1b7a75efab993b224d02a82de610eac0aa511ef06b146da16f9d4a13fc1a
[root@vm2 ~]# docker exec -it docker1 /bin/bash
[root@96af1b7a75ef /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@96af1b7a75ef /]#
[root@96af1b7a75ef /]# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.4
[root@96af1b7a75ef /]#
创建docker2容器
[root@vm2 ~]# docker run -it --network=container:docker1 centos
[root@96af1b7a75ef /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@96af1b7a75ef /]#
[root@96af1b7a75ef /]# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.4
[root@96af1b7a75ef /]#
可以看到docker1和docker2使用的是同一个网络地址。docker2创建时不会创建新的网卡和命名空间复用docker1,并且共享端口范围,两个容器之间的网络交互使用lo回环设备进行交互。
网桥模式
通过参数—network=bridge指定,这里Docker的默认模式,在此模式下各容器拥有独立的网络空间,可以互相通过网络地址访问。
macvlan
MacVLAN使得容器网络和主机网络在同一个广播域,容器等同于真实的物理主机,是一种跨主机的网络通讯方案。
overlay
也叫覆盖网络或扁平化网络,容器之间可以直接通过容器网络地址进行访问。