Docker 网络

6.1 网络模式

bridge(默认)

# 默认网络,容器通过虚拟网桥通信
docker run -d --name web1 nginx
docker run -d --name web2 nginx
 
# 容器间通过容器名通信
docker exec web1 ping web2  # ✅ 可以通
 
# 查看 bridge 网络
docker network inspect bridge
# 容器获得 172.17.0.x 的 IP

host

# 容器直接使用宿主机网络栈
docker run -d --network host --name web nginx
# 容器直接监听宿主机的 80 端口
# 无需 -p 端口映射
# 适用场景:高性能网络、需要访问宿主机网络配置

none

# 完全无网络(完全隔离)
docker run -d --network none --name isolated alpine sleep 3600
docker exec isolated ip addr  # 只有 lo 接口

macvlan

# 容器获得独立 MAC 地址,像物理设备一样接入网络
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 my_macvlan
 
docker run -d --network my_macvlan \
  --ip 192.168.1.100 \
  --name web nginx
# 容器在局域网中可见,其他设备可以直接访问

overlay(Swarm 模式)

# 跨主机容器通信(Docker Swarm / Kubernetes)
# 创建 overlay 网络
docker network create -d overlay my-overlay

6.2 自定义网络

# 创建自定义 bridge 网络
docker network create mynet
docker network create --driver bridge --subnet 172.28.0.0/16 mynet
 
# 将容器加入自定义网络
docker run -d --network mynet --name web1 nginx
docker run -d --network mynet --name web2 nginx
 
# 自定义网络的优势
# 1. 容器名 DNS 解析(默认 bridge 不支持)
# 2. 网络隔离(不同网络的容器不能通信)
# 3. 可配置子网和网关
 
# 连接已有容器到网络
docker network connect mynet existing_container
 
# 断开网络
docker network disconnect mynet existing_container

6.3 端口映射

# 指定端口映射
docker run -d -p 8080:80 nginx
# 宿主机 8080 → 容器 80
 
# 多端口映射
docker run -d -p 8080:80 -p 8443:443 nginx
 
# 随机端口映射
docker run -d -P nginx
# Docker 随机分配宿主机端口
 
# 指定 IP
docker run -d -p 127.0.0.1:8080:80 nginx
# 只允许本地访问
 
# UDP 端口
docker run -d -p 5353:53/udp dns-server
 
# 查看端口映射
docker port web

6.4 网络隔离

# 创建两个网络
docker network create frontend
docker network create backend
 
# Web 服务器在 frontend
docker run -d --network frontend --name web nginx
 
# 数据库在 backend
docker run -d --network backend --name db mysql
 
# 连接 web 到 backend(web 可以访问 db)
docker network connect backend web
 
# 结果:
# web: frontend + backend
# db: backend
# 外部 → frontend → web → backend → db ✅
# 外部 → backend → db ❌(没有映射端口)
# web → frontend → 外部 ✅

6.5 DNS 与服务发现

# Docker 内置 DNS(127.0.0.11)
# 自定义网络中,容器名自动注册为 DNS 记录
 
docker network create mynet
docker run -d --network mynet --name api nginx
docker run -d --network mynet --name web nginx
 
# web 可以通过容器名访问 api
docker exec web ping api      # ✅
docker exec web curl http://api  # ✅
 
# 自定义 DNS
docker run -d --dns 8.8.8.8 --dns-search example.com nginx
 
# 查看 DNS 配置
docker exec web cat /etc/resolv.conf

6.6 跨主机网络

overlay 网络(Swarm 模式)

# 初始化 Swarm
docker swarm init
 
# 创建 overlay 网络
docker network create -d overlay --attachable my-overlay
 
# 跨主机容器通信
# 在 node1 上
docker run -d --network my-overlay --name web nginx
# 在 node2 上
docker run -d --network my-overlay --name app nginx
# app 可以通过容器名访问 web

第三方方案

  • flannel:Kubernetes 默认网络插件
  • weave:mesh 网络
  • Calico:网络策略 + BGP

6.7 网络故障排查

# 检查容器网络配置
docker inspect --format '{{.NetworkSettings.Networks}}' web
 
# 进入容器测试网络
docker exec -it web sh
ping google.com
curl -v http://api:8080
nslookup api
 
# 检查端口是否监听
docker exec web netstat -tlnp
 
# 检查 iptables 规则(宿主机)
sudo iptables -t nat -L -n | grep DOCKER
 
# 重置网络(谨慎)
docker network prune
docker system prune -a