容器能够互相连接的前提是两者同处于一个网络中 ( 这里的网络是指容器网络模型中的网络 )。这个限制很好理解,刚才我们说了,网络这个概念我们可以理解为 Docker 所虚拟的子网,而容器网络沙盒可以看做是虚拟的主机,只有当多个主机在同一子网里时,才能互相看到并进行网络数据交换。
当我们启动 Docker 服务时,它会为我们创建一个默认的 bridge 网络,而我们创建的容器在不专门指定网络的情况下都会连接到这个网络上。所以我们刚才之所以能够把 webapp 容器连接到 mysql 容器上,其原因是两者都处于 bridge 这个网络上。
我们通过 docker inspect 命令查看容器,可以在 Network 部分看到容器网络相关的信息。
sudo docker inspect mysql
[{## ......"NetworkSettings": {## ......"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "bc14eb1da66b67c7d155d6c78cb5389d4ffa6c719c8be3280628b7b54617441b","EndpointID": "1e201db6858341d326be4510971b2f81f0f85ebd09b9b168e1df61bab18a6f22","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}## ......}## ......}]
这里我们能够看到 mysql 容器在 bridge 网络中所分配的 IP 地址,其自身的端点、Mac 地址,bridge 网络的网关地址等信息。
Docker 默认创建的这个 bridge 网络是非常重要的,理由自然是在没有明确指定容器网络时,容器都会连接到这个网络中。在之前讲解 Docker for Win 和 Docker for Mac 安装的时候,我们提到过这两个软件的配置中都有一块配置 Docker 中默认网络的内容,这块所指的默认网络就是这个 bridge 网络。
创建网络
在 Docker 里,我们也能够创建网络,形成自己定义虚拟子网的目的。
docker CLI 里与网络相关的命令都以 docker network 开头,其中创建网络的命令是 docker network create。
sudo docker network create -d bridge individual
通过 -d 选项我们可以为新的网络指定驱动的类型,其值可以是刚才我们所提及的 bridge、host、overlay、maclan、none,也可以是其他网络驱动插件所定义的类型。这里我们使用的是 Bridge Driver ( 当我们不指定网络驱动时,Docker 也会默认采用 Bridge Driver 作为网络驱动 )。
通过 docker network ls 或是 docker network list 可以查看 Docker 中已经存在的网络。
sudo docker network ls
NETWORK ID NAME DRIVER SCOPEbc14eb1da66b bridge bridge local35c3ef1cc27d individual bridge local
之后在我们创建容器时,可以通过 —network 来指定容器所加入的网络,一旦这个参数被指定,容器便不会默认加入到 bridge 这个网络中了 ( 但是仍然可以通过 —network bridge 让其加入 )。
sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
我们通过 docker inspect 观察一下此时的容器网络。
sudo docker inspect mysql
[{## ......"NetworkSettings": {## ......"Networks": {"individual": {"IPAMConfig": null,"Links": null,"Aliases": ["2ad678e6d110"],"NetworkID": "35c3ef1cc27d24e15a2b22bdd606dc28e58f0593ead6a57da34a8ed989b1b15d","EndpointID": "41a2345b913a45c3c5aae258776fcd1be03b812403e249f96b161e50d66595ab","Gateway": "172.18.0.1","IPAddress": "172.18.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:12:00:02","DriverOpts": null}}## ......}## ......}]
可以看到,容器所加入网络已经变成了 individual 这个网络了。
这时候我们通过 —link 让处于另外一个网络的容器连接到这个容器上,看看会发生什么样的效果。
sudo docker run -d --name webapp --link mysql --network bridge webapp:latest
docker: Error response from daemon: Cannot link to /mysql, as it does not belong to the default network.ERRO[0000] error waiting for container: context canceled
可以看到容器并不能正常的启动,而 Docker 提醒我们两个容器处于不同的网络,之间是不能相互连接引用的。
我们来改变一下,让运行 Web 应用的容器加入到 individual 这个网络,就可以成功建立容器间的网络连接了。
sudo docker run -d --name webapp --link mysql --network individual webapp:latest
**
