Docker 網路模式與容器間通訊

Docker 的網路功能是容器化技術中非常重要的一環。了解 Docker 網路模式可以幫助我們更好地設計和部署容器化應用程式。本文將介紹 Docker 的網路驅動類型、如何建立自訂網路、容器間通訊以及 DNS 解析機制。

網路驅動類型

Docker 提供了多種網路驅動(Network Driver),每種驅動適用於不同的使用場景。

Bridge 網路

Bridge 是 Docker 預設的網路模式。當你啟動一個容器而沒有指定網路時,容器會自動連接到預設的 bridge 網路。

1
2
3
4
5
# 查看預設的 bridge 網路
docker network ls

# 使用預設 bridge 網路啟動容器
docker run -d --name web nginx

Bridge 網路的特點:

  • 容器之間可以透過 IP 位址互相通訊
  • 容器可以透過 NAT 存取外部網路
  • 外部網路需要透過端口映射才能存取容器

Host 網路

Host 模式會讓容器直接使用宿主機的網路堆疊,容器不會獲得獨立的網路命名空間。

1
2
# 使用 host 網路模式啟動容器
docker run -d --network host --name web nginx

Host 網路的特點:

  • 容器直接使用宿主機的 IP 和端口
  • 沒有網路隔離,效能較好
  • 可能會有端口衝突問題
  • 僅適用於 Linux 系統

None 網路

None 模式會完全禁用容器的網路功能,容器只有 loopback 介面。

1
2
# 使用 none 網路模式啟動容器
docker run -d --network none --name isolated alpine sleep 3600

None 網路的特點:

  • 完全的網路隔離
  • 適用於不需要網路的批次處理任務
  • 適用於需要自訂網路設定的場景

Overlay 網路

Overlay 網路用於連接多個 Docker daemon,通常用於 Docker Swarm 或跨主機的容器通訊。

1
2
3
4
5
# 建立 overlay 網路(需要 Swarm 模式)
docker network create -d overlay my-overlay

# 在 overlay 網路中建立服務
docker service create --network my-overlay --name web nginx

Overlay 網路的特點:

  • 支援跨主機的容器通訊
  • 自動處理容器間的路由
  • 支援加密通訊
  • 需要 Swarm 模式或外部的 key-value 儲存

建立自訂網路

使用自訂網路可以更好地控制容器間的通訊和隔離。

建立 Bridge 網路

1
2
3
4
5
6
7
8
9
# 建立自訂 bridge 網路
docker network create my-network

# 建立時指定子網路和閘道
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  my-custom-network

將容器連接到網路

1
2
3
4
5
6
7
8
# 啟動容器時指定網路
docker run -d --network my-network --name app1 nginx

# 將執行中的容器連接到網路
docker network connect my-network existing-container

# 將容器從網路斷開
docker network disconnect my-network existing-container

查看網路資訊

1
2
3
4
5
6
7
8
# 列出所有網路
docker network ls

# 查看網路詳細資訊
docker network inspect my-network

# 刪除網路
docker network rm my-network

容器間通訊

容器間的通訊方式會根據所使用的網路類型而有所不同。

預設 Bridge 網路

在預設的 bridge 網路中,容器只能透過 IP 位址互相通訊:

1
2
3
4
5
6
7
8
9
# 啟動兩個容器
docker run -d --name container1 nginx
docker run -d --name container2 nginx

# 查看 container1 的 IP
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

# 從 container2 ping container1(使用 IP)
docker exec container2 ping 172.17.0.2

自訂 Bridge 網路

在自訂網路中,Docker 會提供內建的 DNS 服務,容器可以透過名稱互相通訊:

1
2
3
4
5
6
7
8
9
# 建立自訂網路
docker network create app-network

# 啟動容器並連接到自訂網路
docker run -d --network app-network --name web nginx
docker run -d --network app-network --name db mysql:8

# 從 web 容器 ping db 容器(使用容器名稱)
docker exec web ping db

使用 Docker Compose

Docker Compose 會自動建立網路並處理容器間的通訊:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    ports:
      - "80:80"
    depends_on:
      - api

  api:
    image: node:18
    environment:
      - DB_HOST=db

  db:
    image: mysql:8
    environment:
      - MYSQL_ROOT_PASSWORD=secret

在這個配置中,web 可以透過 api 名稱存取 API 服務,api 可以透過 db 名稱存取資料庫。

DNS 解析

Docker 的 DNS 解析是容器間通訊的重要機制。

內建 DNS 伺服器

自訂網路中的容器會使用 Docker 的內建 DNS 伺服器(127.0.0.11):

1
2
# 查看容器的 DNS 設定
docker exec container1 cat /etc/resolv.conf

輸出範例:

1
2
nameserver 127.0.0.11
options ndots:0

DNS 解析規則

Docker DNS 解析遵循以下規則:

  1. 容器名稱:可以直接使用容器名稱進行解析
  2. 服務名稱:在 Swarm 模式中,可以使用服務名稱
  3. 網路別名:可以為容器設定網路別名
1
2
3
4
5
# 設定網路別名
docker run -d --network my-network --network-alias webserver --name web nginx

# 其他容器可以透過 webserver 或 web 存取這個容器
docker exec other-container ping webserver

自訂 DNS 設定

可以在啟動容器時自訂 DNS 設定:

1
2
3
4
5
6
7
8
# 指定 DNS 伺服器
docker run -d --dns 8.8.8.8 --name web nginx

# 指定 DNS 搜尋域
docker run -d --dns-search example.com --name web nginx

# 新增額外的 hosts 記錄
docker run -d --add-host myhost:192.168.1.100 --name web nginx

網路故障排除

當遇到網路問題時,可以使用以下方法進行故障排除:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看容器的網路設定
docker inspect --format='{{json .NetworkSettings}}' container_name | jq

# 測試容器間的連通性
docker exec container1 ping container2

# 查看容器的網路介面
docker exec container1 ip addr

# 查看容器的路由表
docker exec container1 ip route

# 使用 tcpdump 抓包(需要安裝)
docker exec container1 tcpdump -i eth0

總結

Docker 網路是容器化應用程式的重要組成部分。選擇合適的網路模式可以滿足不同的需求:

網路模式適用場景
Bridge單機上的多容器通訊,需要網路隔離
Host需要最佳網路效能,不需要網路隔離
None完全隔離,不需要網路功能
Overlay跨主機的容器通訊,Swarm 服務

建議在生產環境中使用自訂網路,這樣可以獲得更好的隔離性和內建的 DNS 解析功能。透過合理的網路規劃,可以建立安全、高效的容器化應用架構。

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy