網路概覽
容器網路是指容器連線到並相互通訊,或與非 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 守護程序連線在一起。 |
ipvlan | IPvlan 網路提供對 IPv4 和 IPv6 定址的完全控制。 |
macvlan | 為容器分配一個 MAC 地址。 |
有關不同驅動程式的更多資訊,請參閱網路驅動程式概述。
連線到多個網路
一個容器可以連線到多個網路。
例如,一個前端容器可以連線到一個具有外部訪問許可權的橋接網路,以及一個用於與執行後端服務的容器通訊的--internal
網路,這些後端服務不需要外部網路訪問。
一個容器也可以連線到不同型別的網路。例如,一個 ipvlan
網路用於提供網際網路訪問,而一個 bridge
網路用於訪問本地服務。
傳送資料包時,如果目標是直接連線網路中的地址,資料包將傳送到該網路。否則,資料包將傳送到預設閘道器以路由到其目標。在上面的示例中,ipvlan
網路的閘道器必須是預設閘道器。
預設閘道器由 Docker 選擇,並且可能在容器的網路連線發生變化時改變。要在建立容器或連線新網路時讓 Docker 選擇特定的預設閘道器,請設定閘道器優先順序。請參閱 docker run
和 docker network connect
命令的 gw-priority
選項。
預設的 gw-priority
是 0
,具有最高優先順序的網路中的閘道器是預設閘道器。因此,當一個網路應該始終是預設閘道器時,將其 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 create
或 docker 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 run
或 docker create
命令的標誌。下表描述了與 DNS 配置相關的可用 docker run
標誌。
標誌 | 描述 |
---|---|
--dns | DNS 伺服器的 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 檔案新增條目。
代理伺服器
如果您的容器需要使用代理伺服器,請參閱使用代理伺服器。