3.2 操作 Docker 虛擬網路
上一小節説了很多關於 Docker 虛擬網路的技術,但實際操作起來到底是如何呢?
讓我們從 docker network list
開始,大家應該會開始發現 Docker 的指令其實就是透過一開始提到的 Management Command 當作主詞,後面搭配的動詞其實都是相同的。
$ docker network list
NETWORK ID NAME DRIVER SCOPE
8089a4c2e32a bridge bridge local
0df5a43ad470 host host local
1ba8d9b1e033 none null local
如果沒有特別建立虛擬網路的話,剛開始使用 Docker 的新手應該就只有上方這三個虛擬網路,而 bridge 則是我們前面介紹過 Docker 默認使用的虛擬網路,藉由 NAT 的技術潛伏在主機的防火牆後方。
第二個會看到的是 host 這個虛擬網路,這是一個特殊的服務,它跳過了 Docker 的虛擬網路,直接把容器連接到主機的網路介面上。
這麼做有好處也有壞處,壞處是它讓容器的安全性降低了,直接連接到本機的網路介面是有風險的,好處則是它可以提高網路的效能,畢竟少了多層級的訪問當然會更快!
最後一個看到的則是 none 這個虛擬網路,其實連接到這個虛擬網路相當於沒有連接到任何網路的意思;有些時候或許我們想要斷開某些曝光在網路上,我們可以選擇先暫時將容器連接到 none 的虛擬網路。
接著是上一小節也有使用過的 docker network inspect
這個指令,要記得 inspect
這個指令是非常萬用的 Command,不論今天搭配的是什麼 Docker 的物件,都可以養成習慣用 inspect
來看看詳細資訊。
回應的內容就像上一小節有提到的,可以在裡面看到 Gateway 以及 subnet 的 IP 位置,預設都會是 172.17 開頭,其實這個 IP 位置本身也是可以自訂的,有興趣可以自己上網去研究,這邊就不多做介紹。
同時 inspect
也會列出這個虛擬網路上所連接的容器。
$ docker network inspect bridge
[
..
"Containers": {
"68095f33b6ccb53eb2f1aba489fe642b97dd8...": {
"Name": "nginx2",
"EndpointID":"27e0b715a4e35965dfe65....",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"c2713832bc9abc526e993b2537bee5322fc....": {
"Name": "nginx",
"EndpointID": "e1e747ed84ab55c5cb8e....",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
...
]
這邊可以看到上一小節示範 的兩個 nginx 正連接在 bridge 這個虛擬網路上。
建立自己的虛擬網路
說了那麼多不如直接來建立虛擬網路吧!
$ docker network create app # 這邊的名字你可以取你喜歡的
e4ad3a30af60ff7ce3cf60758fb948b39c03db04
# 這邊和容器同理,是這個虛擬網路的專屬 ID
接著我們來列出所有的虛擬網路,確認真的有建立成功。
$ docker network list
NETWORK ID NAME DRIVER SCOPE
e4ad3a30af60 app bridge local
8089a4c2e32a bridge bridge local
0df5a43ad470 host host local
1ba8d9b1e033 none null local
添加原先的容器到新的虛擬網路
在建立了專屬的虛擬網路後,我們可以把容器連接到這個新的虛擬網路中,該怎麼做呢?使用 --network
的參數。
$ docker container rm -f $(docker container ls -aq)
# 我們先清除舊有的容器
$ docker container run --detach --publish 80:80 --network app --name nginx nginx # 不換行
eb893a93e76abf6078eeab
接著確認一下有沒有正確地連接上 app 這個虛擬網路,再次利用 inspect
的方法來檢查。
$ docker network inspect app
[
..
"Containers": {
"eb893a93e76abf6078eeab8202eeaa028e...": {
"Name": "nginx",
"EndpointID":"85139bd78edc99c8c04bf72cfd....",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
...
]
如預期般的連接上 app 虛擬網路;但在實務上,我們很有可能需要替正在運作的容器添加新的虛擬網路,這時候中斷容器的服務在重新用 --network
的方式似乎不太合理,畢竟中斷正在運作的服務並不是一件樂見的事情。