Docker的网络管理(一)

一、端口映射

默认情况下,宿主机的网络与容器是隔离的。所以,在宿主机无法直接访问启动了的容器服务。但是可以通过端口映射的方式,将容器中的端口映射到宿主机的某个端口上,这样就可以在宿主机*问容器服务。

实现端口映射非常简单,只需要在启动容器时候指定-p参数。

$ docker run -d -P [--name 容器名称] 镜像名称
$ docker run -d -p [宿主机IP]:[宿主机端口号]:[容器端口号] [--name 容器名称] 镜像名称

上面提供了两种方式实现端口映射。第一种方式指定大写的-P参数,这时候系统会给容器随机地指定一个端口号。例如:

$ docker run -d -P --name nginx-zhong nginx
$ docker port nginx-zhong

运行效果:
Docker的网络管理(一)
看一下上面的PORTS列,可以看出启动nginx的80端口已经被映射到了宿主机的32769端口。该端口是由系统自动指派。如果在启动另外一个nginx容器,而且启动的时候也指定了大写-P参数,那么系统指派的端口号就是上一次指派端口号加1,即32770。
Docker的网络管理(一)
第二种映射端口的方式是启动容器时候指定了小写-p参数,该参数用于指定宿主机IP和端口号。例如:

$ docker run -d -p 192.168.31.20:80:80 --name nginx-zhong nginx
$ docker port nginx-zhong

运行效果:
Docker的网络管理(一)
从上图看到,现在容器ngix-zhong的80端口已经被映射到了宿主机(192.168.31.20)的80端口。这时候可以本地浏览器中通过宿主机ip访问ngnix容器服务。
Docker的网络管理(一)
其实,也可以把容器的端口映射到宿主机的不同端口上。

$ docker run -d -p [宿主机端口1]:[容器端口1]  -p [宿主机端口2]:[容器端口2] --name [容器名称][镜像名称]

例如:启动nginx容器,指定容器的80端口映射到宿主机的80和81端口。

$ docker run -d -p 192.168.31.20:80:80 -p 192.168.31.20:81:80 --name nginx-zhong nginx
$ docker port nginx-zhong

运行效果:
Docker的网络管理(一)

二、网络管理命令

网络命令 功能说明
docker network help 查看网络命令帮助
create 创建一个新的网络
connect 将容器连接到一个网络
disconnect 将容器从当前网络中断开连接
inspect 查看网络的详细信息
ls 查看网络列表
rm 删除一个或多个网络

三、网络模式

3.1 常见的网络模式介绍

(1)桥接模式
Docker的默认网络模式。在该模式下,Docker在容器启动时候会自动配置好网络信息,不需要自己进行额外配置。
优点:简单,而且在同一个宿主机上的所有容器都在同一个网络下,可以互相通信。
缺点:该模式是利用宿主机进行网络通信。由于涉及到网络转换,因此会造成一定的资源消耗,效率较低。

(2)Host模式
在该模式下,容器使用宿主机的IP进行通信。容器和宿主机共享网络,不需要进行端口映射。

(3)None模式
在该模式下,Docker不会为容器配置网络,因此用户可以最大限度的定制网络信息。
特点:不提供网络服务,容器启动后没有网络连接,需要自己配置。

3.2 网络模式的应用

3.1 桥接模式

(1)创建网络
默认情况,系统配置网络时候就是使用了桥接模式。上面实现端口映射的时候也是使用了桥接模式。在特殊情况下,我们也可以创建自己的桥接网络,具体步骤如下:

第一步:创建网络。

$ docker network create --driver [网络类型] [网络名称]

例如:创建一个网络,并指定网络类型为bridge。创建成功后把所有网络列出来。

$ docker network create --driver bridge bridge-test
$ docker network ls

运行效果:
Docker的网络管理(一)
上面红色框中的网络信息就是我们刚创建的网络。

# 查看网络的详细信息
$ docker network inspect bridge-test

运行效果:
Docker的网络管理(一)

(2)自定义网段和网关
从上面可以看到,默认情况下网络使用的网段为172.18.0.0/16,网关为172.18.0.1。如果要修改网段和网关的信息,可以在创建网络的时候指定–subnet和–gateway参数。例如:

$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 bridge-test2
$ docker network inspect bridge-test2

Docker的网络管理(一)
我们也可以执行ifconfig命令查看所有的网络信息。
Docker的网络管理(一)
最上面两个就是我们之前创建出来的网络。

(3)在自定义网络中启动容器
如果在自定义网络中启动网络,可以在启动网络的时候指定–net参数。

$ docker run --net [网络名称] -itd --name [容器名称] [镜像名称]

例如:

$ docker run --net bridge-test -itd --name nginx-zhong nginx
$ docker inspect nginx-zhong

运行结果:
Docker的网络管理(一)
我们也可以在网络中看到该网络中的容器。

$ docker network inspect bridge-test

运行结果:
Docker的网络管理(一)
注意:默认桥接模式创建的容器是可以联网的。但是自定义桥接模式创建的容器默认不可以联网,如果要联网就要做端口映射。

(4)断开网络

$ docker network disconnect [网络名称] [容器名称]

例如:

$ docker network disconnect bridge-test nginx-zhong
$ docker network inspect bridge-test

运行效果:
Docker的网络管理(一)
同样地,nginx-zhong容器的networks也被置空。

$ docker inspect nginx-zhong

运行效果:
Docker的网络管理(一)
(5)容器连接网络

$ docker network connect [网络名称] [容器名称]

例如:让容器nginx-zhong连接到自定义网络bridge-test。

$ docker network connect bridge-test nginx-zhong

运行效果:
Docker的网络管理(一)
从图上看到,现在nginx-zhong的网络配置信息已经存在了。

(6)自定义网桥
目前为止,我们创建的容器IP都是从docker0自动获取的。docker0是启动docker时候系统自动分配的一个网络设备。docker0默认指定了IP地址和子网掩码,让主机和容器之间通过网桥进行通信。

但是有可能它提供的IP配置与公司内部网关发生冲突了,造成一些不必要麻烦。

解决办法:自定义网桥。它可以提供一种灵活方式管理docker网络。

自定义网桥的步骤:

第一步:安装网桥管理工具。

$ sudo apt-get install bridge-utils -y

安装成功后,执行brctl show命令查看网桥信息。
Docker的网络管理(一)

第二步:创建网桥。

$ sudo brctl addbr br0

上面命令创建了一个名为br0的网桥,同样可以执行brctl show命令查看。
Docker的网络管理(一)
第三步:设置br0网段和子网掩码。

$ sudo ifconfig br0 192.168.99.1 netmask 255.255.255.0
$ ifconfig

运行效果:
Docker的网络管理(一)
第四步:修改docker配置文件,指定docker服务使用br0网桥。

$ sudo vim /etc/default/docker

打开配置文件后,在文件末尾添加以下内容:

DOCKER_OPTS="-b=br0"

第四步:创建服务依赖文件。

$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo vim /etc/systemd/system/docker.service.d/Using_Environment_File.conf

创建文件后,添加以下内容:

[Service]
EnvironmentFile=-/etc/default/docker
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS

第五步:加载配置文件。

$ systemctl daemon-reload

第六步:重启docker服务。

$ systemctl restart docker

重启完成后,查看docker进程信息。
Docker的网络管理(一)
从图上可以看出,目前docker服务使用的是br0网络。我们也可以执行以下命令查看网桥创建是否成功。

$ docker network inspect bridge

运行效果:
Docker的网络管理(一)

第七步:测试。

# 创建容器
$ docker run -itd --name nginx-test nginx
$ docker inspect nginx-test

运行效果:
Docker的网络管理(一)
至此,网桥br0已经配置成功!!!