2023 iT邦鐵人賽 Day 10 - 容器的連接阜與網絡

前言

昨天講解了很多常使用的指令,讓我們得以查看容器內部的資訊,以及與容器互動的方法等等,今天我們來講常見且重要的連接阜、網絡。

這些通訊的設定,讓我們可以訪問容器,也讓容器可以彼此溝通。

連接阜 ( port )

什麼是連接阜?它是一個連接通道,連接什麼?連接兩端的設備或系統。為什麼要連接?為了讓這一端的設備或系統,能夠通向另一端的設備或系統,這樣我就能在我這端的設備或系統,查看到另一端的設備或系統。

在容器裡,連接的兩端就是指執行容器的主機跟容器本身。容器的連接阜預設為 80,那主機的連接阜就並不侷限特定數字,可以是常聽到的 3000,又或是 8000。

使用 -p--publish 設定容器的連接阜:

1
2
3
docker container run -d -p 主機連接阜號:容器連接阜號 映像檔名稱

docker container run -d -p 8000:80 httpd

像這樣,我們把容器的連接阜映射到主機上,這時,主機跟容器彼此相通,我們可以透過 http://localhost:8000 訪問該容器裡正在運作的 web,如果連接阜有設定成功,就會在網頁上看到 It works! 的字樣。這就代表我們已經將兩端連上,我們可以透過 8000 去訪問容器內應用程式。

網絡 ( net )

網絡主要是連接容器之間的通訊,讓容器之間可以互相溝通,彼此合作。

由於一套龐大完整的系統,不只靠一個容器就能構成,必定是由多個容器,各司其職,互相合作,形成一個龐大的集合體。

建立網絡

透過 docker 建立一個虛擬網絡,讓容器彼此通訊。

1
> docker network create

也可以給網絡一個名字:

1
> docker network create net

查看網絡清單

這裡一樣是使用 ls

1
2
3
4
5
6
> docker network ls

NETWORK ID NAME DRIVER SCOPE
839967535fc2 bridge bridge local
142a82ff9198 host host local
ad9d546e7e88 none null local

在 docker 中,預設會送你三個不同 driver 的網絡。

  • bridge: Docker 默認使用的虛擬網路。
  • host: 將容器的虛擬網絡與本機網絡連接 ( 風險較高 )。
  • null: 沒有網路連接。 ( 有時可能需要將容器的網路關閉 )

讓容器連上網絡

我們可以在建立容器時,將網絡設定進去:

1
> docker container run --name iThome -d -p 8001:80 --network net httpd

接著使用 inspect 確認容器的網絡連結狀況

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> docker container inspect iThome

"Networks": {
"net": { <-------------- 我們建立的網絡
"IPAMConfig": null,
"Links": null,
"Aliases": [
"474f0aed15b5"
],
"NetworkID": "2eb8c5d22b3f1be61e54980a5df232ff8dbbe7e3f594c6e8b01f24acbbcf9ef9",
"EndpointID": "2e4c7b813ca1dad509a19da4c5749076f5513d9446d52d5fc96a71e05f7f5626",
"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
}
}

( 可以建立一個沒有設定網絡的容器來對比,會發現網絡是 bridge )

什麼?你想要中途上車?原本建立好的容器沒有設定,但現在想設定?行!

1
2
3
4
5
> docker container create --name iThome666 -d -p 8888:80 httpd

> docker network create net666

> docker network connect net666 iThome666

這時就讓容器 iThome666 成功連上 net666 了。

檢視網絡

沒錯,使用 inspect 來檢視網絡的細節:

1
> docker network inspect net

內容不多加細說,這裡我們只看這段

1
2
3
4
5
6
7
8
9
"Containers": {
"474f0aed15b59d4d4c278ed5213706b7f9adfa8bc339ba21430240750e5a8989": {
"Name": "iThome",
"EndpointID": "2e4c7b813ca1dad509a19da4c5749076f5513d9446d52d5fc96a71e05f7f5626",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
}

沒錯,哪個容器正在連結這個網絡,上面寫的一清二楚。

當我們將第二個容器連上同一個網絡時:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> docker container run -d --name iThome999 --network net httpd
> docker network inspect net
"Containers": {
"2eb5908d2adf8e2df23ee3e932e851b39a287105c22e3d7f4980305251ce511e": {
"Name": "iThome999",
"EndpointID": "616c50c6943f219ef814f51243997c99d9ba0d1dd6c0525a34cf4f88527d1341",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"474f0aed15b59d4d4c278ed5213706b7f9adfa8bc339ba21430240750e5a8989": {
"Name": "iThome",
"EndpointID": "2e4c7b813ca1dad509a19da4c5749076f5513d9446d52d5fc96a71e05f7f5626",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
}

可以很清楚地發現,現在這個網絡有兩個容器連上了。

刪除網絡

一樣使用 rm 進行刪除,但一樣是無法刪除正在使用欲刪除的網絡的哦,而且甚至是想強制刪除也是無法的哦~

1
2
3
> docker network rm net666
Error response from daemon: error while removing network: network net666
id cda23103762e1b22d59afc4e69261000c417f06fba897f454511005cd96680c8 has active endpoints

總結

在第十天寫了洋洋灑灑、大篇幅的文章,希望大家能越來越熟悉容器。

其實連接阜跟網絡有很深的學問,IP、訪問層級等等,若大家有興趣深度研究,可以再另外搜尋相關資訊,因為這次的鐵人賽主要是希望能讓全新手理解 Docker,所以有些太深的學問,就留到以後有機會再來寫。