DevToolBox免费
博客

Docker 网络指南:Bridge、Host、Overlay 网络详解

14 分钟作者 DevToolBox

Docker 网络是容器化应用架构中最关键的方面之一。理解容器之间、与宿主机以及与外部网络的通信方式,对于构建可靠、安全和可扩展的应用至关重要。本指南涵盖了所有 Docker 网络类型、docker-compose 网络模式和故障排查策略。

Docker 网络概述

Docker 为容器创建隔离的网络环境。默认情况下,Docker 提供多种网络驱动,每种针对不同的使用场景设计。

# List all Docker networks
$ docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
f6e5d4c3b2a1   host      host      local
1a2b3c4d5e6f   none      null      local

Docker 网络类型

Bridge 网络(默认)

Bridge 网络是容器的默认网络驱动。用户定义的 bridge 网络支持使用容器名称进行自动 DNS 解析。

# Create a user-defined bridge network
$ docker network create my-app-network

# Run containers on the custom network
$ docker run -d --name web --network my-app-network nginx:alpine
$ docker run -d --name api --network my-app-network node:20-alpine

# Containers can now reach each other by name
$ docker exec web ping api
PING api (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.089 ms

# User-defined bridge vs default bridge
# Default bridge: containers communicate only via IP addresses
# User-defined bridge: automatic DNS resolution by container name

# Create bridge with custom subnet
$ docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  custom-bridge

Host 网络

Host 网络模式消除了容器与宿主机之间的网络隔离。容器直接共享宿主机的网络栈。

# Run container with host networking
$ docker run -d --network host nginx:alpine

# No port mapping needed — container uses host ports directly
# The nginx server is accessible at localhost:80

# Check: container shares host's network interfaces
$ docker exec <container-id> ip addr
# Shows the same interfaces as the host machine

# Warning: Only one container can bind to a given host port
# Host networking is only supported on Linux (not macOS/Windows)

Overlay 网络

Overlay 网络连接多个 Docker 守护进程,使 Swarm 服务能够相互通信。

# Initialize Docker Swarm (required for overlay networks)
$ docker swarm init

# Create an overlay network
$ docker network create \
  --driver overlay \
  --attachable \
  my-overlay-network

# Create a service on the overlay network
$ docker service create \
  --name web \
  --network my-overlay-network \
  --replicas 3 \
  nginx:alpine

# Create encrypted overlay network for sensitive data
$ docker network create \
  --driver overlay \
  --opt encrypted \
  secure-overlay

Macvlan 网络

Macvlan 网络允许为容器分配 MAC 地址,使其看起来像网络上的物理设备。

# Create a Macvlan network
$ docker network create \
  --driver macvlan \
  --subnet 192.168.1.0/24 \
  --gateway 192.168.1.1 \
  -o parent=eth0 \
  my-macvlan

# Run container with its own IP on the LAN
$ docker run -d \
  --network my-macvlan \
  --ip 192.168.1.100 \
  --name legacy-app \
  my-app:latest

# The container appears as 192.168.1.100 on the physical network

None 网络

None 网络禁用容器的所有网络功能,提供完全的网络隔离。

# Run container with no networking
$ docker run -d --network none alpine sleep 3600

# Only loopback interface is available
$ docker exec <container-id> ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
    inet 127.0.0.1/8 scope host lo

Docker Compose 网络

Docker Compose 默认为应用创建一个网络。每个容器可以使用服务名作为主机名来访问其他容器。

# docker-compose.yml — Default networking
# All services share a network named <project>_default
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
  api:
    image: node:20-alpine
    # Can reach web service at http://web:80
    # Can reach db service at postgres://db:5432
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret

Compose 中的自定义网络

# docker-compose.yml — Custom networks for isolation
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    networks:
      - frontend

  api:
    build: ./api
    networks:
      - frontend
      - backend
    depends_on:
      - db
      - redis

  db:
    image: postgres:16
    volumes:
      - pg-data:/var/lib/postgresql/data
    networks:
      - backend

  redis:
    image: redis:7-alpine
    networks:
      - backend

  admin:
    image: adminer
    ports:
      - "8080:8080"
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # No external access

volumes:
  pg-data:

网络隔离模式

可以使用多个网络来隔离服务。例如,前端网络用于 Web 和 API,后端网络用于 API 和数据库。

# Three-tier architecture with network isolation
#
#  Internet
#     |
#  [nginx]     <-- frontend network
#     |
#   [api]      <-- frontend + backend network
#     |
#   [db]       <-- backend network (internal)
#
# nginx can reach api, but NOT db
# api can reach both nginx and db
# db is completely isolated from external access

DNS 和服务发现

Docker 为用户定义的网络提供内置 DNS 解析。容器可以通过名称互相解析。

DNS 解析规则

# DNS resolution in user-defined networks
# 1. Container name → IP address
$ docker exec web nslookup api
Server:    127.0.0.11
Address:   127.0.0.11#53
Name:      api
Address:   172.18.0.3

# 2. Service name in Compose → all container IPs (round-robin)
$ docker exec web nslookup api
# Returns IPs of all 'api' service replicas

# 3. Network aliases
$ docker run -d \
  --network my-network \
  --network-alias database \
  --network-alias db \
  --name postgres-primary \
  postgres:16

# Container is reachable as: postgres-primary, database, or db

# 4. Check DNS configuration inside a container
$ docker exec web cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

跨网络连接容器

可以将运行中的容器同时连接到多个网络。

# Connect a running container to an additional network
$ docker network connect backend api-container

# Connect with a specific IP address
$ docker network connect --ip 172.20.0.10 backend api-container

# Disconnect from a network
$ docker network disconnect frontend api-container

# A container connected to multiple networks can route between them
# This is useful for "gateway" containers

网络检查

Docker 提供多个命令来检查和调试网络配置。

# List all networks
$ docker network ls

# Inspect a network (shows connected containers, config)
$ docker network inspect my-app-network

# Find which networks a container is connected to
$ docker inspect --format='{{json .NetworkSettings.Networks}}' my-container

# Check container IP address
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container

# Check port mappings
$ docker port my-container

# Test connectivity between containers
$ docker exec web ping -c 3 api
$ docker exec web wget -qO- http://api:3000/health

# Debug with a temporary network tools container
$ docker run --rm -it --network my-app-network \
  nicolaka/netshoot bash

Docker 网络故障排查

容器无法访问另一个容器

验证容器是否在同一网络上。

# Check if containers are on the same network
$ docker network inspect bridge --format='{{range .Containers}}{{.Name}} {{end}}'

# Solution: Use a user-defined network
$ docker network create app-net
$ docker run -d --name web --network app-net nginx
$ docker run -d --name api --network app-net node:20-alpine

# Now name resolution works
$ docker exec web ping api  # Works!

端口冲突

检查冲突端口并更换映射。

# Error: port is already allocated
# Find what is using the port
$ lsof -i :8080
$ ss -tlnp | grep 8080

# Solution 1: Map to a different host port
$ docker run -d -p 8081:80 nginx

# Solution 2: Stop the conflicting service
$ sudo systemctl stop apache2

DNS 解析失败

可以为容器指定自定义 DNS 服务器。

# Specify custom DNS servers
$ docker run -d --dns 8.8.8.8 --dns 8.8.4.4 my-app

# Or in docker-compose.yml
services:
  web:
    image: nginx
    dns:
      - 8.8.8.8
      - 8.8.4.4

网络性能问题

考虑对性能关键服务使用 host 网络。

# Check MTU settings
$ docker network inspect bridge | grep -i mtu

# Set custom MTU for a network
$ docker network create --opt com.docker.network.driver.mtu=1400 my-network

# Use host networking for maximum performance
$ docker run --network host my-performance-app

网络安全最佳实践

遵循以下最佳实践来保护 Docker 网络:

  • 使用用户定义的 bridge 网络。
  • 使用内部网络限制外部访问。
  • 仅发布必要端口。
  • 使用加密的 overlay 网络。
  • 实施网络策略控制流量。
  • 定期审计网络配置。
# Bind to localhost only (not accessible from outside)
$ docker run -d -p 127.0.0.1:5432:5432 postgres:16

# Create internal network (no outbound internet)
$ docker network create --internal isolated-net

# In docker-compose.yml
networks:
  database:
    internal: true  # Containers cannot reach the internet

高级网络主题

自定义 IPAM 配置

可以为 Docker 网络配置自定义 IP 地址管理。

# Custom IPAM configuration
$ docker network create \
  --driver bridge \
  --subnet 10.10.0.0/16 \
  --ip-range 10.10.1.0/24 \
  --gateway 10.10.0.1 \
  --aux-address "dns=10.10.0.2" \
  custom-ipam-net

# In docker-compose.yml
networks:
  app-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          ip_range: 172.28.5.0/24
          gateway: 172.28.0.1

IPv6 支持

Docker 支持 IPv6 网络。

# Enable IPv6 in Docker daemon (/etc/docker/daemon.json)
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

# Create a dual-stack network
$ docker network create \
  --ipv6 \
  --subnet 172.20.0.0/16 \
  --subnet 2001:db8:2::/64 \
  dual-stack-net

内置负载均衡

Docker Swarm 为服务提供内置负载均衡。

# Docker Swarm built-in load balancing
$ docker service create \
  --name web \
  --replicas 5 \
  --publish published=80,target=80 \
  --network my-overlay \
  nginx:alpine

# Requests to port 80 on ANY swarm node
# are load-balanced across all 5 replicas
# using ingress routing mesh

# Scale the service
$ docker service scale web=10

网络驱动对比

驱动使用场景隔离性性能多主机
BridgeSingle-host containersHighGoodNo
HostPerformance-critical appsNoneBestNo
OverlayMulti-host / SwarmHighGoodYes
MacvlanLegacy / physical networkHighGoodNo
NoneMaximum isolationCompleteN/ANo

总结

Docker 网络是使用容器的开发者的基础技能。Bridge 网络处理大多数单主机场景,Overlay 网络用于多主机部署。掌握这些概念,你就能构建健壮、可扩展的容器化应用。

常见问题

Docker 中 bridge 和 host 网络有什么区别?

Bridge 网络创建隔离的网络命名空间并提供端口映射。Host 网络直接共享宿主机网络栈,性能更好但没有端口隔离。

什么时候应该使用 overlay 网络?

当需要不同 Docker 主机上的容器通信时使用,通常用于 Docker Swarm 或 Kubernetes 部署。

不同网络上的容器能通信吗?

默认不能。可以使用 docker network connect 将容器连接到多个网络。

如何排查 Docker DNS 解析问题?

确保容器在用户定义的网络上,使用 docker exec 在容器内运行 nslookup 或 dig。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter

相关文章

Docker Compose 教程:从基础到生产就绪的技术栈

完整的 Docker Compose 教程:docker-compose.yml 语法、服务、网络、卷、环境变量、健康检查,以及 Node.js、Python、WordPress 的实际案例。

Docker 最佳实践:20 个生产容器技巧

掌握 Docker 的 20 个关键最佳实践:多阶段构建、安全加固、镜像优化、缓存策略、健康检查和 CI/CD 自动化。

Docker vs Kubernetes:何时使用哪个?

Docker 和 Kubernetes 对比分析。