這個部分是教你如何用網絡連接到你的容器
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
默認并不會刪除運行中的容器。