網路概覽

容器網路是指容器連線到並相互通訊,或與非 Docker 工作負載通訊的能力。

容器預設啟用網路,並且可以建立出站連線。容器沒有關於其附加到哪種網路的資訊,也不知道其對等方是否也是 Docker 工作負載。容器只能看到一個帶有 IP 地址、閘道器、路由表、DNS 服務和其他網路細節的網路介面。除非容器使用 none 網路驅動程式。

本頁從容器的角度描述網路以及圍繞容器網路的概念。本頁不描述有關 Docker 網路如何工作的特定於作業系統的詳細資訊。有關 Docker 如何在 Linux 上操作 iptables 規則的資訊,請參閱資料包過濾和防火牆

使用者定義的網路

您可以建立自定義的使用者定義網路,並將多個容器連線到同一個網路。一旦連線到使用者定義的網路,容器就可以使用容器 IP 地址或容器名稱相互通訊。

以下示例使用 bridge 網路驅動程式建立一個網路,並在建立的網路中執行一個容器

$ docker network create -d bridge my-net
$ docker run --network=my-net -itd --name=container3 busybox

驅動程式

以下網路驅動程式預設可用,並提供核心網路功能

驅動程式描述
bridge預設網路驅動程式。
host移除容器和 Docker 主機之間的網路隔離。
none將容器與主機和其他容器完全隔離。
overlay覆蓋網路將多個 Docker 守護程序連線在一起。
ipvlanIPvlan 網路提供對 IPv4 和 IPv6 定址的完全控制。
macvlan為容器分配一個 MAC 地址。

有關不同驅動程式的更多資訊,請參閱網路驅動程式概述

連線到多個網路

一個容器可以連線到多個網路。

例如,一個前端容器可以連線到一個具有外部訪問許可權的橋接網路,以及一個用於與執行後端服務的容器通訊的--internal網路,這些後端服務不需要外部網路訪問。

一個容器也可以連線到不同型別的網路。例如,一個 ipvlan 網路用於提供網際網路訪問,而一個 bridge 網路用於訪問本地服務。

傳送資料包時,如果目標是直接連線網路中的地址,資料包將傳送到該網路。否則,資料包將傳送到預設閘道器以路由到其目標。在上面的示例中,ipvlan 網路的閘道器必須是預設閘道器。

預設閘道器由 Docker 選擇,並且可能在容器的網路連線發生變化時改變。要在建立容器或連線新網路時讓 Docker 選擇特定的預設閘道器,請設定閘道器優先順序。請參閱 docker rundocker network connect 命令的 gw-priority 選項。

預設的 gw-priority0,具有最高優先順序的網路中的閘道器是預設閘道器。因此,當一個網路應該始終是預設閘道器時,將其 gw-priority 設定為 1 就足夠了。

$ docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
$ docker network connect anet2 myctr

容器網路

除了使用者定義的網路之外,您還可以使用 --network container:<name|id> 標誌格式將一個容器直接附加到另一個容器的網路堆疊。

對於使用 container: 網路模式的容器,不支援以下標誌

  • --add-host
  • --hostname
  • --dns
  • --dns-search
  • --dns-option
  • --mac-address
  • --publish
  • --publish-all
  • --expose

以下示例執行一個 Redis 容器,其中 Redis 繫結到 localhost,然後執行 redis-cli 命令並透過 localhost 介面連線到 Redis 伺服器。

$ docker run -d --name redis example/redis --bind 127.0.0.1
$ docker run --rm -it --network container:redis example/redis-cli -h 127.0.0.1

已釋出的埠

預設情況下,當您使用 docker createdocker run 建立或執行容器時,橋接網路上的容器不會向外界暴露任何埠。使用 --publish-p 標誌使埠可用於橋接網路之外的服務。這會在主機中建立一個防火牆規則,將容器埠對映到 Docker 主機上的一個埠,以供外界訪問。以下是一些示例

標誌值描述
-p 8080:80將 Docker 主機上的 8080 埠對映到容器中的 TCP 80 埠。
-p 192.168.1.100:8080:80將 Docker 主機 IP 192.168.1.100 上的 8080 埠對映到容器中的 TCP 80 埠。
-p 8080:80/udp將 Docker 主機上的 8080 埠對映到容器中的 UDP 80 埠。
-p 8080:80/tcp -p 8080:80/udp將 Docker 主機上的 TCP 8080 埠對映到容器中的 TCP 80 埠,並將 Docker 主機上的 UDP 8080 埠對映到容器中的 UDP 80 埠。
重要

釋出容器埠預設是不安全的。這意味著,當您釋出一個容器的埠時,它不僅對 Docker 主機可用,也對外部世界可用。

如果您在釋出標誌中包含 localhost IP 地址(127.0.0.1::1),則只有 Docker 主機及其容器可以訪問已釋出的容器埠。

$ docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' nginx
警告

在 28.0.0 之前的版本中,同一 L2 網段內的主機(例如,連線到同一網路交換機的主機)可以訪問釋出到 localhost 的埠。有關更多資訊,請參閱 moby/moby#45610

如果您想讓一個容器可以被其他容器訪問,則不必釋出該容器的埠。您可以透過將容器連線到同一個網路(通常是橋接網路)來啟用容器間通訊。

如果埠對映中未給出主機 IP,橋接網路僅為 IPv4,且 --userland-proxy=true(預設),則主機 IPv6 地址上的埠將對映到容器的 IPv4 地址。

有關埠對映的更多資訊,包括如何停用它以及使用直接路由到容器的方法,請參閱資料包過濾和防火牆

IP 地址和主機名

建立網路時,預設啟用 IPv4 地址分配,可以使用 --ipv4=false 停用。可以使用 --ipv6 啟用 IPv6 地址分配。

$ docker network create --ipv6 --ipv4=false v6net

預設情況下,容器會為其附加的每個 Docker 網路獲取一個 IP 地址。容器從網路的 IP 子網中接收一個 IP 地址。Docker 守護程序為容器執行動態子網劃分和 IP 地址分配。每個網路還有一個預設的子網掩碼和閘道器。

您可以將一個正在執行的容器連線到多個網路,方法是在建立容器時多次傳遞 --network 標誌,或者對已在執行的容器使用 docker network connect 命令。在這兩種情況下,您都可以使用 --ip--ip6 標誌來指定容器在該特定網路上的 IP 地址。

同樣,容器的主機名預設為 Docker 中的容器 ID。您可以使用 --hostname 覆蓋主機名。當使用 docker network connect 連線到現有網路時,您可以使用 --alias 標誌為該網路上的容器指定一個額外的網路別名。

DNS 服務

預設情況下,容器使用與主機相同的 DNS 伺服器,但您可以使用 --dns 覆蓋此設定。

預設情況下,容器繼承 /etc/resolv.conf 配置檔案中定義的 DNS 設定。附加到預設 bridge 網路的容器會收到此檔案的一個副本。附加到自定義網路的容器使用 Docker 的嵌入式 DNS 伺服器。嵌入式 DNS 伺服器將外部 DNS 查詢轉發到主機上配置的 DNS 伺服器。

您可以在每個容器的基礎上配置 DNS 解析,方法是使用用於啟動容器的 docker rundocker create 命令的標誌。下表描述了與 DNS 配置相關的可用 docker run 標誌。

標誌描述
--dnsDNS 伺服器的 IP 地址。要指定多個 DNS 伺服器,請使用多個 --dns 標誌。DNS 請求將從容器的網路名稱空間轉發,因此,例如,--dns=127.0.0.1 指的是容器自己的環回地址。
--dns-search一個 DNS 搜尋域,用於搜尋非完全限定的主機名。要指定多個 DNS 搜尋字首,請使用多個 --dns-search 標誌。
--dns-opt表示 DNS 選項及其值的鍵值對。有關有效選項,請參閱您作業系統的 resolv.conf 文件。
--hostname容器為自己使用的主機名。如果未指定,則預設為容器的 ID。

自定義主機

您的容器將在 /etc/hosts 中包含定義容器本身主機名以及 localhost 和其他一些常見內容的行。在主機上 /etc/hosts 中定義的自定義主機不會被容器繼承。要將其他主機傳遞到容器中,請參閱 docker run 參考文件中的向容器 hosts 檔案新增條目

代理伺服器

如果您的容器需要使用代理伺服器,請參閱使用代理伺服器