找回密码
 立即注册

QQ登录

只需一步,快速开始

peUfSYR.png
查看: 29|回复: 0

Day 07 Docker网络入门:让容器互相通信

[复制链接]

876

主题

13

回帖

2808

积分

管理员

积分
2808
发表于 2026-3-29 16:16:40 | 显示全部楼层 |阅读模式
🌐 Docker网络入门:让容器互相通信
Docker 30天实战系列 · Day 7

你是否遇到过这样的困惑:

  • 🤔 "容器之间怎么互相访问?" —— 启动了多个容器,却不知道怎么让它们通信
  • 🌐 "端口映射到底怎么用?" ——
    1. -p 8080:80
    复制代码
    这些参数让人头晕
  • 🔗 "微服务架构下容器怎么互联?" —— 前端、后端、数据库该如何配合

    今天,我们将揭开 Docker 网络的神秘面纱,让你彻底掌握容器间通信的核心技能。

    ━━━━━━━━━━━━━━━━━━━━

    本文你将学到

    完成今天的学习后,你将能够:

  • ✅ 理解 Docker 的 4 种网络模式及其适用场景
  • ✅ 创建自定义网络实现容器间通信
  • ✅ 掌握端口映射的各种用法
  • ✅ 搭建一个完整的多容器应用架构

    阅读时间:约 15-20 分钟
    实操时间:约 20-30 分钟
    难度等级:⭐⭐⭐☆☆

    ━━━━━━━━━━━━━━━━━━━━

    前置准备

    环境要求

    | 项目 | 要求 | 检查命令 |
    |------|------|----------|
    | Docker | 20.10+ |
    1. docker --version
    复制代码
    |
    | 操作系统 | macOS / Windows / Linux | - |
    | 前置知识 | Day 1-6 内容 | - |

    环境检查
    1. # 确认 Docker 正在运行
    2. docker ps
    3. # 查看当前网络列表
    4. docker network ls
    复制代码

    预期输出
    1. NETWORK ID     NAME      DRIVER    SCOPE
    2. xxxxxxxxxxxx   bridge    bridge    local
    3. xxxxxxxxxxxx   host      host      local
    4. xxxxxxxxxxxx   none      null      local
    复制代码

    如果看到这三个默认网络,说明环境准备就绪。

    清理旧容器

    为了避免端口冲突,先清理之前的实验容器:
    1. # 停止并删除所有运行中的容器(谨慎使用)
    2. docker rm -f $(docker ps -aq) 2>/dev/null || true
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    Docker 网络模式详解

    Docker 提供了 4 种主要的网络模式,每种模式适用于不同的场景。

    网络模式对比
    1. ┌─────────────────────────────────────────────────────────────┐
    2. │                     Docker 网络模式                          │
    3. ├─────────────┬───────────────────────────────────────────────┤
    4. │   bridge    │  默认模式,容器有独立IP,通过NAT访问外网        │
    5. ├─────────────┼───────────────────────────────────────────────┤
    6. │   host      │  容器直接使用宿主机网络,无网络隔离            │
    7. ├─────────────┼───────────────────────────────────────────────┤
    8. │   none      │  容器没有网络,完全隔离                        │
    9. ├─────────────┼───────────────────────────────────────────────┤
    10. │   自定义     │  用户创建的网络,推荐生产使用                  │
    11. └─────────────┴───────────────────────────────────────────────┘
    复制代码

    模式选择指南

    | 网络模式 | 隔离性 | 性能 | 适用场景 |
    |----------|--------|------|----------|
    | bridge (默认) | 中 | 好 | 单机多容器、开发测试 |
    | host | 无 | 最佳 | 性能敏感的网络应用 |
    | none | 最强 | - | 安全隔离、离线计算 |
    | 自定义网络 | 可控 | 好 | 生产环境推荐 |

    ━━━━━━━━━━━━━━━━━━━━

    实战一:探索默认 Bridge 网络

    步骤 1:启动测试容器
    1. # 启动两个 nginx 容器
    2. docker run -d --name web1 nginx:alpine
    3. docker run -d --name web2 nginx:alpine
    复制代码

    步骤 2:查看容器 IP 地址
    1. # 查看 web1 的 IP
    2. docker inspect web1 --format '{{.NetworkSettings.IPAddress}}'
    3. # 查看 web2 的 IP
    4. docker inspect web2 --format '{{.NetworkSettings.IPAddress}}'
    复制代码

    预期输出
    1. 172.17.0.2
    2. 172.17.0.3
    复制代码

    步骤 3:测试容器间通信
    1. # 进入 web1 容器,尝试访问 web2
    2. docker exec web1 ping -c 3 172.17.0.3
    复制代码

    预期输出
    1. PING 172.17.0.3 (172.17.0.3): 56 data bytes
    2. 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.123 ms
    3. 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.089 ms
    4. 64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.092 ms
    复制代码

    IP 直连成功! 但是...

    步骤 4:发现问题 - 无法通过容器名通信
    1. # 尝试用容器名访问
    2. docker exec web1 ping -c 3 web2
    复制代码

    预期输出
    1. ping: bad address 'web2'
    复制代码

    失败了! 默认 bridge 网络不支持容器名解析。

    这就是为什么我们需要自定义网络

    清理
    1. docker rm -f web1 web2
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    实战二:创建自定义网络(推荐方式)

    自定义网络解决了默认 bridge 的两个问题:
  • 容器名自动解析 - 可以直接用容器名通信
  • 更好的隔离性 - 不同网络的容器默认无法互访

    步骤 1:创建自定义网络
    1. # 创建名为 myapp-network 的网络
    2. docker network create myapp-network
    复制代码

    验证创建成功
    1. docker network ls
    复制代码

    预期输出
    1. NETWORK ID     NAME            DRIVER    SCOPE
    2. xxxxxxxxxxxx   bridge          bridge    local
    3. xxxxxxxxxxxx   host            host      local
    4. xxxxxxxxxxxx   myapp-network   bridge    local   <-- 新创建的
    5. xxxxxxxxxxxx   none            null      local
    复制代码

    步骤 2:在自定义网络中启动容器
    1. # 启动两个容器,加入同一个网络
    2. docker run -d --name web1 --network myapp-network nginx:alpine
    3. docker run -d --name web2 --network myapp-network nginx:alpine
    复制代码

    步骤 3:验证容器名解析
    1. # 用容器名直接访问
    2. docker exec web1 ping -c 3 web2
    复制代码

    预期输出
    1. PING web2 (172.18.0.3): 56 data bytes
    2. 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.089 ms
    3. 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.078 ms
    4. 64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.082 ms
    复制代码

    成功! 容器名自动解析为 IP 地址。

    步骤 4:测试 HTTP 访问
    1. # 从 web1 访问 web2 的 nginx 服务
    2. docker exec web1 wget -qO- http://web2
    复制代码

    预期输出(nginx 欢迎页面的 HTML):
    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <title>Welcome to nginx!</title>
    5. ...
    复制代码

    服务间通信成功!

    ━━━━━━━━━━━━━━━━━━━━

    实战三:端口映射详解

    端口映射让外部网络可以访问容器内的服务。

    端口映射语法
    1. -p [宿主机IP:]宿主机端口:容器端口[/协议]
    复制代码

    常用端口映射方式
    1. # 方式1:映射到所有网卡的指定端口
    2. docker run -d -p 8080:80 nginx:alpine
    3. # 访问:http://localhost:8080
    4. # 方式2:只绑定到 localhost(更安全)
    5. docker run -d -p 127.0.0.1:8081:80 nginx:alpine
    6. # 只能本机访问:http://127.0.0.1:8081
    7. # 方式3:随机端口映射
    8. docker run -d -p 80 nginx:alpine
    9. # Docker 自动分配宿主机端口
    10. # 方式4:映射 UDP 端口
    11. docker run -d -p 53:53/udp dns-server
    复制代码

    查看端口映射
    1. # 查看所有容器的端口映射
    2. docker ps
    3. # 查看特定容器的端口
    4. docker port <容器名>
    复制代码

    端口映射示例
    1. # 启动一个 nginx,映射到 8080 端口
    2. docker run -d --name mynginx -p 8080:80 nginx:alpine
    3. # 查看映射
    4. docker port mynginx
    复制代码

    预期输出
    1. 80/tcp -> 0.0.0.0:8080
    复制代码

    访问测试
    打开浏览器访问
    1. http://localhost:8080
    复制代码
    ,应该看到 nginx 欢迎页面。

    ━━━━━━━━━━━━━━━━━━━━

    实战四:搭建完整的多容器应用

    让我们搭建一个真实的应用架构:Nginx (前端) + Redis (缓存)

    架构图
    1.                     ┌─────────────────┐
    2.                     │   用户浏览器     │
    3.                     └────────┬────────┘
    4.                              │
    5.                              ▼ :8080
    6. ┌────────────────────────────────────────────────────────────┐
    7. │                      宿主机                                 │
    8. │  ┌──────────────────────────────────────────────────────┐  │
    9. │  │              myapp-network (自定义网络)               │  │
    10. │  │                                                      │  │
    11. │  │   ┌─────────────┐          ┌─────────────┐          │  │
    12. │  │   │   nginx     │  ──────> │   redis     │          │  │
    13. │  │   │  :80        │          │   :6379     │          │  │
    14. │  │   └─────────────┘          └─────────────┘          │  │
    15. │  │         │                                            │  │
    16. │  └─────────┼────────────────────────────────────────────┘  │
    17. │            │                                               │
    18. └────────────┼───────────────────────────────────────────────┘
    19.              │
    20.              ▼
    21.        端口映射 8080:80
    复制代码

    步骤 1:准备网络和容器
    1. # 确保网络存在
    2. docker network create myapp-network 2>/dev/null || true
    3. # 启动 Redis
    4. docker run -d \
    5.   --name redis \
    6.   --network myapp-network \
    7.   redis:alpine
    8. # 启动 Nginx(对外暴露端口)
    9. docker run -d \
    10.   --name nginx \
    11.   --network myapp-network \
    12.   -p 8080:80 \
    13.   nginx:alpine
    复制代码

    步骤 2:验证容器状态
    1. docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
    复制代码

    预期输出
    1. NAMES     STATUS         PORTS
    2. nginx     Up 10 seconds  0.0.0.0:8080->80/tcp
    3. redis     Up 15 seconds  6379/tcp
    复制代码

    步骤 3:验证内部通信
    1. # 从 nginx 容器 ping redis
    2. docker exec nginx ping -c 2 redis
    3. # 测试 Redis 连接(使用 redis-cli)
    4. docker exec redis redis-cli ping
    复制代码

    预期输出
    1. PONG
    复制代码

    步骤 4:验证外部访问
    1. # 测试外部访问 nginx
    2. curl http://localhost:8080
    复制代码

    或者打开浏览器访问
    1. http://localhost:8080
    复制代码

    多容器应用搭建成功!

    ━━━━━━━━━━━━━━━━━━━━

    网络管理常用命令

    网络操作命令速查
    1. # 列出所有网络
    2. docker network ls
    3. # 创建网络
    4. docker network create <网络名>
    5. # 查看网络详情
    6. docker network inspect <网络名>
    7. # 删除网络
    8. docker network rm <网络名>
    9. # 删除所有未使用的网络
    10. docker network prune
    11. # 将容器连接到网络
    12. docker network connect <网络名> <容器名>
    13. # 将容器从网络断开
    14. docker network disconnect <网络名> <容器名>
    复制代码

    实用技巧

    查看网络中的所有容器
    1. docker network inspect myapp-network --format '{{range .Containers}}{{.Name}} {{end}}'
    复制代码

    让已运行的容器加入网络
    1. # 容器可以同时属于多个网络
    2. docker network connect myapp-network 现有容器名
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    🤔 常见问题

    Q1:容器之间 ping 不通怎么办?

    A:按以下步骤排查:
    1. # 1. 确认两个容器在同一个网络
    2. docker inspect 容器1 --format '{{.NetworkSettings.Networks}}'
    3. docker inspect 容器2 --format '{{.NetworkSettings.Networks}}'
    4. # 2. 如果不在同一网络,手动连接
    5. docker network connect myapp-network 容器名
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    Q2:端口已被占用怎么办?

    A
    1. # 查看端口占用
    2. lsof -i :8080
    3. # 或者使用其他端口
    4. docker run -d -p 8081:80 nginx:alpine
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    Q3:容器重启后 IP 会变吗?

    A:会变!这就是为什么要用自定义网络 + 容器名访问,而不是硬编码 IP。
    1. # 推荐:用容器名(不会变)
    2. redis://redis:6379
    3. # 不推荐:用 IP(可能会变)
    4. redis://172.18.0.3:6379
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    Q4:如何查看容器的网络配置?

    A
    1. # 查看完整网络配置
    2. docker inspect 容器名 --format '{{json .NetworkSettings}}' | jq
    3. # 或者简化版
    4. docker inspect 容器名 | grep -A 20 NetworkSettings
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    Q5:host 网络模式什么时候用?

    A:当你需要最高网络性能不需要网络隔离时:
    1. # 使用 host 网络(Linux 下有效)
    2. docker run -d --network host nginx:alpine
    3. # 容器直接使用宿主机 80 端口
    4. curl http://localhost
    复制代码

    ⚠️ 注意:host 模式在 macOS/Windows 的 Docker Desktop 上行为不同。

    ━━━━━━━━━━━━━━━━━━━━

    📚 本文总结

    核心要点

  • 4 种网络模式
    1. bridge
    复制代码
    :默认模式,适合开发测试
    1. host
    复制代码
    :最高性能,无隔离
    1. none
    复制代码
    :完全隔离
  • 自定义网络:生产推荐 ⭐

  • 自定义网络的优势
  • ✅ 容器名自动 DNS 解析
  • ✅ 更好的网络隔离
  • ✅ 可以指定子网和网关

  • 端口映射
    1. -p 8080:80
    复制代码
    :映射到所有网卡
    1. -p 127.0.0.1:8080:80
    复制代码
    :只绑定本地
    1. -p 80
    复制代码
    :随机端口

  • 最佳实践
  • 始终使用自定义网络
  • 通过容器名通信,不要用 IP
  • 只暴露必要的端口

    命令速查表

    | 命令 | 说明 |
    |------|------|
    |
    1. docker network ls
    复制代码
    | 列出网络 |
    |
    1. docker network create mynet
    复制代码
    | 创建网络 |
    |
    1. docker network inspect mynet
    复制代码
    | 查看网络详情 |
    |
    1. docker network rm mynet
    复制代码
    | 删除网络 |
    |
    1. docker run --network mynet
    复制代码
    | 指定网络启动 |
    |
    1. docker network connect mynet 容器
    复制代码
    | 连接容器到网络 |

    ━━━━━━━━━━━━━━━━━━━━

    实验清理

    完成今天的学习后,清理实验环境:
    1. # 删除所有实验容器
    2. docker rm -f nginx redis web1 web2 mynginx 2>/dev/null
    3. # 删除自定义网络
    4. docker network rm myapp-network custom-net 2>/dev/null
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    下一步学习

    今天我们学习了 Docker 网络的基础知识。这是构建复杂应用的关键技能!

    明天预告:Day 8 - 编写你的第一个 Dockerfile:Node.js 应用容器化

    我们将学习如何编写 Dockerfile,把自己的应用打包成 Docker 镜像。

    第一周回顾
  • ✅ Day 1:Docker 是什么
  • ✅ Day 2:Docker 安装
  • ✅ Day 3:第一个容器
  • ✅ Day 4:镜像管理
  • ✅ Day 5:常用容器实战
  • ✅ Day 6:数据持久化
  • ✅ Day 7:Docker 网络(今天)

    🎉 恭喜完成第一周的学习! 你已经掌握了 Docker 的核心基础知识。

    ━━━━━━━━━━━━━━━━━━━━

    💬 互动时间

    今日思考:在你的项目中,哪些服务需要互相通信?你会如何设计它们的网络架构?

    今日作业
  • 创建一个自定义网络
  • 在网络中启动 nginx 和 redis
  • 验证容器名可以互相访问
  • 尝试端口映射,从浏览器访问 nginx

    在评论区分享你的实践结果:
  • 💡 你遇到了什么问题?
  • ✅ 你是怎么解决的?
  • 🎯 你对 Docker 网络还有什么疑问?

    如果这篇文章对你有帮助:
  • 👍 点个「赞」和「在看」
  • 🔄 分享给需要的朋友
  • 💬 评论区交流心得

    ━━━━━━━━━━━━━━━━━━━━

    📖 相关资源

    官方文档
  • Docker 网络概述
  • Bridge 网络驱动
  • Host 网络驱动

    系列文章
  • 上一篇:Day 6 - Docker 卷完全指南
  • 下一篇:Day 8 - 编写你的第一个 Dockerfile

    ━━━━━━━━━━━━━━━━━━━━

    关于本系列

    这是「Docker 30天实战系列」的第 7 篇文章。

    本系列将用 30 天时间,带你从零基础到实战部署,系统掌握 Docker 容器技术:

  • Week 1:基础入门 ✅ 完成!
  • Week 2:镜像构建(Dockerfile、优化、最佳实践)
  • Week 3:容器编排(Docker Compose、多容器)
  • Week 4:生产实践(安全、性能、CI/CD)

    🔔 关注公众号,不错过每一篇干货!

    下周见!我们将进入 Dockerfile 编写的精彩世界 🚀

    ━━━━━━━━━━━━━━━━━━━━

    作者:Docker 实战系列
    发布日期:2026-02-16
    系列进度:7/30

    🐳 Happy Dockering!

    ━━━━━━━━━━━━━━━━━━━━
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码关注微信公众号

    Archiver|手机版|小黑屋|风叶林

    GMT+8, 2026-5-8 23:02 , Processed in 0.231153 second(s), 20 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表