Docker网络功能
容器互联
常用于用于一个主机间创建的容器之间的联动,由于每次删除创建新的容器,容器的IP地址将不是固定的,所以使用容器互联可以方便容器之间的互相调用,以及减少人工成本。
容器互联是在创建容器时使用--link container_name
,容器创建成功后将会在容器内的hosts内添加解析记录,
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d --link volume-server 948a57f42cb9
872d04735de6e64cf29c50a7f82cb5ffa6f45c9e6ecbb89c1373a70076481c0d
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it 872d04735de6e64cf29c50a7f82cb5ffa6f45c9e6ecbb89c1373a70076481c0d bash
root@872d04735de6:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 volume-server 212a49d69bcb
172.17.0.4 872d04735de6
root@872d04735de6:/# ping volume-server
PING volume-server (172.17.0.2) 56(84) bytes of data.
64 bytes from volume-server (172.17.0.2): icmp_seq=1 ttl=64 time=0.149 ms
64 bytes from volume-server (172.17.0.2): icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from volume-server (172.17.0.2): icmp_seq=3 ttl=64 time=0.049 ms
将link的容器删除后将无法进入,提示以下报错
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it 872d04735de6 bash
Error response from daemon: Cannot link to a non running container: /volume-server AS /nervous_wozniak/volume-server
docker 网络类型
使用docker network ls
可以列出以下默认的网络类型,分别为bridge,host和null
root@ubuntu1804-server:/data/webapps/myapp# docker network ls
NETWORK ID NAME DRIVER SCOPE
7f05725b5e55 bridge bridge local
5b5d14ec36c7 host host local
94c745143679 none null local
bridge
docker 的默认模式即不指定任何模式就是 bridge 模式,也是使用比较多的模式,此模式创建的容器会为每一个容器分配自己的网络 IP 等信息,并将容器连接到一个虚拟网桥与外界通信。
docker创建荣起的时候如果不指定网络类型,则默认网络类型为bridge,通过 -p选项指定要暴露于的网络端口,而其中是使用iptables将原本要访问物理网卡的端口,使用nat将其转换给容器内部
host
容器的网络信息与宿主机的网络信息相同。容器如果使用host网络类型则不会生成防火墙规则,而是类似于透传功能将请求直接传递给容器内部,容器内的所有端口将会显示在宿主机上。此时不能使用-p选项,否则报错。
通过iptables可以看出没有8080的端口,而通过ss命令可以观察到8080端口。
root@ubuntu1804-server:/data/webapps/myapp# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6012 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 128 [::1]:6012 [::]:*
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d --net=host 06d988b898c7
8681c500e192f81a538d9247d22e68f5ceb689fba9223355f5feb12b1bcba703
root@ubuntu1804-server:/data/webapps/myapp# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6012 0.0.0.0:*
LISTEN 0 100 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 128 [::1]:6012 [::]:*
LISTEN 0 1 [::ffff:127.0.0.1]:8005 *:*
none(null)
在使用 none 模式后,Docker 容器不会进行任何网络配置,其没有网卡、没有 IP
也没有路由,因此默认无法与外界通信,需要手动添加网卡配置 IP 等,所以极少使用
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it 368d58566001eb0e6bce27dce983e9569fefe1f31eede779ca56a8b5964d6771 bash
[root@368d58566001 /]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 1 127.0.0.1:8005 *:*
LISTEN 0 100 *:8080 *:*
[root@368d58566001 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
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
container模式
使用参数 –net=container:名称或 ID 指定。
使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的 IP,而是和一个已经存在的被指定的容器东西 IP 和端口范围,因此这个容器的端口不能和被指定的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,两容器的进程可以通过 lo 网卡及容器 IP 进行通信。
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d --name container_host -p 8082:8080 -p 8099:8009 06d988b898c7
1dfa30f4c8a4ad09f39f8dddfb087fc3fda7aea5d9d882a7c9857d76104297a2
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d --net=container:container_host 06d988b898c7
5fd6615c1f96c0d312782fad168c2f422f4a2aef8f58d31b1cd8b97229c161b8
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it 5fd6615c1f96c0d312782fad168c2f422f4a2aef8f58d31b1cd8b97229c161b8 bash
[root@1dfa30f4c8a4 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 10 bytes 796 (796.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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
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
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it 1dfa30f4c8a4ad09f39f8dddfb087fc3fda7aea5d9d882a7c9857d76104297a2 bash
[root@1dfa30f4c8a4 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 11 bytes 866 (866.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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
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
容器跨主机互联
两台主机之间的容器如何通信?
夸主机互联是说 A 宿主机的容器可以访问 B 主机上的容器,但是前提是保证各宿主机之间的网络是可以相互通信的,然后各容器才可以通过宿主机访问到对方的容器,实现原理是在宿主机做一个网络路由就可以实现 A 宿主机的容器访问 B主机的容器的目的,复杂的网络或者大型的网络可以使用 google 开源的 k8s 进行互联。
node1:192.168.7.101 --> docker0:172.17.0.1/24
node2:192.168.7.11 --> docker0:10.0.0.1/241.修改其中一台主机的docker0网段
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock –
bip=10.10.0.1/24
root@ubuntu1804-server:~# vim /lib/systemd/system/docker.service
root@ubuntu1804-server:~# systemctl daemon-reload
root@ubuntu1804-server:~# systemctl restart docker
root@ubuntu1804-server:~# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::42:a6ff:fe8d:4e8d prefixlen 64 scopeid 0x20<link>
ether 02:42:a6:8d:4e:8d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21 bytes 1606 (1.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.添加静态路由
root@ubuntu1804-server:~# route add -net 172.17.0.0/16 gw 192.168.7.101
3.创建一个容器,地址为10.0.0.3
root@ubuntu1804-server:~# docker run -it centos:base bash
[root@0c604ed6b52a /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.3 netmask 255.255.255.0 broadcast 10.0.0.255
ether 02:42:0a:00:00:03 txqueuelen 0 (Ethernet)
RX packets 6 bytes 516 (516.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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
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
3.在另一台添加静态路由,将其指向192.168.7.11
root@ubuntu1804-server:/data/webapps/myapp# route add -net 10.0.0.0/16 gw 192.168.7.11
4.ping测试
5.注:
开启ip_forward
如果是centos,则需要添加防火墙规则iptables -A FORWARD -s 网段 -j ACCEPT
创建自定义网络
命令用法:docker network create --subnet 网段 --gateway 网关 网络名称
创建网络:
网段:172.22.0.0/24
网关:172.22.0.1
网络名称: thomas-net
root@ubuntu1804-server:/data/webapps/myapp# docker network create --subnet 172.22.0.0/24 --gateway 172.22.0.1 thomas-net
2676b5e65a32e0f0d9264c5a75bf5a3bc5ef5cf64c929c25615f1794b378cb70
root@ubuntu1804-server:/data/webapps/myapp# docker network ls
NETWORK ID NAME DRIVER SCOPE
7f05725b5e55 bridge bridge local
5b5d14ec36c7 host host local
94c745143679 none null local
2676b5e65a32 thomas-net bridge local
创建容器并指定网络
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d 06d988b898c7
caa681763b53fff4d44186370f259f929e20e3c228139b119be8e84d9d2f0cac
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it caa681763b53fff4d44186370f259f929e20e3c228139b119be8e84d9d2f0cac bash
[root@caa681763b53 /]# ifcon^C
[root@caa681763b53 /]# ^C
[root@caa681763b53 /]# exit
exit
root@ubuntu1804-server:/data/webapps/myapp# docker run -it -d --net=thomas-net 06d988b898c7
d062d418d3e15873316ec18e431c00997630e86f5e5df83b57f34adeb0a4898b
root@ubuntu1804-server:/data/webapps/myapp# docker exec -it d062d418d3e15873316ec18e431c00997630e86f5e5df83b57f34adeb0a4898b bash
[root@d062d418d3e1 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.0.2 netmask 255.255.255.0 broadcast 172.22.0.255
ether 02:42:ac:16:00:02 txqueuelen 0 (Ethernet)
RX packets 14 bytes 1172 (1.1 KiB)
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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
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