冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

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

浏览:22次阅读
没有评论

共计 5696 个字符,预计需要花费 15 分钟才能阅读完成。

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

Docker 30 天实战系列 · Day 7

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

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

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


本文你将学到

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

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

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


前置准备

环境要求

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

环境检查

# 确认 Docker 正在运行
docker ps

# 查看当前网络列表
docker network ls

预期输出

NETWORK ID     NAME      DRIVER    SCOPE
xxxxxxxxxxxx   bridge    bridge    local
xxxxxxxxxxxx   host      host      local
xxxxxxxxxxxx   none      null      local

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

清理旧容器

为了避免端口冲突,先清理之前的实验容器:

# 停止并删除所有运行中的容器(谨慎使用)docker rm -f $(docker ps -aq) 2>/dev/null || true

Docker 网络模式详解

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

网络模式对比

┌─────────────────────────────────────────────────────────────┐
│                     Docker 网络模式                          │
├─────────────┬───────────────────────────────────────────────┤
│   bridge    │  默认模式,容器有独立 IP,通过 NAT 访问外网        │
├─────────────┼───────────────────────────────────────────────┤
│   host      │  容器直接使用宿主机网络,无网络隔离            │
├─────────────┼───────────────────────────────────────────────┤
│   none      │  容器没有网络,完全隔离                        │
├─────────────┼───────────────────────────────────────────────┤
│   自定义     │  用户创建的网络,推荐生产使用                  │
└─────────────┴───────────────────────────────────────────────┘

模式选择指南

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

实战一:探索默认 Bridge 网络

步骤 1:启动测试容器

# 启动两个 nginx 容器
docker run -d --name web1 nginx:alpine
docker run -d --name web2 nginx:alpine

步骤 2:查看容器 IP 地址

# 查看 web1 的 IP
docker inspect web1 --format '{{.NetworkSettings.IPAddress}}'

# 查看 web2 的 IP
docker inspect web2 --format '{{.NetworkSettings.IPAddress}}'

预期输出

172.17.0.2
172.17.0.3

步骤 3:测试容器间通信

# 进入 web1 容器,尝试访问 web2
docker exec web1 ping -c 3 172.17.0.3

预期输出

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.123 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.089 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.092 ms

IP 直连成功! 但是 …

步骤 4:发现问题 – 无法通过容器名通信

# 尝试用容器名访问
docker exec web1 ping -c 3 web2

预期输出

ping: bad address 'web2'

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

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

清理

docker rm -f web1 web2

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

自定义网络解决了默认 bridge 的两个问题:

  1. 容器名自动解析 – 可以直接用容器名通信
  2. 更好的隔离性 – 不同网络的容器默认无法互访

步骤 1:创建自定义网络

# 创建名为 myapp-network 的网络
docker network create myapp-network

验证创建成功

docker network ls

预期输出

NETWORK ID     NAME            DRIVER    SCOPE
xxxxxxxxxxxx   bridge          bridge    local
xxxxxxxxxxxx   host            host      local
xxxxxxxxxxxx   myapp-network   bridge    local   <-- 新创建的
xxxxxxxxxxxx   none            null      local

步骤 2:在自定义网络中启动容器

# 启动两个容器,加入同一个网络
docker run -d --name web1 --network myapp-network nginx:alpine
docker run -d --name web2 --network myapp-network nginx:alpine

步骤 3:验证容器名解析

# 用容器名直接访问
docker exec web1 ping -c 3 web2

预期输出

PING web2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.078 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.082 ms

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

步骤 4:测试 HTTP 访问

# 从 web1 访问 web2 的 nginx 服务
docker exec web1 wget -qO- http://web2

预期输出(nginx 欢迎页面的 HTML):




Welcome to nginx!
...

服务间通信成功!


实战三:端口映射详解

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

端口映射语法

-p [宿主机 IP:]宿主机端口: 容器端口[/ 协议]

常用端口映射方式

# 方式 1:映射到所有网卡的指定端口
docker run -d -p 8080:80 nginx:alpine
# 访问:http://localhost:8080

# 方式 2:只绑定到 localhost(更安全)docker run -d -p 127.0.0.1:8081:80 nginx:alpine
# 只能本机访问:http://127.0.0.1:8081

# 方式 3:随机端口映射
docker run -d -p 80 nginx:alpine
# Docker 自动分配宿主机端口

# 方式 4:映射 UDP 端口
docker run -d -p 53:53/udp dns-server

查看端口映射

# 查看所有容器的端口映射
docker ps

# 查看特定容器的端口
docker port <容器名>

端口映射示例

# 启动一个 nginx,映射到 8080 端口
docker run -d --name mynginx -p 8080:80 nginx:alpine

# 查看映射
docker port mynginx

预期输出

80/tcp -> 0.0.0.0:8080

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


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

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

架构图

                    ┌─────────────────┐
                    │   用户浏览器     │
                    └────────┬────────┘
                             │
                             ▼ :8080
┌────────────────────────────────────────────────────────────┐
│                      宿主机                                 │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              myapp-network (自定义网络)               │  │
│  │                                                      │  │
│  │   ┌─────────────┐          ┌─────────────┐          │  │
│  │   │   nginx     │  ──────> │   redis     │          │  │
│  │   │  :80        │          │   :6379     │          │  │
│  │   └─────────────┘          └─────────────┘          │  │
│  │         │                                            │  │
│  └─────────┼────────────────────────────────────────────┘  │
│            │                                               │
└────────────┼───────────────────────────────────────────────┘
             │
             ▼
       端口映射 8080:80

步骤 1:准备网络和容器

# 确保网络存在
docker network create myapp-network 2>/dev/null || true

# 启动 Redis
docker run -d \
  --name redis \
  --network myapp-network \
  redis:alpine

# 启动 Nginx(对外暴露端口)docker run -d \
  --name nginx \
  --network myapp-network \
  -p 8080:80 \
  nginx:alpine

步骤 2:验证容器状态

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

预期输出

NAMES     STATUS         PORTS
nginx     Up 10 seconds  0.0.0.0:8080->80/tcp
redis     Up 15 seconds  6379/tcp

步骤 3:验证内部通信

# 从 nginx 容器 ping redis
docker exec nginx ping -c 2 redis

# 测试 Redis 连接(使用 redis-cli)docker exec redis redis-cli ping

预期输出

PONG

步骤 4:验证外部访问

# 测试外部访问 nginx
curl http://localhost:8080

或者打开浏览器访问 http://localhost:8080

多容器应用搭建成功!


网络管理常用命令

网络操作命令速查

# 列出所有网络
docker network ls

# 创建网络
docker network create <网络名>

# 查看网络详情
docker network inspect <网络名>

# 删除网络
docker network rm <网络名>

# 删除所有未使用的网络
docker network prune

# 将容器连接到网络
docker network connect <网络名> <容器名>

# 将容器从网络断开
docker network disconnect <网络名> <容器名>

实用技巧

查看网络中的所有容器

docker network inspect myapp-network --format '{{range .Containers}}{{.Name}} {{end}}'

让已运行的容器加入网络

# 容器可以同时属于多个网络
docker network connect myapp-network 现有容器名

🤔 常见问题

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

A:按以下步骤排查:

# 1. 确认两个容器在同一个网络
docker inspect 容器 1 --format '{{.NetworkSettings.Networks}}'
docker inspect 容器 2 --format '{{.NetworkSettings.Networks}}'

# 2. 如果不在同一网络,手动连接
docker network connect myapp-network 容器名

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

A

# 查看端口占用
lsof -i :8080

# 或者使用其他端口
docker run -d -p 8081:80 nginx:alpine

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

A:会变!这就是为什么要用自定义网络 + 容器名访问,而不是硬编码 IP。

# 推荐:用容器名(不会变)redis://redis:6379

# 不推荐:用 IP(可能会变)redis://172.18.0.3:6379

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

A

# 查看完整网络配置
docker inspect 容器名 --format '{{json .NetworkSettings}}' | jq

# 或者简化版
docker inspect 容器名 | grep -A 20 NetworkSettings

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

A:当你需要 最高网络性能 不需要网络隔离 时:

# 使用 host 网络(Linux 下有效)docker run -d --network host nginx:alpine

# 容器直接使用宿主机 80 端口
curl http://localhost

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


📚 本文总结

核心要点

  1. 4 种网络模式

    • bridge:默认模式,适合开发测试
    • host:最高性能,无隔离
    • none:完全隔离
    • 自定义网络:生产推荐 ⭐
  2. 自定义网络的优势

    • ✅ 容器名自动 DNS 解析
    • ✅ 更好的网络隔离
    • ✅ 可以指定子网和网关
  3. 端口映射

    • -p 8080:80:映射到所有网卡
    • -p 127.0.0.1:8080:80:只绑定本地
    • -p 80:随机端口
  4. 最佳实践

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

命令速查表

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

实验清理

完成今天的学习后,清理实验环境:

# 删除所有实验容器
docker rm -f nginx redis web1 web2 mynginx 2>/dev/null

# 删除自定义网络
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 的核心基础知识。


💬 互动时间

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

今日作业

  1. 创建一个自定义网络
  2. 在网络中启动 nginx 和 redis
  3. 验证容器名可以互相访问
  4. 尝试端口映射,从浏览器访问 nginx

在评论区分享你的实践结果:

  • 💡 你遇到了什么问题?
  • ✅ 你是怎么解决的?
  • 🎯 你对 Docker 网络还有什么疑问?

如果这篇文章对你有帮助:

  • 👍 点个「赞」和「在看」
  • 🔄 分享给需要的朋友
  • 💬 评论区交流心得

📖 相关资源

官方文档

系列文章


关于本系列

这是「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!


正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计5696字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。