【Docker】网络介绍
- 【一】底层核心原理
- 1. Linux 底层支撑技术
- 2. 数据流转简单流程(桥接模式默认)
- 【二】Docker 内置 5 种网络驱动
- 1. bridge 默认网桥(docker0)
- 2. 自定义 bridge(生产首选)
- 3. host 主机网络
- 4. none 无网络
- 5. container 复用容器网络
- 【三】网络常用操作:创建、查看、连接、删除
- 1. 查看所有网络
- 2. 创建自定义网桥(重点)
- 3. 启动容器时指定网络
- 方式 1:创建容器直接加入自定义网络
- 方式 2:host 主机网络
- 方式 3:none 无网络
- 方式 4:复用其他容器网络
- 4. 容器运行后动态连接 / 断开网络
- 5. 删除网络
- 【四】端口映射原理(-p)
- 1. 两种写法
- 底层原理
- 【五】不指定 --network 时默认行为
- (1)底层环境
- (2)完整场景演示
- (3)生产环境结论
- 【六】容器间通信规则
- 【七】跨主机 Docker 网络(Overlay,简单补充)
- 【八】生产最佳实践总结
【一】底层核心原理
1. Linux 底层支撑技术
Docker 网络完全基于 Linux 内核四大技术实现:
- Network Namespace(网络命名空间)
内核隔离技术,每个容器拥有独立网络栈:独立网卡、IP、路由表、iptables、端口、DNS。
容器与宿主机、其他容器网络默认隔离,相当于一台独立虚拟机网络环境。 - veth pair(虚拟网线)
一对成对虚拟网卡,一端宿主机网桥,一端容器 namespace,实现宿主机 ↔ 容器数据互通。 - Linux Bridge(虚拟网桥)
宿主机虚拟交换机,多个 veth 网卡挂载到网桥,同网桥下容器二层互通。 - iptables / netfilter
端口映射、SNAT/DNAT、访问控制、内外网转发、隔离策略全部依靠 iptables 规则实现。 - 路由转发 ip_forward
宿主机开启内核转发,容器才能访问外网。
2. 数据流转简单流程(桥接模式默认)
- 容器内程序发包 → 容器内 eth0(veth 一端)
- 通过 veth pair 转发到宿主机网桥 docker0
- 网桥转发给同网络其他容器 / 交给宿主机网卡
- 访问外网时 iptables 做 SNAT 源地址转换,走宿主机物理网卡出去
- 外部访问容器端口:iptables DNAT 转发流量到容器内部 IP + 端口
【二】Docker 内置 5 种网络驱动
执行docker network ls可查看默认网络
表格
| 网络类型 | 驱动 | 用途 | 默认创建 |
|---|---|---|---|
| 桥接网络 | bridge | 单机容器互通,最常用 | 自动创建bridge(docker0) |
| 主机网络 | host | 容器共享宿主机网卡,无隔离 | 不默认创建,手动使用 |
| 无网络 | none | 容器完全禁用网络,隔离 | 自动创建none |
| 容器互联 | container | 复用另一个容器网络栈 | 无需提前创建,运行时指定 |
| 自定义网桥 | bridge | 推荐生产使用,自定义网段、DNS、隔离分组 | 手动docker network create创建 |
1. bridge 默认网桥(docker0)
- 宿主机开机启动 docker 自动创建虚拟网桥 docker0,网段默认
172.17.0.0/16 - 不指定网络的容器默认接入 docker0
- 同 docker0 容器之间可以通过容器名 / IP 互相访问
- 外部访问容器需要
-p 宿主机端口:容器端口端口映射
缺点:
多项目容器混在同一网段,无隔离;无法自定义网段;复杂环境混乱。生产不建议直接用默认 docker0,推荐自定义 bridge。
2. 自定义 bridge(生产首选)
和默认 bridge 原理一致,但支持自定义网段、子网、网关、标签,实现项目网络隔离。
同一自定义网络内容器可直接用容器名称互相解析访问,跨自定义网络默认不通。
3. host 主机网络
容器不创建独立 network namespace,直接复用宿主机物理网卡、IP、端口。
- 优势:无端口转发损耗,性能极高
- 缺点:无网络隔离,容器直接占用宿主机端口,多服务端口冲突风险大;无法端口映射
-p失效
适用:高性能中间件(如 k8s node、监控采集、网关)
4. none 无网络
容器只有 lo 本地回环网卡,无任何外部网络,完全隔离。
适用:纯本地计算、安全离线任务。
5. container 复用容器网络
新容器共享已有容器的 network namespace,共用同一张网卡、同一个 IP。
用法:--network container:容器ID/名称
适用:sidecar 边车容器(日志采集、监控代理),和主容器共享网络。
【三】网络常用操作:创建、查看、连接、删除
1. 查看所有网络
docker network ls # 查看网络详情(网段、挂载容器、配置) docker network inspect 网络名/ID2. 创建自定义网桥(重点)
基础语法:
docker network create [参数] 网络名称常用参数:
--subnet:自定义子网网段--gateway:网关地址--driver bridge:指定网桥驱动(默认)-d overlay:跨主机集群网络(Swarm)--attachable:允许容器后期动态接入网络
示例:创建业务专属网络 app-net
# 指定网段 172.20.0.0/16,网关172.20.0.1 docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 app-net3. 启动容器时指定网络
方式 1:创建容器直接加入自定义网络
# 容器web加入app-net,映射8080端口 docker run -d --name web --network app-net -p 8080:80 nginx # mysql 同网络,和web互通 docker run -d --name mysql --network app-net -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7此时 web 容器可直接用mysql作为域名连接数据库,Docker 内置 DNS 自动解析容器名。
方式 2:host 主机网络
# 共享宿主机网络,无需-p端口映射 docker run -d --name agent --network host prom/node-exporter方式 3:none 无网络
docker run -it --name offline --network none centos方式 4:复用其他容器网络
# 复用web容器网络栈 docker run -it --name sidecar --network container:web busybox4. 容器运行后动态连接 / 断开网络
容器启动后可以中途加入其他网络,实现跨网络互通:
# 将已存在容器连接到指定网络 docker network connect app-net web # 断开容器与网络 docker network disconnect app-net web5. 删除网络
# 删除闲置网络(无容器挂载才能删除) docker network rm app-net # 清理所有未使用网络 docker network prune【四】端口映射原理(-p)
1. 两种写法
# 宿主机所有网卡 8080 → 容器80 -p 8080:80 # 指定宿主机IP 192.168.1.100:8080 → 容器80 -p 192.168.1.100:8080:80 # 随机宿主机端口映射容器80 -p :80底层原理
- Docker 自动在宿主机 iptables 添加 DNAT 规则
- 外部请求访问宿主机 IP:8080 → iptables 转发到容器内部 IP:80
- 容器回包时做 SNAT,修改源地址为宿主机网桥地址
- host 网络模式不经过端口映射,直接监听宿主机端口
【五】不指定 --network 时默认行为
执行docker run不加--network xxx,容器会自动接入 Docker 默认网桥bridge(宿主机虚拟网卡 docker0)。
(1)底层环境
- 自动分配
172.17.0.0/16网段内一个空闲 IP,网关为172.17.0.1(docker0 网桥地址); - 自动创建一对 veth pair 虚拟网卡,一端挂 docker0,一端进容器网络命名空间;
- 容器拥有独立网络栈,和宿主机、其他容器隔离。
(1)能做什么
- 同属默认 bridge 的容器可以互通
所有没指定自定义网络的容器都在 docker0 网段,互相之间可以通过容器 IP 访问。 - 容器能访问外网
Docker 自动配置 iptables SNAT 规则,容器流量经过宿主机转发访问互联网。 - 宿主机可以访问容器
只要启动时加-p 宿主机端口:容器端口做端口映射,外部 / 宿主机就能访问容器服务。 - 宿主机内部可直接 ping 容器内部 IP。
(2)关键限制(和自定义 bridge 最大区别)
默认 bridge 不支持 Docker DNS 容器名解析
这是最核心痛点:
- 自定义 bridge:同网络容器可以直接用容器名称互相访问(如
curl nginx); - 默认 docker0 bridge:只能用 IP 访问,容器名无法解析。
示例:
# 两个容器都不指定网络,都在默认bridgedockerrun-d--nameng nginxdockerrun-it--namebus busybox# bus 里 ping ng 会失败(域名解析失败)pingng# 只能 ping ng 的容器IP才能通(3)无法和自定义 bridge 网络互通
假设:
- A 容器:未指定网络 → 默认 bridge (docker0)
- B 容器:加入自定义网络 app-net
两者默认完全隔离,互相 ping 不通。
想要互通只能手动执行:
dockernetwork connect bridge B容器名# 或dockernetwork connect app-net A容器名(4)网段不可自定义
默认网段固定172.17.0.0/16,不能修改子网、网关,多业务混在一起无网络隔离,容易 IP 冲突、维护混乱。
(5)无业务分组隔离
所有不指定网络的容器挤在同一个大网段,测试、预发、业务容器混在一起,安全边界模糊。
(2)完整场景演示
# 容器1:不指定网络,进默认bridgedockerrun-d--nameweb nginx# 容器2:不指定网络,同默认bridgedockerrun-it--nametestbusybox# 1. test ping web IP 能通# 2. test ping web 容器名 解析失败# 3. 新建一个自定义网络容器 mysql,test 和 mysql 互相不通(3)生产环境结论
- 本地临时测试、一次性容器可以不指定网络,省事;
- 正式业务服务必须创建自定义 bridge 并手动 --network 指定:
- 支持容器名称 DNS 互通;
- 业务网络隔离;
- 可自定义网段、网关;
- 方便权限、访问控制分组。
【六】容器间通信规则
- 同一自定义 bridge 网络
容器之间互通,Docker DNS 解析容器名称,直接使用容器名访问,无需 IP。 - 不同自定义 bridge 网络
默认隔离,互相不通;如需互通,用docker network connect将容器加入对方网络。 - 默认 docker0 网桥容器
同网段互通,但无法和自定义 bridge 容器互通。 - host 模式容器
可直接访问宿主机所有服务、所有网段容器。 - none 网络
只能访问自身 127.0.0.1,无法和任何外部通信。
【七】跨主机 Docker 网络(Overlay,简单补充)
前面所有 bridge 仅限单台宿主机容器互通;多台服务器容器互通使用overlay驱动,依赖 Docker Swarm:
- 初始化 swarm 集群:
docker swarm init - 创建 overlay 网络:
docker network create -d overlay swarm-net- 不同节点容器加入 swarm-net 即可跨服务器通信
底层基于 VXLAN 隧道技术,封装 UDP 数据包跨物理主机传输。
【八】生产最佳实践总结
- 禁止直接使用默认 docker0,每个业务项目单独创建自定义 bridge 网络,实现环境隔离;
- 所有业务容器统一加入同一张自定义网络,利用容器名 DNS 互通,无需写死 IP;
- 数据库、中间件容器不暴露外网端口,仅同网络业务容器访问,提升安全;
- 高性能采集组件使用
host网络,普通 web / 数据库使用自定义 bridge; - 离线计算类容器使用
none网络缩小攻击面; - 禁止容器以 root+host 网络运行对外服务,风险极高。