Docker网络

Docker 网络是容器通信的基础,它提供了灵活的网络模型,使容器能够相互通信以及与外部网络交互。

1、核心概念

Docker 网络的核心目标是提供隔离和连通性。它利用 Linux 的 网络命名空间(Network Namespaces 为每个容器提供独立的网络栈(包括网卡、路由表、iptables 规则等),从而实现网络隔离。同时,通过虚拟网桥、veth pair 等设备和技术,容器之间及容器与主机之间能够建立通信渠道。

  • 网络命名空间(Network Namespace) :提供了网络的隔离,每个容器(除 host 模式外)都拥有独立的命名空间,包括自己独立的网卡、路由表、ARP 表等。
  • 虚拟以太设备对(veth pair) :总是成对出现,像一根虚拟的网线,一端放在容器的网络命名空间内(通常命名为 eth0),另一端连接到虚拟网桥 (如 docker0)上,从而实现容器与网桥的连接。
  • 虚拟网桥(Virtual Bridge) :类似于物理交换机,docker0 网桥负责在连接到它的多个容器(veth端点)之间转发数据帧。
  • iptables :Docker 大量使用 iptables 规则来实现端口映射(DNAT)容器访问外部网络(SNAT/MASQUERADE) 以及网络访问控制

2、默认网络

当你安装 Docker 后,它会自动创建三个默认网络:

bash 复制代码
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
f1e2d3c4b5a6   host      host      local
1234567890ab   none      null      local

新创建的容器默认会连接到 bridge 网络,除非你用 --network 指定。

3、各种网络模式详解

3.1 Bridge 网络(默认)

这是最常用、最简单的网络模式。

特点:

  • 每个容器分配独立 IP 地址(默认在 172.17.0.0/16 网段)
  • 容器通过网桥相互通信
  • 通过 NAT 实现与外部网络通信(容器内部访问外部)
  • 支持端口映射(将容器端口映射到宿主机)(外部访问容器内部)

工作原理:

  1. Docker 守护进程会创建一个名为 docker0 的虚拟网桥。
  2. 每创建一个新容器(使用 bridge 模式),Docker 会创建一对 veth 虚拟设备接口,一端放在容器内(命名为 eth0),另一端连接到 docker0 网桥上。
  3. 容器内的 eth0 接口会从网桥的 IP 地址段中获得一个私有 IP 地址(如 172.17.0.2)。
  4. 容器通过 docker0 网桥与外界通信。docker0 网桥作为 NAT 设备,通过宿主机的物理网卡进行流量转发。

示例:端口映射(Port Publishing)

默认的 bridge 网络内的容器可以互相通过 IP 地址通信,但无法通过容器名通信,且外部无法直接访问。要让外部访问,必须映射端口

bash 复制代码
# 运行一个 Nginx 容器,将容器的 80 端口映射到宿主机的 8080 端口
docker run -d --name web -p 8080:80 nginx:alpine

# 现在,你可以通过宿主机的 IP 和 8080 端口访问容器中的 Nginx
# 例如:http://localhost:8080 或 http://<host-ip>:8080

示例:创建自定义 Bridge 网络

自定义的 Bridge 网络比默认的更好,它提供自动 DNS 解析(容器可以通过容器名互相访问)和更好的隔离性。

bash 复制代码
# 1. 创建一个名为 my-net 的自定义桥接网络
docker network create my-net

# 2. 运行两个容器,并连接到 my-net 网络
docker run -d --name web-app --network my-net nginx:alpine
docker run -it --name redis --network my-net redis:alpine redis-cli

# 3. 在 redis 容器中,你可以直接通过容器名 "web-app" ping 通另一个容器
# redis-alpine:/data# ping web-app
# PING web-app (172.21.0.2): 56 data bytes
# 64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.191 ms

2.2 Host 网络

host 网络让容器直接使用宿主机的网络栈,容器的网络配置与 host 完全一样,没有网络隔离。

特点:

  1. 容器共享宿主机的 IP 和端口空间
  2. 性能最好(无网络转发开销)
  3. 缺乏网络隔离,端口可能冲突
  4. 不支持端口映射(直接使用宿主机端口)
bash 复制代码
# 使用 host 网络运行 Nginx
docker run -d --name nginx-host --network host nginx:alpine

# 此时,Nginx 直接监听了宿主机的 80 端口。
# 访问 http://<host-ip> 即可,无需使用 -p 参数进行端口映射。

**注意:**如果宿主机上已经有进程占用了 80 端口,容器启动会失败。

2.3 None 网络

容器没有任何网络接口。

特点:

  1. 容器没有网络连接
  2. 仅能访问自身
  3. 适用于不需要网络的场景
bash 复制代码
docker run -it --rm --network none alpine:latest /bin/sh
# 在容器内执行 `ifconfig`,只会看到 lo(回环)接口。

3、容器间通信

3.1 同一网络内的容器通信

同一网络中的容器可以通过容器名或 IP 地址相互通信:

bash 复制代码
# 创建网络
docker network create my-network

# 启动两个容器在同一网络
docker run -d --name service1 --network my-network nginx
docker run -d --name service2 --network my-network nginx

# 从 service1 访问 service2
docker exec -it service1 ping service2

3.2 不同网络的容器通信

不同网络的容器默认无法通信,需要通过以下方式实现:

  • 将容器连接到两个网络
  • 使用端口映射通过宿主机中转
  • 使用专用的代理容器
bash 复制代码
# 将容器连接到第二个网络,此时该容器就会有和需要通信容器相同网络的网卡
docker network connect another-network service1

3.3 端口映射(容器与外部通信)

端口映射允许外部访问容器内的服务:

bash 复制代码
# 将容器的 80 端口映射到宿主机的 8080 端口
docker run -d -p 8080:80 --name web nginx

# 映射到指定 IP 的端口
docker run -d -p 192.168.1.100:8080:80 --name web nginx

# 随机映射端口(32768-60999)
docker run -d -P --name web nginx

4、网络故障排查

4.1 常用网络排查命令

bash 复制代码
# 查看容器网络详情
docker inspect -f '{{json .NetworkSettings}}' <container> | jq

# 查看容器IP地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container>

# 在容器内执行网络命令
docker exec -it <container> ping <host>
docker exec -it <container> curl <url>
docker exec -it <container> netstat -tulpn

# 查看网络连接情况
docker network inspect <network>

# 查看Docker网络相关的iptables规则
iptables -L -n | grep docker

4.2 常见网络问题及解决

  1. 容器无法访问外部网络
    • 检查 DNS 配置:cat /etc/resolv.conf
    • 检查防火墙规则
    • 重启 Docker 服务:systemctl restart docker
  2. 容器间无法通信
    • 确认容器在同一网络:docker network inspect <network>
    • 检查容器是否正常运行:docker ps
    • 检查容器内服务是否监听正确的地址(0.0.0.0 而非 127.0.0.1)
  3. 外部无法访问容器服务
    • 检查端口映射是否正确:docker port <container>
    • 检查容器内服务是否正常运行
    • 检查宿主机防火墙是否允许该端口

5、核心命令总结

  • docker network ls: 列出所有网络。
  • docker network create : 创建网络。
  • docker network inspect : 查看网络详细信息(包括连接的容器、IP 段等)。
  • docker network connect : 将运行中的容器连接到指定网络。
  • docker network disconnect : 从网络断开容器。
相关推荐
敲上瘾5 小时前
Docker 存储卷(Volume)核心概念、类型与操作指南
linux·服务器·数据库·docker·容器·架构
IT利刃出鞘6 小时前
Docker--宿主机和容器相互拷贝文件
运维·docker·容器
慕容晓开17 小时前
docker,本地目录挂载
docker
Mr. Cao code18 小时前
Docker:颠覆传统虚拟化的轻量级革命
linux·运维·ubuntu·docker·容器
Dontla18 小时前
Docker多共享网络配置策略(Docker多网络、Docker networks、Docker Compose网络、Docker网络、Docker共享网络)
网络·docker·容器
Jayin_chan19 小时前
paddlex3.0.1-ocr服务化安装部署(docker)
docker·容器·ocr
ifanatic19 小时前
[每周一更]-(第159期):Go 工程师视角:容器化技术(Docker/Kubernetes)与CI/CD流程的应用场景
docker·golang·kubernetes
感哥21 小时前
Docker镜像
docker
Dontla21 小时前
Dockerfile解析器指令(Parser Directive)指定语法版本,如:# syntax=docker/dockerfile:1
java·docker·eureka