容器之间的互联

直接互联

启动两个容器

[root@docker-server1 ~]# docker run -d -it --name web1 nginx:1.8
[root@docker-server1 ~]# docker run -d -it --name web2 nginx:1.8

检测网络连通性

先登录查看两个容器的IP,再ping测试

root@855ab8d0bd74:/# ping 172.17.0.3 -c 2
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.081 ms

使用名称互联

启动两个容器

[root@docker-server1 ~]# docker run -d -it --name web1 nginx:1.8
[root@docker-server1 ~]# docker run -d -it --name web2 --link web1 nginx:1.8

查看web2容器的hosts文件

发现已经实现名称解析

[root@docker-server1 ~]# docker exec -it web2 bash
root@8a3e9cee9e37:/# 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  web1 622eff54876f
172.17.0.3  8a3e9cee9e37

连通性测试

root@8a3e9cee9e37:/# ping web1 -c 2
PING web1 (172.17.0.2) 56(84) bytes of data.
64 bytes from web1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from web1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.045 ms

使用别名互联

启动一个容器

[root@docker-server1 ~]# docker run -d -it --name web3 --link web1:nginx-web1 nginx:1.8

查看容器web3的hosts文件

发现已经实现别名解析

[root@docker-server1 ~]# docker exec -it web3 bash
root@c85c73ebf00b:/# 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  nginx-web1 622eff54876f web1
172.17.0.4  c85c73ebf00b

连通性测试

root@c85c73ebf00b:/# ping nginx-web1 -c2
PING nginx-web1 (172.17.0.2) 56(84) bytes of data.
64 bytes from nginx-web1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.112 ms
64 bytes from nginx-web1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.055 ms

四大网络模式

在启动容器的时候可以使用--network参数去指定网络类型,默认使用的是bridge网络类型

host网络类型

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

container网络类型

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

none网络类型

在使用none模式后,docker容器不会进行任何网络配置,其没有网卡、没有ip也没有路由,因此默认无法与外界进行通信,需要手动添加网卡配置ip等,所以极少使用 img

bridge网络类型(默认)

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

自定义网络

自定义网络可以自定义ip地址范围和网关等信息

创建一个网络

[root@docker-server1 ~]# docker network create -d bridge --subnet 10.10.0.0/16 --gateway 10.10.0.1 eagleslab-net
[root@docker-server1 ~]# docker network list
NETWORK ID     NAME            DRIVER    SCOPE
787342a0d883   bridge          bridge    local
74ee6ecdfc03   eagleslab-net   bridge    local
9a6d7244e807   host            host      local
beace8354cca   none            null      local

使用自定义网络创建容器

[root@docker-server1 ~]# docker run -d -it --name web8 --network eagleslab-net nginx:1.8

检查网络

[root@docker-server1 ~]# docker exec -it web8 bash
root@a7edddb4114e:/# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.0.2  netmask 255.255.0.0  broadcast 10.10.255.255
        ether 02:42:0a:0a:00:02  txqueuelen 0  (Ethernet)
        RX packets 1064  bytes 8764484 (8.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 738  bytes 41361 (40.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
root@a7edddb4114e:/# ping www.baidu.com -c2
PING www.a.shifen.com (112.34.112.83) 56(84) bytes of data.
64 bytes from 112.34.112.83 (112.34.112.83): icmp_seq=1 ttl=127 time=37.8 ms
64 bytes from 112.34.112.83 (112.34.112.83): icmp_seq=2 ttl=127 time=36.9 ms