长安的Docker教程长安的Docker教程
首页
快速开始
编程指南
首页
快速开始
编程指南
  • 🎯 Docker入门篇

    • 快速开始
    • Docker是什么?
    • 为什么要用Docker?
    • 安装Docker
    • 第一个容器
  • 📦 Docker基础篇

    • Docker镜像详解
    • 容器操作详解
    • 编写Dockerfile
    • 数据卷(Volumes)
    • Docker网络
  • ⚡ Docker进阶篇

    • Docker Compose
    • 多阶段构建
    • Docker性能优化
    • Docker最佳实践
  • 🚀 实战项目

    • 实战:部署Node.js应用
    • 实战:搭建数据库环境
    • 实战:微服务架构
  • 💡 常见问题

    • 常见问题排查
    • 实用技巧

Docker网络

嘿!长安来讲Docker网络了!这个看起来复杂,但我会用最简单的方式讲给你听!🌐

🤔 为什么需要网络?

问题场景

# 运行一个Web应用
docker run -d --name web nginx

# 运行一个MySQL数据库
docker run -d --name db mysql

# 问题:web容器怎么连接到db容器?

答案:Docker网络!

📚 Docker网络类型

Docker有几种网络模式:

1. bridge(桥接网络)- 默认

# 不指定网络,默认就是bridge
docker run -d nginx

特点:

  • 容器之间可以互相访问
  • 容器可以访问外网
  • 外网不能直接访问容器(需要端口映射)

2. host(主机网络)

docker run -d --network host nginx

特点:

  • 容器直接使用宿主机网络
  • 没有网络隔离
  • 性能最好
  • 端口冲突风险高

3. none(无网络)

docker run -d --network none nginx

特点:

  • 容器没有网络
  • 完全隔离
  • 适合安全要求极高的场景

4. container(容器网络)

# 容器2使用容器1的网络
docker run -d --name web1 nginx
docker run -d --name web2 --network container:web1 nginx

特点:

  • 共享网络栈
  • 可以用localhost互相访问
  • 端口冲突风险

5. 自定义网络(最推荐!)

# 创建自定义网络
docker network create my-network

# 使用自定义网络
docker run -d --network my-network --name web nginx
docker run -d --network my-network --name db mysql

特点:

  • 容器可以通过容器名互相访问
  • 更好的隔离性
  • 生产环境首选!

💡 长安建议:生产环境用自定义网络!

🌐 自定义网络详解

创建网络

# 创建bridge网络(默认)
docker network create my-network

# 指定子网
docker network create \
  --subnet=172.18.0.0/16 \
  my-network

# 指定网关
docker network create \
  --subnet=172.18.0.0/16 \
  --gateway=172.18.0.1 \
  my-network

# 指定驱动
docker network create \
  --driver bridge \
  my-network

查看网络

# 列出所有网络
docker network ls

# 查看网络详情
docker network inspect my-network

输出:

[
    {
        "Name": "my-network",
        "Driver": "bridge",
        "Scope": "local",
        "IPAM": {
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Containers": {}
    }
]

使用网络

# 创建时指定网络
docker run -d --network my-network --name web nginx

# 运行中的容器连接到网络
docker network connect my-network web

# 断开网络
docker network disconnect my-network web

删除网络

# 删除网络
docker network rm my-network

# 清理未使用的网络
docker network prune

🎯 实战案例

案例1:Web + Database

传统方式(不好):

# 运行MySQL
docker run -d \
  --name db \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -p 3306:3306 \
  mysql:8.0

# 运行Web应用(连接宿主机的3306端口)
docker run -d \
  --name web \
  -e DB_HOST=宿主机IP \
  -e DB_PORT=3306 \
  -p 8080:8080 \
  my-web-app

问题:

  • 需要暴露MySQL端口(不安全)
  • 需要知道宿主机IP
  • 配置复杂

Docker网络方式(好!):

# 创建网络
docker network create app-network

# 运行MySQL(不需要-p)
docker run -d \
  --name db \
  --network app-network \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0

# 运行Web应用(直接用容器名连接)
docker run -d \
  --name web \
  --network app-network \
  -e DB_HOST=db \
  -e DB_PORT=3306 \
  -p 8080:8080 \
  my-web-app

优点:

  • MySQL不暴露端口(安全)
  • 用容器名通信(简单)
  • 完全隔离(网络层面)

案例2:微服务架构

# 创建网络
docker network create microservices

# 服务1:用户服务
docker run -d \
  --name user-service \
  --network microservices \
  my-user-service

# 服务2:订单服务
docker run -d \
  --name order-service \
  --network microservices \
  my-order-service

# 服务3:API网关(对外暴露)
docker run -d \
  --name api-gateway \
  --network microservices \
  -p 80:80 \
  my-api-gateway

服务之间通信:

// order-service访问user-service
fetch('http://user-service:3000/api/users')

// 用容器名就行,DNS自动解析!

案例3:多网络隔离

# 创建前端网络
docker network create frontend

# 创建后端网络
docker network create backend

# 数据库(只在后端网络)
docker run -d \
  --name db \
  --network backend \
  mysql

# API服务(连接两个网络)
docker run -d \
  --name api \
  --network backend \
  my-api
docker network connect frontend api

# Web服务(只在前端网络)
docker run -d \
  --name web \
  --network frontend \
  -p 80:80 \
  nginx

结果:

  • web可以访问api ✅
  • web不能访问db ❌(安全)
  • api可以访问db ✅

🔍 容器DNS

自动DNS解析

在自定义网络中,容器可以通过容器名互相访问:

# 创建网络
docker network create my-net

# 运行容器1
docker run -d --name web --network my-net nginx

# 运行容器2,ping容器1
docker run --rm --network my-net alpine ping web

# ✅ 成功!容器名自动解析为IP

DNS配置

# 自定义DNS服务器
docker run -d \
  --dns 8.8.8.8 \
  --dns 114.114.114.114 \
  nginx

# 自定义hosts
docker run -d \
  --add-host myhost:192.168.1.100 \
  nginx

🎨 网络调试技巧

1. 查看容器IP

# 方法1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

# 方法2
docker inspect web | grep IPAddress

2. 测试容器连接

# 从容器1 ping 容器2
docker exec web ping db

# 测试端口连通性
docker exec web nc -zv db 3306

# 使用curl测试HTTP
docker exec web curl http://db:3000

3. 查看网络中的所有容器

docker network inspect my-network | grep -A 5 Containers

4. 抓包调试

# 在容器内抓包
docker run --rm --net container:web nicolaka/netshoot tcpdump -i any

🚀 网络性能优化

1. 使用host网络(性能最好)

# 适合对性能要求极高的场景
docker run -d --network host nginx

缺点:

  • 失去隔离性
  • 端口冲突风险

2. 自定义MTU

docker network create \
  --opt com.docker.network.driver.mtu=1450 \
  my-network

3. 使用overlay网络(多主机)

# 需要Docker Swarm
docker network create \
  --driver overlay \
  --attachable \
  my-overlay-network

💡 网络安全最佳实践

1. 最小暴露原则

# ❌ 不好(暴露所有端口)
docker run -p 3306:3306 mysql

# ✅ 好(不暴露,只在内网访问)
docker run --network my-network mysql

2. 网络隔离

# 前端和后端分开网络
docker network create frontend
docker network create backend

# 数据库只在后端网络
docker run --network backend mysql

3. 使用防火墙规则

# 限制IP访问
iptables -A DOCKER-USER -i eth0 ! -s 192.168.1.0/24 -j DROP

📊 常用命令速查

# 网络管理
docker network create <name>       # 创建网络
docker network ls                  # 列出网络
docker network inspect <name>      # 查看详情
docker network rm <name>           # 删除网络
docker network prune               # 清理未使用的网络

# 容器连接网络
docker network connect <network> <container>     # 连接
docker network disconnect <network> <container>  # 断开

# 创建容器时指定网络
docker run --network <name>        # 指定网络
docker run --network host          # 主机网络
docker run --network none          # 无网络

# 查看容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container>

# 测试连接
docker exec <container> ping <target>
docker exec <container> curl <url>

💡 小结

今天长安教你玩转Docker网络:

核心概念

  1. 网络类型:bridge、host、none、自定义
  2. 推荐用法:生产环境用自定义网络
  3. 容器通信:通过容器名(DNS自动解析)
  4. 安全原则:最小暴露、网络隔离

常用命令

docker network create     # 创建网络
docker network ls         # 列出网络
docker network inspect    # 查看详情
docker network connect    # 连接容器到网络
docker run --network      # 指定网络

最佳实践

  1. 使用自定义网络
  2. 不要随便暴露端口
  3. 服务通过容器名通信
  4. 敏感服务隔离网络
  5. 定期清理未使用的网络

🚀 下一步

基础知识都学完了!下一章长安带你进阶,学习 Docker Compose,一键管理多个容器!


💬 长安的网络踩坑记:

刚开始用Docker的时候,我所有容器都用默认网络。

结果容器之间通信要用IP,IP还总变,配置文件改到吐血😂

后来发现自定义网络可以用容器名通信,爽翻了!

还有一次,我把MySQL端口暴露到公网,结果被扫描器攻击了...

教训:

  1. 用自定义网络,通过容器名通信
  2. 不需要外网访问的服务,不要暴露端口!

网络搞明白了,Docker就掌握一大半了!💪

在 GitHub 上编辑此页
Prev
数据卷(Volumes)