Docker网络介绍
在Docker中,有一个重要的模块叫做Network Driver,负责创建并配置Docker容器的网络环境。在宿主机尚键入命令ifconfig/ipconfig,就会看到对应的docker网络信息:

Docker网络负责容器之间的通信和端口映射。在容器IP地址发生变化的时候,可以通过服务名进行容器间通信。
如果输入命令docker network ls:
> docker network ls
NETWORK ID NAME DRIVER SCOPE
81b2898ba8cd bridge bridge local
1bc988b15d22 host host local
a7b90b510a64 none null local
查看某个Docker网络的详细信息:
docker network inspect bridge
Docker中的几种网络模式
bridge虚拟网桥
bridge是Docker容器默认的网络模式。通过虚拟网桥,可以为容器分配IP,同时将容器连接到Docker虚拟网桥docker0。
Docker虚拟网桥docker0就有些类似于一个虚拟的交换机,所有Docker容器都通过虚拟网卡连接到这个虚拟交换机,从而实现容器之间的通信,以及和宿主机之间的通信。
针对每个容器,网桥都会创建一对虚拟设备:veth(网桥端,类似于交换机上接口),eth0(容器端,类似于机器上的网卡)
在启动一个Docker容器后,如果在宿主机运行如下命令:
ip addr
就会看到类似vethxxxxxxxx的虚拟设备:
41: vethac5668a@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 6a:89:02:70:e3:15 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::6889:2ff:fe70:e315/64 scope link
valid_lft forever preferred_lft forever
但当进入容器内之后,需要运行:
apt update -y
apt install iproute2 -y
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
40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
host
说明容器会直接使用host的IP和端口,而不会创建自己的网卡,IP等网络资源。
注意:如果在启动容器时指定了host模式,同时也指定了端口映射,可能会看到提示:
docker run -d -p 6380:6379 --network host redis
WARNING: Published ports are discarded when using host network mode
删除上面命令中的–network host选项,警告就会消失。
因此在访问容器的时候,直接使用host IP:端口号就可以。
none
容器有自己独立的网络命名空间,但并未对其进行任何配置。只能通过lo (127.0.0.1)访问容器。如果有必要,需要自己配置所有网络细节。
container
在创建Docker容器时,不会创建该容器自己的网卡和IP,而是和另一个容器共享这些网络资源。其使用方式是:
--network container:CONTAINER_NAME/CONTAINER_ID
Docker中的自定义网络
如果通过前面的Bridge方式创建不同容器,容器之间是可以互相通过IP地址来访问的(但不能通过容器名互访)。这就会造成一定的麻烦,因为每次重新启动容器,获得的IP地址可能会发生变化。
解决方法就是使用自定义网络。步骤如下:
创建自定义网络
docker network create lcoding_network
创建容器并加入自定义网络
之后在创建容器的时候,就可以把容器都加入到自定义网络中了:
docker run -d -p 6380:6379 --network lcoding_network --name redis1 redis
docker run -d -p 6381:6379 --network lcoding_network --name redis2 redis
至此,不同容器之间就可以通过容器名互访了。