找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]

1736

主题

14

回帖

5640

积分

管理员

积分
5640
发表于 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-11-6 00:54 , Processed in 0.038054 second(s), 20 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

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