这个部分是教你如何用网络连接到你的容器
Dodker中使用网络驱动器来对网络容器进行支持。默认地,Docker提供给你两个网络驱动器:
the bridge and the overlay drivers。
你也可以自己写网络驱动器插件来创建自己的驱动器但是这不是一件简单的事。
每一个安装好的Dockery引擎都自动包含了三个网络。你可以列出他们
docker network ls
NETWORK ID NAME DRIVER
18a2866682b8 none null
c288470c46f6 host host
7b369448dccb bridge bridge
名字为bridge的网络是一个特殊的网络。除非你在你的容器中特别地声明其他网络否则容器会默认使用这个网络。试一试下面这句:
docker run -itd --name=networktest ubuntu
74695c9cea6d9810718fddadc01a727a5dd3ce6a69d09752239736c030599741
通过查看网络可以很容易地找出容器的IP地址:
docker network inspect bridge
[ { "Name": "bridge", "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.17.0.1/16", "Gateway": "172.17.0.1" } ] }, "Containers": { "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": { "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": { "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "9001" } }]
你可以通过使一个容器的网络断连来移除该容器。要这样做的话,你要提供网络的名字和容器名字,当然容器名字可以换成容器的ID.在这个例子中,使用容器名字更快。
docker network disconnect bridge networktest
创建自己的bridge网络
Docker引擎内在支持包括both bridge networks and overlay networks.一个bridge network限制到一个运行Docker引擎的主机。( A bridge network is limited to a single host running Docker Engine. )。
overlay network可以包含多个主机而且是个更加高级的东西。在这个例子当中,你可以创建一个bridge network
docker network create -d bridge my-bridge-network
往容器中添加网络
To build web applications that act in concert but do so securely, create a network.
网络,根据定义,给容器提供完全隔离的环境。当你第一次运行一个容器的时候你可以将容器添加到网络中。
启动容器,运行PostgreSQL数据库,传进去参数: pass it the --net=my-bridge-network来连接到你的网路。
docker run -d --net=my-bridge-network --name db training/postgres
如果你查看 my-bridge-network的话,你会看到它已经被一个容器依附了。你也可以查看你的容器 ,看看它在哪里被连接了。
docker inspect --format='{{json .NetworkSettings.Networks}}' db
{"my-bridge-network":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99","EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.18.0.1","IPAddress":"172.18.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}
现在,运行你熟悉的网页应用。这次,我们不指定某一个网络。
docker run -d --name web training/webapp python app.py
现在,这个网页应用的是运行在那个网络下呢?查看一下应用程序,你会发现它运行在默认的网络下:
bridge network.
docker inspect --format='{{json .NetworkSettings.Networks}}' web
{"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812","EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"172.17.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}
接下来,我们获取你网页的IP
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2
现在,打开一个shell来运行db容器
docker exec -it db bash
root@a205f0dd33b2:/# ping 172.17.0.2ping 172.17.0.2PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.^C--- 172.17.0.2 ping statistics ---44 packets transmitted, 0 received, 100% packet loss, time 43185ms
过一会之后,按Ctrl+C来强制退出ping,你会发现ping失败了。这是因为两个容器运行在不同的网络下。当然你可以修正。接着,用
exit
退出这个db容器.
docker 网络允许你将一个容器依附于多个网络。你也可以依附已经在运行的容器。接下来,我们将网页应用依附到my-bridge-network
.
docker network connect my-bridge-network web
打开一个shell进去db应用,然后试一下ping命令。这次就用容器名字web而不使用IP地址。
docker exec -it db bash
root@a205f0dd33b2:/# ping webPING web (172.18.0.3) 56(84) bytes of data.64 bytes from web (172.18.0.3): icmp_seq=1 ttl=64 time=0.095 ms64 bytes from web (172.18.0.3): icmp_seq=2 ttl=64 time=0.060 ms64 bytes from web (172.18.0.3): icmp_seq=3 ttl=64 time=0.066 ms^C--- web ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2000msrtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms
这次,ping显示它连接到了一个不同的IP地址,my-bridge-network神的地址和 bridge network.上的地址不同。
分割线,分割线,分割线
上面有个ping不可用,原因在与网页应用和它使用的数据库使用了不同的网络,所以无法进行正确的网络连接。
以下是修改方法的思路:将两个容器连接到的网络设置成一样就可以。
我们接下来将db连接到的网络改为默认的网络:
首先,断开db容器已经连接到的网络
docker network disconnect my-bridge-network db
断开连接之后,db还没有完全被删除,只是没有网络连接而已,但是这时候如果要新设置db的网络连接,会出现如下的错误:
docker: Error response from daemon: Conflict. The name "/db" is already in use by container 9be85ea3ed617d379580f10216fda a3fdcbb9d01b3ac7935510d97f73977b659. You have to remove (or rename) that container to be able to reuse that name..
See 'docker run --help'.
意思是,db这个名字已经被某个容器使用,所以要么把这个删了再重新建一个名字为db的容器,在新建的时候就可以指定网络(所以这里可以反推出上面指定网络的语句是在容器新建的时候指定的,不能用这个语句来修改,至于有没有其他的,暂时没接触到)。要么用在去新建一个容器(当然,使用的是一样的初始容器)。
删除容器使用下面的语句:
如果不是正在运行的
docker rm db
如果是正在运行的:
docker rm -f db
停止一个容器运行的语句
docker stop db
清理所有处于终止状态的容器
用 :
docker ps -a
命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用
docker rm $(docker ps -a -q)
可以全部清理掉。
*注意:这个命令其实会试图删除所有的包括还在运行中的容器,不过就像上面提过的
docker rm
默认并不会删除运行中的容器。