橋接網路驅動程式
在網路功能方面,橋接網路是一種連結層(Link Layer)裝置,用於在網路區段之間轉發流量。橋接器可以是硬體裝置,也可以是在主機核心中執行的軟體裝置。
在 Docker 方面,橋接網路使用軟體橋接器,讓連接到相同橋接網路的容器可以相互通訊,同時與未連接到該橋接網路的容器隔離。Docker 橋接驅動程式會自動在主機上安裝規則,以便不同橋接網路上的容器無法直接相互通訊。
橋接網路適用於在同一 Docker 守護程式(daemon)主機上運行的容器。對於在不同 Docker 守護程式主機上運行的容器之間的通訊,您可以選擇在作業系統層級管理路由,或者使用一個overlay 網路。
當您啟動 Docker 時,會自動建立一個預設橋接網路(也稱為 bridge),新啟動的容器除非另有指定,否則都會連接到該網路。您也可以建立使用者定義的自訂橋接網路。使用者定義的橋接網路優於預設的 bridge 網路。
使用者定義的橋接網路與預設橋接網路之間的差異
使用者定義的橋接網路提供容器之間的自動 DNS 解析.
預設橋接網路上的容器只能透過 IP 位址相互存取,除非您使用被視為過時的
--link選項。在使用者定義的橋接網路中,容器可以透過名稱或別名相互解析。想像一個具有網頁前端和資料庫後端的應用程式。如果您將容器命名為
web和db,則無論應用程式堆疊在哪個 Docker 主機上執行,網頁容器都可以透過db連接到資料庫容器。如果您在預設橋接網路上運行相同的應用程式堆疊,則需要手動在容器之間建立連結(使用過時的
--link旗標)。這些連結需要雙向建立,因此您可以看到,如果有多於兩個容器需要通訊,這會變得複雜。或者,您可以操作容器內的/etc/hosts檔案,但這會產生難以偵錯的問題。使用者定義的橋接網路提供更好的隔離.
所有未指定
--network的容器都會連接到預設橋接網路。這可能存在風險,因為不相關的堆疊/服務/容器隨後都能夠相互通訊。使用者定義的網路提供了一個範圍受限的網路,其中只有連接到該網路的容器才能相互通訊。
容器可以即時連接和中斷與使用者定義網路的連線.
在容器的生命週期中,您可以即時將其連接或中斷與使用者定義網路的連線。要從預設橋接網路中移除容器,您需要停止容器並使用不同的網路選項重新建立它。
每個使用者定義的網路都會建立一個可配置的橋接器.
如果您的容器使用預設橋接網路,您可以配置它,但所有容器都使用相同的設定,例如 MTU 和
iptables規則。此外,配置預設橋接網路是在 Docker 本身之外進行的,並且需要重新啟動 Docker。使用者定義的橋接網路是使用
docker network create建立和配置的。如果不同群組的應用程式有不同的網路需求,您可以在建立時分別配置每個使用者定義的橋接網路。預設橋接網路上連結的容器共享環境變數.
最初,在兩個容器之間共享環境變數的唯一方法是使用
--link旗標將它們連結起來。這種變數共享在使用者定義的網路中是不可能的。然而,有更好的方法來共享環境變數。以下是一些想法:多個容器可以使用 Docker 磁碟區掛載包含共享資訊的檔案或目錄。
可以使用
docker-compose一起啟動多個容器,並且 compose 檔案可以定義共享變數。您可以使用 swarm 服務而不是獨立容器,並利用共享的機密(secrets)和配置(configs)。
連接到相同使用者定義橋接網路的容器會有效地向彼此公開所有連接埠。要使連接埠可供不同網路上的容器或非 Docker 主機存取,該連接埠必須使用 -p 或 --publish 旗標進行發布。
選項
下表描述了當您使用 bridge 驅動程式建立自訂網路時,可以傳遞給 --opt 的驅動程式特定選項。
| 選項 | 預設值 | 描述 |
|---|---|---|
com.docker.network.bridge.name | 建立 Linux 橋接器時使用的介面名稱。 | |
com.docker.network.bridge.enable_ip_masquerade | true | 啟用 IP 偽裝(IP masquerading)。 |
com.docker.network.bridge.gateway_mode_ipv4com.docker.network.bridge.gateway_mode_ipv6 | nat | 控制外部連線。請參閱封包過濾與防火牆。 |
com.docker.network.bridge.enable_icc | true | 啟用或禁用容器間連線。 |
com.docker.network.bridge.host_binding_ipv4 | 所有 IPv4 和 IPv6 位址 | 綁定容器連接埠時的預設 IP。 |
com.docker.network.driver.mtu | 0 (無限制) | 設定容器網路的最大傳輸單元 (MTU)。 |
com.docker.network.container_iface_prefix | eth | 為容器介面設定自訂前綴。 |
com.docker.network.bridge.inhibit_ipv4 | false | 防止 Docker 將 IP 位址指派給橋接器。 |
其中一些選項也作為旗標提供給 dockerd CLI,您可以在啟動 Docker 守護程式時使用它們來配置預設的 docker0 橋接器。下表顯示了哪些選項在 dockerd CLI 中具有等效的旗標。
| 選項 | 旗標 |
|---|---|
com.docker.network.bridge.name | - |
com.docker.network.bridge.enable_ip_masquerade | --ip-masq |
com.docker.network.bridge.enable_icc | --icc |
com.docker.network.bridge.host_binding_ipv4 | --ip |
com.docker.network.driver.mtu | --mtu |
com.docker.network.container_iface_prefix | - |
Docker 守護程式支援 --bridge 旗標,您可以使用它來定義自己的 docker0 橋接器。如果您想在同一主機上運行多個守護程式實例,請使用此選項。有關詳細資訊,請參閱運行多個守護程式。
預設主機綁定位址
當連接埠發布選項(例如 -p 80 或 -p 8080:80)中未提供主機位址時,預設會使容器的連接埠 80 在所有主機位址(IPv4 和 IPv6)上可用。
橋接網路驅動程式選項 com.docker.network.bridge.host_binding_ipv4 可用於修改已發布連接埠的預設位址。
儘管該選項的名稱如此,但仍可以指定 IPv6 位址。
當預設綁定位址是分配給特定介面的位址時,容器的連接埠將只能透過該位址存取。
將預設綁定位址設定為 :: 表示已發布的連接埠將僅在主機的 IPv6 位址上可用。然而,將其設定為 0.0.0.0 表示它將在主機的 IPv4 和 IPv6 位址上可用。
要將已發布的連接埠限制為僅限 IPv4,必須將位址包含在容器的發布選項中。例如,-p 0.0.0.0:8080:80。
管理使用者定義的橋接網路
使用 docker network create 指令建立使用者定義的橋接網路。
$ docker network create my-net
您可以指定子網路、IP 位址範圍、閘道器和其他選項。有關詳細資訊,請參閱 docker network create 參考或 docker network create --help 的輸出。
使用 docker network rm 指令移除使用者定義的橋接網路。如果容器當前已連接到該網路,請先將其斷開連線。
$ docker network rm my-net
實際發生了什麼?
當您建立或移除使用者定義的橋接網路,或將容器連接或中斷與使用者定義橋接網路的連線時,Docker 會使用作業系統特定的工具來管理底層網路基礎設施(例如在 Linux 上新增或移除橋接裝置或配置
iptables規則)。這些細節應被視為實作細節。讓 Docker 為您管理使用者定義的網路。
將容器連接到使用者定義的橋接網路
當您建立新容器時,可以指定一個或多個 --network 旗標。此範例將 Nginx 容器連接到 my-net 網路。它還將容器中的連接埠 80 發布到 Docker 主機上的連接埠 8080,以便外部客戶端可以存取該連接埠。任何連接到 my-net 網路的其他容器都可以存取 my-nginx 容器上的所有連接埠,反之亦然。
$ docker create --name my-nginx \
--network my-net \
--publish 8080:80 \
nginx:latest
要將正在執行中的容器連接到現有的使用者定義橋接網路,請使用 docker network connect 指令。以下指令將一個已經在執行的 my-nginx 容器連接到一個已經存在的 my-net 網路
$ docker network connect my-net my-nginx
將容器從使用者定義的橋接網路中斷開
要將正在執行的容器從使用者定義的橋接網路中斷開連線,請使用 docker network disconnect 指令。以下指令將 my-nginx 容器從 my-net 網路中斷開。
$ docker network disconnect my-net my-nginx
在使用者定義的橋接網路中使用 IPv6
當您建立網路時,可以指定 --ipv6 旗標來啟用 IPv6。
$ docker network create --ipv6 --subnet 2001:db8:1234::/64 my-net
如果您未提供 --subnet 選項,將會自動選擇一個唯一本地位址 (ULA) 前綴。
僅限 IPv6 的橋接網路
若要在橋接器及其容器上跳過 IPv4 位址配置,請使用選項 --ipv4=false 建立網路,並使用 --ipv6 啟用 IPv6。
$ docker network create --ipv6 --ipv4=false v6net
在預設橋接網路中,IPv4 位址配置無法禁用。
使用預設橋接網路
預設的 bridge 網路被視為 Docker 的一個過時細節,不建議用於生產環境。配置它需要手動操作,並且它具有技術上的缺點。
將容器連接到預設橋接網路
如果您未指定 --network 旗標來指定網路,但指定了網路驅動程式,則您的容器預設會連接到預設的 bridge 網路。連接到預設 bridge 網路的容器可以通訊,但只能透過 IP 位址,除非它們使用過時的 --link 旗標連結。
配置預設橋接網路
要配置預設的 bridge 網路,您可以在 daemon.json 中指定選項。以下是一個包含多個指定選項的 daemon.json 範例。僅指定您需要自訂的設定。
{
"bip": "192.168.1.1/24",
"fixed-cidr": "192.168.1.0/25",
"mtu": 1500,
"default-gateway": "192.168.1.254",
"dns": ["10.20.1.2","10.20.1.3"]
}在此範例中
- 橋接器的位址是 "192.168.1.1/24" (來自
bip)。 - 橋接網路的子網路是 "192.168.1.0/24" (來自
bip)。 - 容器位址將從 "192.168.1.0/25" (來自
fixed-cidr) 分配。
在預設橋接網路中使用 IPv6
可以透過在 daemon.json 中使用以下選項或其命令列等效項來為預設橋接器啟用 IPv6。
這三個選項僅影響預設橋接器,不被使用者定義的網路使用。以下位址是來自 IPv6 文件範圍的範例。
- 選項
ipv6是必需的。 - 選項
bip6是可選的,它指定了預設橋接器的位址,該位址將被容器用作預設閘道器。它還指定了橋接網路的子網路。 - 選項
fixed-cidr-v6是可選的,它指定了 Docker 可能自動分配給容器的位址範圍。- 前綴通常應該是
/64或更短。 - 對於在本地網路上的實驗,使用唯一本地位址 (ULA) 前綴(匹配
fd00::/8)比使用連結本地前綴(匹配fe80::/10)更好。
- 前綴通常應該是
- 選項
default-gateway-v6是可選的。如果未指定,預設是fixed-cidr-v6子網路中的第一個位址。
{
"ipv6": true,
"bip6": "2001:db8::1111/64",
"fixed-cidr-v6": "2001:db8::/64",
"default-gateway-v6": "2001:db8:abcd::89"
}如果未指定 bip6,則 fixed-cidr-v6 定義橋接網路的子網路。如果未指定 bip6 或 fixed-cidr-v6,則將選擇一個 ULA 前綴。
重新啟動 Docker 以使變更生效。
橋接網路的連線限制
由於 Linux 核心設定的限制,當 1000 個或更多容器連接到單一網路時,橋接網路會變得不穩定,並且容器間的通訊可能會中斷。
有關此限制的更多資訊,請參閱 moby/moby#44973。
跳過橋接 IP 位址配置
橋接器通常會被指派網路的 --gateway 位址,該位址用作從橋接網路到其他網路的預設路由。
com.docker.network.bridge.inhibit_ipv4 選項允許您建立一個網路,而不將 IPv4 閘道器位址指派給橋接器。如果您想手動配置橋接器的閘道器 IP 位址,這會很有用。例如,如果您將實體介面新增到您的橋接器,並且需要它具有閘道器位址。
在此配置下,南北向流量(往返橋接網路)將無法工作,除非您已在橋接器上或連接到橋接器的裝置上手動配置閘道器位址。
此選項只能用於使用者定義的橋接網路。