伦伦影院久久影视,天天操天天干天天射,ririsao久久精品一区 ,一本大道香蕉大久在红桃,999久久久免费精品国产色夜,色悠悠久久综合88,亚洲国产精品久久无套麻豆,亚洲香蕉毛片久久网站,一本一道久久综合狠狠老

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Docker容器網絡模式全解析

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 2026-02-26 16:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Docker網絡模式詳解

一、概述

1.1 背景介紹

容器網絡是Docker使用中最容易出問題的部分。容器之間怎么通信、容器怎么訪問外網、外部怎么訪問容器內的服務——這三個問題搞不清楚,排查網絡故障就是抓瞎。

Docker網絡基于Linux內核的Network Namespace、veth pair、iptables和bridge實現。每個容器有自己獨立的網絡命名空間,通過veth pair連接到宿主機的網橋(docker0),再通過iptables NAT規則訪問外網。理解這個數據包流向,網絡問題排查就有了方向。

Docker提供了bridge、host、none、container、overlay、macvlan六種網絡模式,每種模式的隔離級別、性能、適用場景都不同。單機環境用bridge和host就夠了,跨主機通信需要overlay或macvlan。

1.2 技術特點

bridge模式:默認模式,通過docker0網橋和veth pair實現容器間通信,通過iptables NAT實現外網訪問。隔離性好,有約5%-10%的網絡性能損耗

host模式:容器直接使用宿主機網絡棧,沒有NAT開銷,網絡性能和宿主機一致。但失去了網絡隔離性

none模式:容器沒有網絡接口(只有lo),完全隔離。適合不需要網絡的批處理任務或安全敏感場景

container模式:多個容器共享同一個網絡命名空間,通過localhost通信。Kubernetes的Pod網絡就是基于這個原理

overlay模式:基于VXLAN的跨主機容器網絡,Docker Swarm和部分K8s網絡插件使用

macvlan模式:容器直接獲得物理網絡的IP地址,像一臺獨立的物理機。適合需要直接接入物理網絡的場景

1.3 適用場景

bridge模式:大多數單機容器部署場景,開發測試環境

host模式:對網絡性能要求高的應用(Nginx反向代理、高頻交易系統),需要監聽大量端口的應用

none模式:安全隔離要求高的計算任務,不需要網絡的數據處理容器

container模式:Sidecar模式(日志收集、監控代理),需要共享網絡的緊耦合容器

overlay模式:Docker Swarm集群中的跨主機服務通信

macvlan模式:需要容器擁有獨立MAC地址和IP的場景,傳統網絡架構遷移

1.4 環境要求

組件 版本要求 說明
Docker Engine 20.10+(推薦24.0+) 基本網絡功能所有版本都支持
Linux內核 3.10+(推薦5.4+) overlay需要4.0+內核的VXLAN支持
iptables 1.4+ bridge模式的NAT依賴iptables
bridge-utils 任意版本 調試用,brctl命令查看網橋信息
iproute2 任意版本 調試用,ip命令查看網絡配置
tcpdump 任意版本 抓包分析用

二、詳細步驟

2.1 準備工作

2.1.1 系統檢查

# 檢查內核網絡模塊
lsmod | grep -E"bridge|vxlan|macvlan|overlay"

# 檢查IP轉發是否開啟
sysctl net.ipv4.ip_forward
# 必須為1

# 檢查iptables
iptables -L -n
iptables -t nat -L -n

# 檢查docker0網橋
ip addr show docker0
brctl show docker0

# 安裝網絡調試工具
sudo apt install -y bridge-utils tcpdump iproute2 net-tools # Debian/Ubuntu
sudo yum install -y bridge-utils tcpdump iproute net-tools  # CentOS/RHEL

2.1.2 查看當前Docker網絡

# 查看所有Docker網絡
docker network ls

# 默認會有三個網絡:
# bridge - 默認bridge網絡
# host  - host網絡
# none  - 無網絡

# 查看bridge網絡詳情
docker network inspect bridge

# 查看網絡中的容器
docker network inspect bridge --format='{{range .Containers}}{{.Name}}: {{.IPv4Address}}{{"
"}}{{end}}'

2.2 核心配置

2.2.1 Bridge模式詳解

Bridge是Docker默認的網絡模式。Docker啟動時會創建一個docker0虛擬網橋,每個容器通過veth pair連接到docker0,容器之間通過網橋二層轉發通信,訪問外網通過iptables MASQUERADE做源地址轉換。

數據包流向

容器eth0 → veth pair → docker0網橋 → iptables NAT → 宿主機eth0 → 外網
# 創建自定義bridge網絡(推薦,比默認bridge功能更多)
docker network create 
 --driver bridge 
 --subnet 172.20.0.0/24 
 --gateway 172.20.0.1 
 --opt"com.docker.network.bridge.name"="br-mynet"
 --opt"com.docker.network.bridge.enable_icc"="true"
 --opt"com.docker.network.bridge.enable_ip_masquerade"="true"
 mynet

# 查看創建的網橋
brctl show
ip addr show br-mynet

# 在自定義網絡中運行容器
docker run -d --name web1 --network mynet nginx:1.24-alpine
docker run -d --name web2 --network mynet nginx:1.24-alpine

# 自定義網絡支持容器名DNS解析(默認bridge不支持)
dockerexecweb1 ping -c 3 web2
# 能ping通,通過Docker內置DNS解析容器名

# 指定容器IP
docker run -d --name web3 --network mynet --ip 172.20.0.100 nginx:1.24-alpine

# 查看容器網絡配置
dockerexecweb1 ip addr
dockerexecweb1 ip route
dockerexecweb1 cat /etc/resolv.conf

默認bridge和自定義bridge的區別

特性 默認bridge 自定義bridge
容器名DNS解析 不支持(只能用IP) 支持(推薦)
容器間隔離 同網絡內全部互通 同網絡內互通,不同網絡隔離
熱插拔 不支持 支持(docker network connect/disconnect)
自定義子網 不方便 創建時指定

注意:生產環境不要用默認bridge網絡,用自定義bridge。默認bridge不支持容器名DNS解析,容器重啟后IP可能變化,用IP通信會斷。

2.2.2 Host模式詳解

Host模式下容器直接使用宿主機的網絡命名空間,沒有網絡隔離,也沒有NAT轉換開銷。容器內看到的網絡接口和宿主機完全一樣。

# 使用host網絡運行容器
docker run -d --name nginx-host --network host nginx:1.24-alpine

# 不需要-p端口映射,Nginx直接監聽宿主機的80端口
curl http://localhost:80

# 查看容器網絡(和宿主機一樣)
dockerexecnginx-host ip addr
# 輸出和宿主機的 ip addr 完全一致

# 查看端口占用
ss -tlnp | grep 80
# 能看到nginx進程直接監聽在宿主機上

Host模式的性能對比

# 用iperf3測試bridge和host模式的網絡吞吐量差異

# 啟動iperf3服務端(bridge模式)
docker run -d --name iperf-bridge -p 5201:5201 networkstatic/iperf3 -s

# 啟動iperf3服務端(host模式)
docker run -d --name iperf-host --network host networkstatic/iperf3 -s

# 測試bridge模式吞吐量
docker run --rm networkstatic/iperf3 -c <宿主機IP> -p 5201
# 典型結果:約30-40 Gbps(取決于硬件)

# 測試host模式吞吐量
docker run --rm --network host networkstatic/iperf3 -c 127.0.0.1 -p 5201
# 典型結果:約45-50 Gbps
# host模式比bridge模式吞吐量高約15%-25%

警告:host模式下容器端口直接占用宿主機端口,多個容器不能監聽同一端口。而且容器能看到宿主機所有網絡接口和連接,安全隔離性為零。

2.2.3 None模式詳解

None模式下容器只有lo回環接口,沒有任何外部網絡連接。適合不需要網絡的計算任務,或者需要完全自定義網絡的場景。

# 使用none網絡運行容器
docker run -d --name isolated --network none alpine sleep 3600

# 查看容器網絡接口(只有lo)
dockerexecisolated ip addr
# 輸出:
# 1: lo:  mtu 65536
#   inet 127.0.0.1/8 scope host lo

# 驗證無法訪問外網
dockerexecisolated ping -c 1 8.8.8.8
# ping: sendto: Network is unreachable

# 適用場景:數據加密/解密處理
docker run --rm --network none 
 -v /data/input:/input:ro 
 -v /data/output:/output 
 crypto-tool encrypt /input/data.bin /output/data.enc

2.2.4 Container模式詳解

Container模式讓一個容器共享另一個容器的網絡命名空間。兩個容器通過localhost通信,共享IP地址和端口空間。Kubernetes的Pod就是基于這個原理——Pod內所有容器共享同一個網絡命名空間。

# 先啟動一個基礎容器
docker run -d --name base-container -p 8080:80 nginx:1.24-alpine

# 啟動第二個容器,共享base-container的網絡
docker run -d --name sidecar --network container:base-container alpine sleep 3600

# sidecar可以通過localhost訪問nginx
dockerexecsidecar wget -qO- http://localhost:80
# 返回Nginx默認頁面

# 兩個容器的網絡接口完全一樣
dockerexecbase-container ip addr
dockerexecsidecar ip addr
# 輸出一致

# 典型應用:日志收集sidecar
docker run -d --name app -p 8080:8080 myapp:1.0
docker run -d --namelog-collector 
 --network container:app 
 -v /data/logs:/logs 
 fluentd:v1.16
# log-collector通過localhost收集app的日志

2.2.5 Overlay模式詳解

Overlay網絡基于VXLAN隧道實現跨主機容器通信。數據包在源主機封裝VXLAN頭部,通過UDP 4789端口發送到目標主機,目標主機解封裝后轉發給目標容器。

# 初始化Docker Swarm(overlay網絡需要Swarm模式)
docker swarm init --advertise-addr 192.168.1.10

# 在其他節點加入Swarm
# docker swarm join --token  192.168.1.10:2377

# 創建overlay網絡
docker network create 
 --driver overlay 
 --subnet 10.10.0.0/24 
 --gateway 10.10.0.1 
 --attachable 
 my-overlay

# --attachable 允許非Swarm服務的獨立容器也能加入這個網絡

# 在overlay網絡中部署服務
docker service create 
 --name web 
 --network my-overlay 
 --replicas 3 
 -p 80:80 
 nginx:1.24-alpine

# 驗證跨主機通信
docker service ps web
# 三個副本分布在不同節點上,通過overlay網絡互通

注意:overlay網絡有約10%-15%的性能損耗(VXLAN封裝/解封裝開銷)。對延遲敏感的應用(如Redis集群),建議用macvlan或host模式。

2.2.6 Macvlan模式詳解

Macvlan讓容器直接獲得物理網絡的IP地址,每個容器有獨立的MAC地址,在網絡上表現得像一臺獨立的物理機。不經過NAT,網絡性能接近原生。

# 創建macvlan網絡
# 需要知道宿主機的物理網卡名和所在網段
docker network create 
 --driver macvlan 
 --subnet 192.168.1.0/24 
 --gateway 192.168.1.1 
 --opt parent=eth0 
 my-macvlan

# 運行容器(指定IP)
docker run -d --name db 
 --network my-macvlan 
 --ip 192.168.1.200 
 mysql:8.0.35

# 容器直接擁有192.168.1.200這個IP
# 同網段的其他機器可以直接訪問192.168.1.200:3306

# 查看容器MAC地址
dockerexecdb ip link show eth0
# 每個容器有獨立的MAC地址

注意:macvlan模式下,容器和宿主機之間默認無法通信(這是macvlan的設計限制)。如果需要宿主機訪問容器,需要在宿主機上創建macvlan子接口:

# 在宿主機上創建macvlan子接口
ip link add macvlan-host link eth0typemacvlan mode bridge
ip addr add 192.168.1.201/24 dev macvlan-host
ip linksetmacvlan-host up
# 現在宿主機可以通過192.168.1.201訪問macvlan網絡中的容器

2.2.7 容器網絡互聯

# 將容器連接到多個網絡
docker network create frontend --subnet 172.20.0.0/24
docker network create backend --subnet 172.21.0.0/24

# Nginx連接到frontend
docker run -d --name nginx --network frontend -p 80:80 nginx:1.24-alpine

# App連接到frontend和backend
docker run -d --name app --network frontend myapp:1.0
docker network connect backend app

# MySQL只連接到backend
docker run -d --name mysql --network backend mysql:8.0.35

# 網絡拓撲:
# 外部 → Nginx(frontend) → App(frontend+backend) → MySQL(backend)
# Nginx無法直接訪問MySQL(不在同一網絡)
# App可以同時訪問Nginx和MySQL

# 斷開容器的網絡連接
docker network disconnect frontend app

2.3 啟動和驗證

2.3.1 端口映射詳解

# 映射到宿主機所有接口
docker run -d -p 8080:80 nginx:1.24-alpine
# 等價于 -p 0.0.0.080

# 映射到指定接口(安全,只監聽內網)
docker run -d -p 192.168.1.1080 nginx:1.24-alpine

# 映射到隨機端口
docker run -d -p 80 nginx:1.24-alpine
docker port 
# 查看分配的隨機端口

# UDP端口映射
docker run -d -p 53:53/udp dns-server:1.0

# 映射多個端口
docker run -d -p 80:80 -p 443:443 nginx:1.24-alpine

# 映射端口范圍
docker run -d -p 8000-8010:8000-8010 myapp:1.0

# 查看端口映射對應的iptables規則
sudo iptables -t nat -L DOCKER -n

2.3.2 功能驗證

# 驗證bridge網絡容器間通信
docker network create testnet
docker run -d --name server --network testnet nginx:1.24-alpine
docker run --rm --network testnet alpine wget -qO- http://server:80
# 預期返回Nginx默認頁面

# 驗證DNS解析
docker run --rm --network testnet alpine nslookup server
# 預期解析到server容器的IP

# 驗證外網訪問
docker run --rm alpine ping -c 3 8.8.8.8
docker run --rm alpine wget -qO- http://ifconfig.me
# 預期返回宿主機的公網IP

# 驗證端口映射
docker run -d --name web -p 8080:80 nginx:1.24-alpine
curl -I http://localhost:8080
# 預期返回 HTTP/1.1 200 OK

# 清理
docker rm -f server web
docker network rm testnet

三、示例代碼和配置

3.1 完整配置示例

3.1.1 生產環境網絡規劃配置

// 文件路徑:/etc/docker/daemon.json
// 網絡相關配置
{
"bip":"172.17.0.1/24",
"default-address-pools": [
  {
  "base":"172.20.0.0/16",
  "size":24
  },
  {
  "base":"172.21.0.0/16",
  "size":24
  }
 ],
"dns": ["223.5.5.5","8.8.8.8"],
"dns-search": ["example.com"],
"ip-forward":true,
"iptables":true,
"ip-masq":true,
"userland-proxy":false,
"fixed-cidr":"172.17.0.0/25"
}

參數說明

bip:docker0網橋的IP和子網,默認172.17.0.1/16。生產環境改成/24,避免分配太大的網段

default-address-pools:自定義網絡的地址池。docker network create時從這里分配子網。配兩個池做冗余

userland-proxy:設為false用iptables做端口映射。默認的docker-proxy是用戶態進程,每個端口映射都fork一個進程,高并發下CPU開銷大

fixed-cidr:限制容器IP分配范圍,172.17.0.0/25表示只分配172.17.0.1-172.17.0.126

3.1.2 網絡排查腳本

#!/bin/bash
# 文件名:docker-network-diag.sh
# Docker網絡診斷腳本

CONTAINER_NAME=${1:-""}

if[ -z"$CONTAINER_NAME"];then
 echo"Usage:$0"
 exit1
fi

echo"========== 容器基本信息 =========="
docker inspect --format='容器ID: {{.Id}}'$CONTAINER_NAME
docker inspect --format='狀態: {{.State.Status}}'$CONTAINER_NAME
docker inspect --format='PID: {{.State.Pid}}'$CONTAINER_NAME

echo""
echo"========== 網絡配置 =========="
docker inspect --format='{{range $net, $config := .NetworkSettings.Networks}}網絡: {{$net}} IP: {{$config.IPAddress}} 網關: {{$config.Gateway}} MAC: {{$config.MacAddress}}{{"
"}}{{end}}'$CONTAINER_NAME

echo""
echo"========== 端口映射 =========="
docker port$CONTAINER_NAME2>/dev/null ||echo"無端口映射"

echo""
echo"========== DNS配置 =========="
dockerexec$CONTAINER_NAMEcat /etc/resolv.conf 2>/dev/null

echo""
echo"========== 路由表 =========="
dockerexec$CONTAINER_NAMEip route 2>/dev/null

echo""
echo"========== 網絡接口 =========="
dockerexec$CONTAINER_NAMEip addr 2>/dev/null

echo""
echo"========== 連接測試 =========="
echo"--- 外網連通性 ---"
dockerexec$CONTAINER_NAMEping -c 2 -W 3 8.8.8.8 2>/dev/null &&echo"外網: OK"||echo"外網: FAIL"
echo"--- DNS解析 ---"
dockerexec$CONTAINER_NAMEnslookup www.baidu.com 2>/dev/null &&echo"DNS: OK"||echo"DNS: FAIL"

echo""
echo"========== 宿主機iptables NAT規則 =========="
sudo iptables -t nat -L DOCKER -n 2>/dev/null | head -20

echo""
echo"========== 宿主機veth接口 =========="
PID=$(docker inspect --format='{{.State.Pid}}'$CONTAINER_NAME)
if["$PID"!="0"];then
  VETH_INDEX=$(sudo nsenter -t$PID-n ip link show eth0 2>/dev/null | head -1 | awk -F:'{print $1}'| awk -F@'{print $2}'| tr -d'if')
 if[ -n"$VETH_INDEX"];then
    ip link show | grep"^${VETH_INDEX}:"| awk'{print "veth接口: "$2}'
 fi
fi

3.2 實際應用案例

案例一:微服務網絡隔離架構

場景描述:一個典型的Web應用包含Nginx、App、MySQL、Redis四個服務。通過Docker網絡實現前后端隔離——Nginx和App在前端網絡,App和數據庫在后端網絡,Nginx無法直接訪問數據庫。

實現代碼

#!/bin/bash
# 創建隔離網絡
docker network create frontend --subnet 172.20.0.0/24
docker network create backend --subnet 172.21.0.0/24

# 啟動MySQL(只在backend網絡)
docker run -d 
 --name mysql 
 --network backend 
 --ip 172.21.0.10 
 --restart=unless-stopped 
 --memory=2g 
 -e MYSQL_ROOT_PASSWORD='DbP@ss123!'
 -e MYSQL_DATABASE=myapp 
 -v /data/mysql/data:/var/lib/mysql 
 mysql:8.0.35

# 啟動Redis(只在backend網絡)
docker run -d 
 --name redis 
 --network backend 
 --ip 172.21.0.11 
 --restart=unless-stopped 
 --memory=1g 
 redis:7.2-alpine

# 啟動App(連接frontend和backend)
docker run -d 
 --name app 
 --network frontend 
 --restart=unless-stopped 
 --memory=1g 
 -e DB_HOST=172.21.0.10 
 -e REDIS_HOST=172.21.0.11 
 myapp:1.0

# 將App也連接到backend網絡
docker network connect backend app

# 啟動Nginx(只在frontend網絡)
docker run -d 
 --name nginx 
 --network frontend 
 --restart=unless-stopped 
 -p 80:80 -p 443:443 
 -v /data/nginx/conf.d:/etc/nginx/conf.d:ro 
 nginx:1.24-alpine

# 驗證網絡隔離
echo"--- Nginx訪問App(應該成功)---"
dockerexecnginx wget -qO- --timeout=3 http://app:8080/health

echo"--- Nginx訪問MySQL(應該失?。?--"
dockerexecnginx ping -c 1 -W 2 172.21.0.10 ||echo"隔離生效:Nginx無法訪問MySQL"

echo"--- App訪問MySQL(應該成功)---"
dockerexecapp ping -c 1 -W 2 172.21.0.10 &&echo"App可以訪問MySQL"

運行結果

--- Nginx訪問App(應該成功)---
{"status":"UP"}
--- Nginx訪問MySQL(應該失敗)---
PING 172.21.0.10: 1 data bytes
ping: sendto: Network is unreachable
隔離生效:Nginx無法訪問MySQL
--- App訪問MySQL(應該成功)---
PING 172.21.0.10: 1 data bytes
64 bytes from 172.21.0.10: seq=0 ttl=64 time=0.089 ms
App可以訪問MySQL

案例二:使用Macvlan讓容器直接接入物理網絡

場景描述:公司有一套傳統的監控系統,通過SNMP輪詢固定IP獲取設備狀態?,F在要把監控Agent容器化,但監控系統不支持NAT后的地址,需要容器擁有物理網絡的真實IP。

實現步驟

# 1. 確認宿主機網絡信息
ip addr show eth0
# 假設:IP=192.168.1.100/24, 網關=192.168.1.1

# 2. 開啟網卡混雜模式(macvlan需要)
sudo ip linkseteth0 promisc on

# 3. 創建macvlan網絡
docker network create 
 --driver macvlan 
 --subnet 192.168.1.0/24 
 --gateway 192.168.1.1 
 --ip-range 192.168.1.200/29 
 --opt parent=eth0 
 physical-net

# --ip-range 限制Docker只分配192.168.1.200-192.168.1.207
# 避免和DHCP分配的地址沖突

# 4. 運行監控Agent容器
docker run -d 
 --name monitor-agent 
 --network physical-net 
 --ip 192.168.1.200 
 --restart=unless-stopped 
 monitor-agent:1.0

# 5. 驗證:從其他物理機直接訪問容器IP
# 在192.168.1.50這臺機器上:
ping 192.168.1.200
# 能ping通,容器就像一臺獨立的物理機

# 6. 解決宿主機無法訪問容器的問題
sudo ip link add macvlan-shim link eth0typemacvlan mode bridge
sudo ip addr add 192.168.1.201/32 dev macvlan-shim
sudo ip linksetmacvlan-shim up
sudo ip route add 192.168.1.200/32 dev macvlan-shim

四、最佳實踐和注意事項

4.1 最佳實踐

4.1.1 性能優化

關閉userland-proxy:daemon.json中設置"userland-proxy": false,用iptables替代docker-proxy做端口映射。docker-proxy是用戶態進程,每個端口映射fork一個進程,100個端口映射就是100個進程。iptables在內核態處理,零進程開銷,高并發下吞吐量提升約20%:

{
"userland-proxy":false
}

高性能場景用host網絡:Nginx反向代理、HAProxy負載均衡這類網絡密集型應用,bridge模式的NAT轉換有5%-10%的性能損耗。切換到host模式后,Nginx的QPS從12000提升到14000(測試環境4核8GB):

docker run -d --name nginx --network host 
 -v /data/nginx/nginx.conf:/etc/nginx/nginx.conf:ro 
 nginx:1.24-alpine

調大conntrack表:bridge模式依賴iptables的連接跟蹤(conntrack),默認nf_conntrack_max=65536,高并發場景下會滿,導致新連接被丟棄。生產環境建議調到100萬:

sysctl -w net.netfilter.nf_conntrack_max=1048576
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=600
# 寫入 /etc/sysctl.d/docker-network.conf 持久化

4.1.2 安全加固

網絡隔離:不同安全級別的服務放在不同的Docker網絡中。數據庫和緩存放在backend網絡,Web服務放在frontend網絡,只有應用層同時連接兩個網絡。這樣即使Web容器被攻破,攻擊者也無法直接訪問數據庫:

docker network create --internal backend-secure
# --internal 禁止該網絡訪問外網,數據庫不需要外網訪問

限制容器間通信(ICC):默認同一bridge網絡內的容器可以互相通信。如果不需要容器間通信,關閉ICC:

docker network create --opt"com.docker.network.bridge.enable_icc"="false"isolated-net
# ICC關閉后,容器間只能通過端口映射通信

端口映射綁定內網IP:不要把端口映射到0.0.0.0,綁定到內網IP。我見過把MySQL 3306映射到0.0.0.0,結果被外網掃描到暴力破解的:

#  危險:監聽所有接口
docker run -d -p 3306:3306 mysql:8.0.35

#  安全:只監聽內網
docker run -d -p 192.168.1.103306 mysql:8.0.35

4.1.3 高可用配置

DNS輪詢負載均衡:自定義bridge網絡支持同名容器的DNS輪詢。多個容器用相同的網絡別名,Docker DNS會輪詢返回不同IP:

docker network create mynet
docker run -d --name app1 --network mynet --network-alias app myapp:1.0
docker run -d --name app2 --network mynet --network-alias app myapp:1.0
docker run -d --name app3 --network mynet --network-alias app myapp:1.0
# 訪問 app 這個名字會輪詢到app1/app2/app3

overlay網絡跨主機高可用:Docker Swarm的overlay網絡自動處理節點故障,服務副本會在健康節點上重新調度

網絡故障自愈:配置容器restart策略,網絡閃斷導致容器異常退出時自動重啟

4.2 注意事項

4.2.1 配置注意事項

警告:Docker網絡地址段不能和宿主機所在網段、公司內網網段沖突。我遇到過Docker默認的172.17.0.0/16和公司辦公網段沖突,導致開發機無法訪問172.17開頭的內網服務器。修改daemon.json的bip和default-address-pools避免沖突。

注意iptables規則持久化:Docker重啟會重建iptables規則,但如果手動修改了iptables規則(比如加了防火墻規則),Docker重啟后可能覆蓋。建議用firewalld的docker zone管理防火墻規則

注意IPv6支持:Docker默認不啟用IPv6。如果需要IPv6,在daemon.json中配置"ipv6": true和"fixed-cidr-v6": "fd00::/80"

注意容器重啟后IP變化:默認bridge網絡不保證容器IP不變。用自定義網絡+容器名DNS解析,或者用--ip指定固定IP

4.2.2 常見錯誤

錯誤現象 原因分析 解決方案
容器無法訪問外網 ip_forward未開啟或iptables NAT規則丟失 sysctl -w net.ipv4.ip_forward=1 ,重啟Docker重建規則
端口映射不生效 防火墻阻斷或端口被占用 檢查firewalld/iptables規則,ss -tlnp檢查端口占用
容器間ping不通 不在同一Docker網絡 docker network connect 將容器加入同一網絡
DNS解析失敗 使用了默認bridge網絡(不支持DNS) 改用自定義bridge網絡
conntrack表滿導致丟包 nf_conntrack_max太小 調大到1048576,dmesg中搜索"nf_conntrack: table full"
macvlan容器和宿主機不通 macvlan的設計限制 在宿主機創建macvlan子接口

4.2.3 兼容性問題

版本兼容:overlay網絡需要Docker 1.12+和Swarm模式。獨立容器加入overlay需要--attachable參數(Docker 17.06+)

平臺兼容:macvlan在虛擬機環境中可能不工作(取決于虛擬化平臺是否允許混雜模式)。AWS/阿里云等云平臺通常不支持macvlan

內核兼容:VXLAN需要內核4.0+,ipvlan需要內核4.2+。CentOS 7默認內核3.10不支持這些特性,需要升級內核

五、故障排查和監控

5.1 故障排查

5.1.1 日志查看

# 查看Docker網絡相關日志
sudo journalctl -u docker.service | grep -i -E"network|bridge|iptables"

# 查看容器網絡事件
docker events --filter'type=network'

# 查看iptables規則(NAT表)
sudo iptables -t nat -L -n -v

# 查看iptables規則(filter表)
sudo iptables -L DOCKER -n -v
sudo iptables -L DOCKER-ISOLATION-STAGE-1 -n -v

# 查看conntrack連接跟蹤表
sudo conntrack -L | head -20
sudo conntrack -C # 當前連接數

5.1.2 常見問題排查

問題一:容器無法訪問外網

# 第一步:檢查IP轉發
sysctl net.ipv4.ip_forward
# 如果為0,開啟:
sudo sysctl -w net.ipv4.ip_forward=1

# 第二步:檢查iptables MASQUERADE規則
sudo iptables -t nat -L POSTROUTING -n | grep MASQUERADE
# 應該有類似:MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0

# 第三步:檢查容器DNS
dockerexec cat /etc/resolv.conf
# nameserver應該指向Docker內置DNS 127.0.0.11

# 第四步:分步測試
dockerexec ping -c 1 172.17.0.1  # 網關
dockerexec ping -c 1 8.8.8.8    # 外網IP
dockerexec nslookup www.baidu.com  # DNS解析

解決方案

ip_forward為0:開啟并寫入sysctl.conf持久化

MASQUERADE規則缺失:systemctl restart docker重建

DNS不通:在daemon.json中配置"dns": ["223.5.5.5", "8.8.8.8"]

問題二:端口映射后外部無法訪問

# 檢查端口映射是否生效
docker port 

# 檢查宿主機端口是否在監聽
ss -tlnp | grep 

# 檢查防火墻規則
sudo firewall-cmd --list-all
sudo iptables -L INPUT -n | grep 

# 檢查Docker的iptables規則
sudo iptables -t nat -L DOCKER -n | grep 
sudo iptables -L DOCKER -n | grep 

# 檢查是否有docker-proxy進程(如果userland-proxy=true)
ps aux | grep docker-proxy

解決方案

防火墻阻斷:firewall-cmd --add-port=8080/tcp --permanent && firewall-cmd --reload

iptables規則丟失:重啟Docker或手動重建

端口被其他進程占用:ss -tlnp | grep 找到占用進程

問題三:容器間網絡延遲高

癥狀:同一宿主機上的容器間通信延遲從0.1ms突然升高到5-10ms

排查

# 檢查網橋狀態
brctl show
brctl showstp docker0

# 檢查veth接口是否有錯誤
ip -s link show | grep -A 5 veth

# 檢查conntrack表是否接近滿
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
# 如果count接近max,說明conntrack表快滿了

# 抓包分析
sudo tcpdump -i docker0 -nn -c 100

解決:conntrack表滿導致丟包重傳,調大nf_conntrack_max;veth接口錯誤計數增長說明網絡棧有問題,檢查內核日志

5.1.3 調試模式

# 使用nsenter進入容器網絡命名空間(不需要容器內有調試工具)
PID=$(docker inspect --format='{{.State.Pid}}')
sudo nsenter -t$PID-n ip addr
sudo nsenter -t$PID-n ss -tlnp
sudo nsenter -t$PID-n iptables -L -n
sudo nsenter -t$PID-n tcpdump -i eth0 -nn -c 50

# 在docker0網橋上抓包
sudo tcpdump -i docker0 -nn -w /tmp/docker0.pcap

# 在veth接口上抓包(找到容器對應的veth)
VETH=$(ip link show | grep"$(docker inspect --format='{{.State.Pid}}' )"| awk'{print $2}'| tr -d':')
sudo tcpdump -i$VETH-nn -c 50

# 跟蹤iptables規則匹配(調試NAT問題)
sudo iptables -t nat -L -n -v --line-numbers
# 觀察各規則的pkts和bytes計數器變化

# 使用nicolaka/netshoot調試容器(自帶各種網絡工具)
docker run --rm -it --network container: nicolaka/netshoot
# 進入后可以用 tcpdump, iperf3, nslookup, curl, ss 等工具

5.2 性能監控

5.2.1 關鍵指標監控

# 查看容器網絡IO
docker stats --no-stream --format"table {{.Name}}	{{.NetIO}}"

# 查看網橋流量
cat /sys/class/net/docker0/statistics/rx_bytes
cat /sys/class/net/docker0/statistics/tx_bytes

# 查看conntrack使用率
echo"$(cat /proc/sys/net/netfilter/nf_conntrack_count)/$(cat /proc/sys/net/netfilter/nf_conntrack_max)"| bc -l

# 查看veth接口錯誤計數
ip -s link show | grep -A 6 veth

# 查看iptables規則計數
sudo iptables -t nat -L -n -v | grep DOCKER

5.2.2 監控指標說明

指標名稱 正常范圍 告警閾值 說明
conntrack使用率 <60% >80% 超過80%開始丟包
容器網絡收發錯誤 0 >0 有錯誤說明網絡棧異常
docker0網橋流量 視業務而定 突增50%以上 流量突增可能是攻擊或異常
DNS解析延遲 <5ms >50ms Docker內置DNS通常很快
端口映射連接數 視業務而定 接近conntrack_max 連接數過多需要擴容
veth接口丟包率 0% >0.01% 丟包說明網絡擁塞或配置問題

5.2.3 Prometheus監控配置

# Prometheus告警規則:docker-network-alerts.yml
groups:
-name:docker_network_alerts
 rules:
  -alert:ConntrackTableNearlyFull
   expr:node_nf_conntrack_entries/node_nf_conntrack_entries_limit>0.8
   for:5m
   labels:
    severity:critical
   annotations:
    summary:"conntrack表使用率超過80%"
    description:"當前使用率{{ $value | humanizePercentage }},即將導致新連接被丟棄"

  -alert:ContainerNetworkErrors
   expr:rate(container_network_receive_errors_total{name!=""}[5m])>0
   for:2m
   labels:
    severity:warning
   annotations:
    summary:"容器{{ $labels.name }}網絡接收錯誤"
    description:"錯誤率{{ $value }}/s"

  -alert:HighNetworkTraffic
   expr:rate(container_network_receive_bytes_total{name!=""}[5m])>100000000
   for:5m
   labels:
    severity:warning
   annotations:
    summary:"容器{{ $labels.name }}網絡流量異常"
    description:"接收流量{{ $value | humanize }}B/s,超過100MB/s"

5.3 備份與恢復

5.3.1 備份策略

#!/bin/bash
# Docker網絡配置備份腳本
BACKUP_DIR="/backup/docker-network/$(date +%Y%m%d)"
mkdir -p${BACKUP_DIR}

# 備份所有自定義網絡配置
fornetin$(docker network ls --filter'type=custom'-q);do
  NET_NAME=$(docker network inspect --format='{{.Name}}'$net)
  docker network inspect$net>${BACKUP_DIR}/${NET_NAME}.json
done

# 備份iptables規則
sudo iptables-save >${BACKUP_DIR}/iptables-rules.txt
sudo ip6tables-save >${BACKUP_DIR}/ip6tables-rules.txt

# 備份sysctl網絡參數
sysctl -a 2>/dev/null | grep -E"net.(ipv4|bridge|netfilter)">${BACKUP_DIR}/sysctl-network.txt

# 備份daemon.json
cp /etc/docker/daemon.json${BACKUP_DIR}/

echo"Network backup completed:${BACKUP_DIR}"

5.3.2 恢復流程

恢復daemon.json:cp daemon.json /etc/docker/ && systemctl restart docker

恢復sysctl參數:cp sysctl-network.txt /etc/sysctl.d/docker-network.conf && sysctl --system

重建自定義網絡:根據備份的JSON文件中的subnet、gateway等參數重新創建

驗證網絡連通性:啟動測試容器驗證各網絡的連通性和隔離性

六、總結

6.1 技術要點回顧

bridge模式:默認模式,通過docker0網橋+veth pair+iptables NAT實現。生產環境用自定義bridge,支持容器名DNS解析

host模式:直接使用宿主機網絡棧,零NAT開銷,適合網絡密集型應用。代價是失去網絡隔離

網絡隔離:通過多個自定義網絡實現服務間隔離,前端網絡和后端網絡分離,最小化攻擊面

性能調優:關閉userland-proxy、調大conntrack表、高性能場景用host模式

排查思路:ip_forward → iptables規則 → DNS解析 → conntrack表,按這個順序排查覆蓋90%的網絡問題

6.2 進階學習方向

容器網絡接口(CNI):Kubernetes使用CNI標準管理容器網絡,理解CNI插件機制是進入K8s網絡的基礎

學習資源:CNI規范文檔、Flannel/Calico源碼

實踐建議:手動配置CNI插件,理解網絡創建和刪除的生命周期

eBPF網絡:Cilium等新一代容器網絡方案用eBPF替代iptables,性能更好,可觀測性更強

學習資源:Cilium官方文檔

實踐建議:在測試環境部署Cilium,對比iptables方案的性能差異

Service Mesh:Istio/Linkerd在容器網絡之上提供流量管理、熔斷、鏈路追蹤等能力

學習資源:Istio官方教程

6.3 參考資料

Docker網絡官方文檔- 各網絡驅動的詳細說明

Linux網絡命名空間- 理解容器網絡隔離的內核基礎

iptables教程- 理解Docker的NAT規則

nicolaka/netshoot- 容器網絡調試工具集

附錄

A. 命令速查表

# 網絡管理
docker network ls               # 查看所有網絡
docker network create --subnet X mynet    # 創建自定義網絡
docker network rm mynet            # 刪除網絡
docker network inspect mynet         # 查看網絡詳情
docker network connect mynet container    # 容器加入網絡
docker network disconnect mynet container   # 容器離開網絡
docker network prune             # 清理未使用的網絡

# 容器網絡操作
docker run --network host ...         # host模式運行
docker run --network none ...         # 無網絡運行
docker run --network container:other ...   # 共享網絡運行
docker run -p 8080:80 ...           # 端口映射
docker run --ip 172.20.0.100 --network mynet # 指定IP
docker port container             # 查看端口映射

# 網絡調試
dockerexeccontainer ip addr         # 查看容器網絡
dockerexeccontainer ping target       # 連通性測試
dockerexeccontainer nslookup name      # DNS測試
sudo tcpdump -i docker0 -nn          # 網橋抓包
sudo nsenter -t PID -n ip addr        # 進入網絡命名空間

B. 網絡模式對比表

特性 bridge host none container overlay macvlan
網絡隔離 完全隔離 共享
性能損耗 5-10% 0% N/A 0% 10-15% <2%
端口映射 需要-p 不需要 N/A 不需要 需要-p 不需要
跨主機通信 不支持 不支持 不支持 不支持 支持 支持(同網段)
DNS解析 自定義網絡支持 用宿主機 共享 支持
適用場景 通用 高性能 安全隔離 Sidecar Swarm集群 物理網絡接入

C. 術語表

術語 英文 解釋
網絡命名空間 Network Namespace Linux內核特性,為進程提供獨立的網絡棧(接口、路由表、iptables規則)
veth pair Virtual Ethernet Pair 虛擬以太網對,一端在容器內(eth0),一端在宿主機(vethXXX),數據從一端進另一端出
網橋 Bridge 二層網絡設備,連接多個網絡接口,實現同網段內的數據轉發。docker0就是一個Linux網橋
NAT Network Address Translation 網絡地址轉換,Docker用MASQUERADE規則將容器IP轉換為宿主機IP訪問外網
VXLAN Virtual Extensible LAN 虛擬可擴展局域網,overlay網絡的底層隧道協議,用UDP 4789端口封裝二層幀
conntrack Connection Tracking iptables的連接跟蹤機制,記錄每個網絡連接的狀態,NAT依賴此機制
ICC Inter-Container Communication 容器間通信,可以在網絡級別開啟或關閉
macvlan MAC VLAN 在一個物理網卡上創建多個虛擬網卡,每個有獨立的MAC地址和IP

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 網絡
    +關注

    關注

    14

    文章

    8317

    瀏覽量

    95467
  • 容器
    +關注

    關注

    0

    文章

    533

    瀏覽量

    23012
  • Docker
    +關注

    關注

    0

    文章

    535

    瀏覽量

    14363

原文標題:從網絡隔離到服務互通:Docker 網絡模式全解析

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    ARM平臺實現Docker容器技術

    T113-i工業核心板在支持Docker后,其性價比還將進一步提升!圖2基于T113-i平臺實現Docker容器技術 如下為基于志T113-i工業平臺,演示
    發表于 07-17 11:05

    ARM平臺實現Docker容器技術

    性價比志T113-i工業核心板在支持Docker后,其性價比還將進一步提升! 圖2基于T113-i平臺實現Docker容器技術 如下為基于
    發表于 07-25 14:36

    如何在Docker中創建容器

    Docker是一個開源的引擎,可以輕松的為任何應用創建一個輕量級的、可移植的、自給自足的容器。開發者在筆記本上編譯測試通過的容器可以批量地在生產環境中部署,包括VMs(虛擬機)、bare metal
    發表于 01-03 15:58

    docker的四種網絡模式

    docker網絡模式
    發表于 10-16 08:11

    理解Docker容器并暢玩docker

    ,完全不影響其他容器的正常運作)。這樣描述,還是不大明白,我們可以實際操作一下。先打開兩個命令行,在其中一個命令行執行以下命令:docker run -it --name a1_rm alpine命令解析
    發表于 11-05 09:54

    Docker容器管理命令(二)

    1、Docker容器管理命令的使用方法批量刪除docker 容器docker cp命令docker
    發表于 04-21 11:31

    詳解docker的四種網絡模式

    使用none模式Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何
    的頭像 發表于 01-21 09:21 ?7338次閱讀

    docker的4種網絡模式

    Docker 使用 Linux 橋接,在宿主機虛擬一個 Docker 容器網橋(docker0),Docker 啟動一個
    的頭像 發表于 08-14 11:50 ?2854次閱讀

    docker的4種網絡模式配置

    Docker 使用 Linux 橋接,在宿主機虛擬一個 Docker 容器網橋(docker0),Docker 啟動一個
    的頭像 發表于 10-10 10:37 ?2398次閱讀

    Docker容器的四種網絡模式

    Docker 在安裝后自動提供 3 種網絡,可以使用 docker network ls 命令查看。
    的頭像 發表于 10-17 14:53 ?2603次閱讀

    Docker容器網絡的數據鏈路是什么

    單主機容器網絡可能存在多個docker,分屬于不同的bridge,它們之間有通信的需求。
    的頭像 發表于 02-15 09:56 ?1885次閱讀
    <b class='flag-5'>Docker</b><b class='flag-5'>容器</b><b class='flag-5'>網絡</b>的數據鏈路是什么

    docker容器刪除后數據還在嗎

    的數據是否還會保留,這是一個需要深入分析和理解的問題。 本文將詳細探討Docker容器刪除后數據的存儲機制,從容器使用的存儲驅動、數據卷、掛載以及網絡等方面進行講解,以幫助讀者全面理解
    的頭像 發表于 11-23 09:32 ?3484次閱讀

    docker容器容器之間通信

    Docker容器之間的通信方式、通信過程以及常見的通信模式。 一、Docker容器之間的通信方式 在Do
    的頭像 發表于 11-23 09:36 ?2591次閱讀

    docker進入容器的方法有哪些

    Docker是一種流行的容器化平臺,它能夠快速構建、交付和運行應用程序。在使用Docker時,我們經常需要進入容器進行調試、管理和運行命令等操作。本文將詳細介紹
    的頭像 發表于 11-23 09:45 ?1.4w次閱讀

    docker容器有幾種狀態

    Docker 容器的各種狀態及其含義。 Created(已創建):當我們使用 docker create 命令創建一個容器時,它會進入已創建狀態。在這個狀態下,
    的頭像 發表于 11-23 09:50 ?3914次閱讀