一、三个网络模式:从"隔离"到"共享"
"小陈,容器默认是'谁也看不见谁'的(Namespace 隔离)。要让它们通信,得用 Docker 的网络。"老周说,"Docker 有几种内置网络模式,先记最常用的三个:"
① bridge(桥接,默认):
每个容器分配一个内网 IP(172.17.x.x)
容器之间通过虚拟网桥通信
容器默认"不暴露"端口,要映射才能被外部访问
✅ 默认、常用、隔离性好
② host(宿主机):
容器直接用宿主机的网络栈(没有自己的 IP)
容器端口 = 宿主机端口
✅ 性能好(无 NAT),❌ 隔离差、容易端口冲突
③ none:
没有网络(完全隔离)
适合纯计算任务(不需要网络)
docker network ls # 查看网络
docker run --network=bridge ... # 指定网络
"默认 bridge 是 90% 场景的选择——隔离好、够用。host 只有在'要极高性能'时才考虑。"
二、端口映射:让外面的世界访问容器
"容器在 bridge 网络里有一个内网 IP,但外部(宿主机之外)访问不到。要让外面能访问,必须做端口映射(Port Mapping):"老周演示:
# 把容器的 8000 端口,映射到宿主机的 80 端口
docker run -d -p 80:8000 --name web01 yunjian/web:v1
# 格式:-p 宿主机端口:容器端口
# 访问 http://宿主机IP:80 → 转发到容器内 8000
# 其他映射方式
docker run -d -p 8080:8000 web01 # 指定端口
docker run -d -p 8000 web01 # 随机宿主机端口
docker run -d -p 443:443 -p 80:80 nginx # 多个端口
# 查看映射关系
docker port web01 # 80/tcp -> 0.0.0.0:80
"-p 宿主机端口:容器端口 这个格式必须刻进脑子。 左边是外面访问的,右边是容器里面的。搞反了你就访问不到了。"
三、容器互联:用名字代替 IP
"端口映射解决'外部访问容器',但容器之间互相访问怎么办?"老周说,"容器每次重启 IP 都可能变——总不能用 IP 通信吧?"
方案:自定义网络 + 容器名(DNS 解析)
第一步:创建自定义网络
docker network create yunjian-net
第二步:把容器放进同一个网络
docker run -d --network yunjian-net --name db01 mysql
docker run -d --network yunjian-net --name web01 yunjian/web
第三步:容器之间直接用"名字"访问!
web01 里访问数据库:db01:3306
(Docker 内置 DNS 会把名字解析成对应 IP)
关键:只有在"同一个自定义网络"里的容器才能用名字互访
默认 bridge 网络不支持容器名互访(要 --link,已过时)
# 验证:从 web01 ping db01
docker exec -it web01 bash
ping db01 # 能通!(名字被解析成 db01 的 IP)
mysql -h db01 -P 3306 ... # 应用里就用 db01 当主机名
"生产实践:所有业务容器放进同一个自定义网络,用容器名互访。 这样容器 IP 怎么变都不用改配置——代码里写死 db01、cache01 这些名字就行。"
四、云间书店的网络拓扑
老周带小陈设计云间书店容器化的网络:
云间书店容器网络拓扑:
宿主机
┌─────────────────────────┐
│ 外部访问 → 宿主机:80 │
│ │ 端口映射 │
│ ▼ │
│ yunjian-net(自定义网络) │
│ ┌─────────┐ │
│ │ web01 │ (前端) │
│ │ 80:8000 │ │
│ └────┬────┘ │
│ │ web01:8000 │
│ ┌────┴────┐ │
│ │ api01 │ (后端 API) │
│ └────┬────┘ │
│ │ api01:5000 │
│ ┌────┴────┐ ┌───────┐ │
│ │ db01 │ │ cache01│ │
│ │ mysql │ │ redis │ │
│ └─────────┘ └───────┘ │
└─────────────────────────┘
外部 → 宿主机:80 → web01(只有 web 对外)
web01 → api01:5000(内部,用名字访问)
api01 → db01:3306 / cache01:6379(内部)
数据库不对外暴露端口!(安全)
"记住:只有需要被外部访问的容器才做端口映射,内部服务(数据库、缓存)绝不映射端口,只在自定义网络内部通信。 这是容器网络安全的第一条规则。"
五、网络排障三件套
"容器连不上,怎么排查?三个命令:"老周说:
# 1. 看容器 IP 和网络
docker inspect web01 | grep -i ip
# 2. 进容器测试连通性
docker exec -it web01 bash
curl http://api01:5000/health # 测 API
ping db01 # 测连通
# 3. 看网络连接
docker network inspect yunjian-net # 看谁在这个网络里
# 常见问题速查:
# - 容器间不通:不在同一个网络?
# - 名字解析不了:确认都在自定义网络里?
# - 外部访问不了:端口映射写反了?宿主机防火墙?
"网络问题 80% 出在'不在同一网络'或'端口映射写错'——按这个思路查,大部分都能解决。"
六、章末:老周的第五层总结
第五层:容器网络
├── 三种模式:bridge(默认)/ host / none
├── 端口映射:-p 宿主机端口:容器端口(外部访问容器)
├── 容器互联:自定义网络 + 容器名(用名字代替 IP)
├── 安全规则:只有对外服务映射端口,数据库不暴露
└── 排障:inspect / exec curl / network inspect
"小陈,现在你有了:镜像、容器、数据卷、网络——单容器已经玩明白了。 但是,云间书店的直播带货模块有 5 个组件,你要一条条命令地启动 5 个容器、配 5 次网络、加 5 个数据卷……每次部署都要敲几十条命令?"
小陈:"……手都要敲断了。"
"所以下一章,我们学编排——用 docker-compose 把'整个系统的启动配置'写成一个文件,一条命令,全家桶全部拉起。这是从'管单个容器'到'管一套系统'的飞跃。"