介紹
Docker 容器被設計為可移植和隔離的,但它們很少單獨運行。容器需要相互通訊、與主機系統以及外部服務通訊。了解 Docker 的網路模型對於建立可靠、安全且高效能的容器化應用程式至關重要。
Docker 提供了多種內建網路驅動程式——bridge、host、overlay、macvlan、ipvlan 和 none——每種驅動程式都適合不同的用例。本指南深入介紹了每個驅動程序,以及 DNS 解析、連接埠映射、安全隔離和 Docker Compose 網路模式。
了解 Docker 網路驅動程式
每個容器都有一個連接到主機的虛擬網路介面(veth 對)。 Docker 使用 網路命名空間 為每個容器提供一個獨立的網路堆疊,並擁有自己的 IP 位址、路由表和連接埠。
docker network 指令是管理網路的控制中心:
# List all networks
docker network ls
# Create a user-defined bridge network
docker network create my-network
# Inspect network details
docker network inspect my-network
# Connect a running container to a network
docker network connect my-network my-container
以下是Docker內建網路驅動的比較:
| 司機 | 範圍 | 使用案例 | DNS解析 |
|---|---|---|---|
| 橋樑 | 單主機 | 獨立容器的預設值 | 僅限使用者定義 |
| 主持人 | 單主機 | 低延遲,無需隔離 | 不適用(主機 DNS) |
| 覆蓋 | 多主機 | Swarm 服務、跨主機通訊 | 是的 |
| 麥克弗蘭 | 單主機 | 需要 MAC 位址的舊版應用程式 | 是的 |
| ipvlan | 單主機 | 高效能、大型子網路 | 是的 |
| 無 | 單主機 | 最大程度的隔離 | 無 |
橋接網路的實踐
橋接網路是 Docker 的預設驅動程式。當 Docker 啟動時,它會在主機上建立一個名為 docker0 的虛擬網橋,並預設從 172.17.0.0/16 子網路指派容器 IP。
預設網橋有限制:沒有自動 DNS 解析,且所有容器都無隔離地連接。 使用者定義的橋解決這些問題:
docker network create my-app-net
docker run -d --name web --net my-app-net nginx
docker run -d --name api --net my-app-net node:18
同一使用者定義橋上的容器可以透過容器名稱相互解析:
# From the api container, this resolves to web's IP
ping web
連接埠發布透過 iptables DNAT 規則將主機連接埠對應到容器連接埠:
# Map host port 8080 to container port 80
docker run -p 8080:80 nginx
主機和覆蓋網絡
主機網路
使用 --network host,容器直接共享主機的網路堆疊 — 無 NAT,無虛擬接口,且延遲最小。這對於效能基準測試或需要監視主機介面的應用程式非常有用。但是,不存在網路隔離:容器可以綁定到任何主機連接埠並可能幹擾其他服務。
# docker-compose.yml
services:
benchmark:
image: tool:latest
network_mode: "host"
覆蓋網路
覆蓋網路支援跨多個 Docker 主機進行通訊。在 Swarm 模式下,建立覆蓋網路會自動將其分發到所有節點:
docker network create -d overlay --attachable my-overlay
在底層,覆蓋網路使用 VXLAN 封裝來包裝容器資料包,允許它們穿越實體網路邊界。可以使用 --opt encrypted 標誌透過 IPsec 對流量進行加密。效能開銷約為每個資料包 50 字節,吞吐量降低 5-10%。
DNS解析和服務發現
Docker 在每個容器內的 127.0.0.11 處執行嵌入式 DNS 伺服器。此伺服器將容器名稱解析為使用者定義的橋接和覆蓋網路上的 IP 位址。預設橋不提供 DNS 解析 - 您必須使用 --link (舊版)或切換到使用者定義的橋。
在 Swarm 模式下,Docker DNS 為具有多個副本的服務提供循環解析:
# Create a service with 3 replicas
docker service create --name api --replicas 3 --network my-overlay my-api:latest
# Other containers resolve "api" to one of the 3 replicas via DNS round-robin
自訂 DNS 設定可以應用於每個容器:
docker run --dns 8.8.8.8 --dns-search example.com nginx
連接埠對映和安全隔離
連接埠映射將主機連接埠轉換為容器連接埠。 -p 標誌接受格式 hostPort:containerPort/protocol:
# Multiple ports, specific interface binding
docker run -p 127.0.0.1:8080:80 -p 443:443 nginx
對於網路隔離,Docker提供了幾種機制:
- 內部網路 (
--internal) — 容器無法存取網際網路。 - 無網路 (
--network none) — 僅環回,最大隔離。 - 單獨的網橋 — 根據信任等級將容器保留在不同的使用者定義的網橋上。
Docker 沒有像 Kubernetes 那樣內建網路策略。若要進行細粒度控制,請使用 iptables、firewalld 或第三方插件,例如 Calico、Weave 或 Cilium。
Docker Compose 網路模式
Docker Compose 為每個專案建立一個使用者定義的橋接網路 (<project>_default)。您可以在 Compose 檔案中定義多個自訂網路來分隔關注點:
services:
web:
image: nginx
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
redis:
image: redis
networks:
- backend
networks:
frontend:
backend:
此模式將面向公眾的 Web 層與內部資料層分開。 web 服務連接到兩個網絡,而 db 和 redis 只能在內部 backend 網路上存取。
若要連接到預先存在的網路(例如共用監控網路),請使用外部網路:
networks:
monitoring:
external: true
擴展服務時,每個副本在同一網路上都有自己的容器。將 depends_on 與 healthcheck 和 condition 結合使用以確保服務已準備就緒,而不是只依賴啟動順序。
結論
Docker 的網路模型為容器通訊提供了靈活、安全且高效能的選項。從針對單主機多容器應用程式的使用者定義的橋接網路開始 - 它們提供自動 DNS 解析和比預設橋接更好的隔離。對於多主機部署,請使用具有 Docker Swarm 的 覆蓋網路。
設計網路拓撲時:
- 優先選擇基於 DNS 的服務發現,而不是硬編碼的 IP 位址。
- 使用單獨的橋接網路根據信任等級隔離各層。
- 僅當延遲或介面存取至關重要時才選擇主機網路。
- 利用 Compose 網路定義使您的基礎設施具有聲明性和可複製性。
將 docker network inspect、docker exec 的網路問題偵錯到容器中以執行 ip addr 和 tcpdump,並檢查防火牆規則是否有跨主機連線問題。有了這些基礎知識,您就可以建立強大且易於管理的容器網路。

