找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1998

积分

0

好友

259

主题
发表于 3 小时前 | 查看: 6| 回复: 0

「Docker生产最佳实践」系列第②篇,聚焦存储驱动深度配置与网络架构规划。

很多人在安装完 Docker 后就直接投入使用,默认的存储驱动和网络配置完全没动。运行一段时间后,各种问题开始浮现:容器 IO 偶尔会异常飙升、磁盘空间莫名其妙被占满、不同服务的容器之间居然能互相 ping 通……其实,大多数这类问题都可以在最初部署时,通过合理的配置提前规避。

存储:overlay2 不是装上就完了

磁盘配额——防止单个容器把磁盘吃光

我曾遇到过一个案例:某个容器因故障疯狂写入日志,短短几小时就把宿主一块 500GB 的磁盘空间全部写满。仅仅依赖日志轮转工具限制单个日志文件的大小有时还不够,更稳妥的做法是在存储驱动层直接为每个容器设置磁盘配额。

前提条件:Docker 数据目录在 xfs 文件系统上

# 检查文件系统类型
df -Th /var/lib/docker
# 如果是 xfs,可以继续配置配额

启用 quota 的挂载方式:

需要在系统启动时自动挂载的配置文件中,为 Docker 的数据目录添加配额选项。

# /etc/fstab 中添加 pquota 挂载选项
/dev/sdb1  /var/lib/docker  xfs  defaults,pquota  0  0

daemon.json 中配置每个容器的磁盘上限:

这是全局配置,对所有新建的容器生效。

{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true",
"overlay2.size=10G"
  ]
}

配置后,每个容器的可写层最多只能使用 10GB 空间。这样一来,即使某个容器失控,其影响范围也被严格限制在自身,不会波及宿主或其他容器。

也可以针对单个容器设置:

在启动特定容器时,可以覆盖全局配置,为其指定独立的磁盘限额。

docker run --storage-opt size=5G nginx

定期清理——自动化,别靠记忆

Docker 的磁盘空间问题通常有两个来源:一是运行中容器不断产生的日志和应用数据;二是随着时间积累下来的“垃圾”,比如已停止的容器、悬空的镜像、未被使用的数据卷。

依赖手动清理不仅效率低下,而且容易遗忘。最佳实践是编写一个自动化清理脚本,并交给 crontab 定时执行。

#!/bin/bash
# /usr/local/bin/docker-cleanup.sh

# 清理3天前停止的容器
docker container prune -f --filter "until=72h"

# 清理7天前未使用的镜像
docker image prune -a -f --filter "until=168h"

# 清理7天前未使用的卷(小心,确认数据无用再启用此条)
docker volume prune -f --filter "until=168h"

# 清理构建缓存
docker builder prune -a -f --filter "until=168h"

echo "[$(date)] Docker cleanup done" >> /var/log/docker-cleanup.log
# 将脚本添加到 crontab,设定每天凌晨3点执行
0 3 * * * /usr/local/bin/docker-cleanup.sh

快速查看 Docker 当前占用多少磁盘:

docker system df
# 输出中的 RECLAIMABLE 列,就是可以安全回收的空间大小

网络:别全扔在默认 bridge 上

为什么默认网络不适合生产?

Docker 自带的 bridge 网络(名为 bridge 的默认网络)在生产环境存在两个明显的硬伤:

  1. 容器间通信只能使用 IP 地址,而 IP 是动态分配的,容器一旦重启就可能发生变化。
  2. 没有内置 DNS 服务,容器之间无法通过容器名称进行解析。

因此,生产环境强烈推荐使用 自定义 bridge 网络,它不仅能解决上述问题,还能实现容器组间的网络隔离,这是做好 运维 和安全的基础。

我的网络分层方案

一个清晰的生产架构通常会按功能进行网络分层。这里分享一个典型的三层网络划分方案:

# 前端网络(用于 Nginx 等接入层服务)
docker network create \
  --driver bridge \
  --subnet 172.80.1.0/24 \
  --gateway 172.80.1.1 \
  --opt com.docker.network.bridge.name=docker-frontend \
  frontend-net

# 后端网络(用于应用服务内部通信)
docker network create \
  --driver bridge \
  --subnet 172.80.2.0/24 \
  --gateway 172.80.2.1 \
  --opt com.docker.network.bridge.name=docker-backend \
  backend-net

# 数据库网络(内部隔离,禁止访问外网)
docker network create \
  --driver bridge \
  --subnet 172.80.3.0/24 \
  --gateway 172.80.3.1 \
  --internal \
  database-net

其网络隔离和数据流向可以这样理解:

[外网流量]
    ↓
Nginx (连接至 frontend-net)
    ↓
应用服务 (同时连接 frontend-net 和 backend-net)
    ↓
MySQL (连接至 database-net, 且拥有 --internal 属性)

关键在于,标记为 --internaldatabase-net 完全禁止容器访问外部网络。这意味着即使数据库容器因漏洞被攻破,攻击者也无法直接从该容器发起对外网络请求,天然形成了一道安全屏障。这种精细化的 网络 规划是 云原生 应用安全的重要一环。

MTU 问题——大数据包丢失排查

典型现象: 容器内进行小请求测试一切正常,但传输大文件时就会出现问题,表现为连接超时或间歇性丢包。

这通常是MTU(最大传输单元)不匹配导致的。在使用了 VPN、或云服务商提供的 overlay 隧道网络的宿主机环境中尤其常见。

# 首先查看宿主机物理网卡的 MTU 值
ip link show eth0
# 输出中会显示类似 `mtu 1500` 的信息

# 如果宿主机存在VPN或隧道,有效MTU可能需要减去封装开销,例如变为1450
# 创建 Docker 网络时,明确指定适配的 MTU
docker network create \
  --driver bridge \
  --opt com.docker.network.driver.mtu=1450 \
  my-net

MTU 的选取原则通常是:比宿主机实际有效 MTU(考虑隧道开销后)稍小一些,比如小 50 字节,为各种协议封装预留空间。

端口规划——别让端口成为运维噩梦

当多个项目或服务运行在同一台宿主机上时,端口冲突会成为令运维人员头疼的问题。提前做好端口范围规划能有效避免混乱。

端口范围 用途 示例
8000-8099 Web应用 8080: Nginx, 8081: 前端服务
8100-8199 API服务 8100: API Gateway
8200-8299 中间件 8200: Redis, 8201: 消息队列
8300-8399 数据库 8300: MySQL, 8301: PostgreSQL
8400-8499 监控工具 8400: Prometheus, 8401: Grafana

更优的方案是:在生产环境中,容器一律不向宿主机暴露端口,统一通过 Nginx 或 API 网关进行反向代理。

# 容器启动时不使用 -p 参数暴露端口
docker run -d --name app --network backend-net myapp

# 由宿主机上的 Nginx 统一做反向代理和 SSL 终止
# 好处:端口管理集中,SSL证书只需配置一次,容器可以随时迁移或重启而不影响外部访问

本篇小结

  • 存储:采用 overlay2 驱动,在 XFS 文件系统上启用配额以限制单容器磁盘用量,并通过定时任务自动清理无用资源。
  • 网络:弃用默认 bridge 网络,按照前端、后端、数据库等逻辑层次创建自定义网络,在 VPN/隧道环境下务必注意 MTU 配置。
  • 端口:要么提前做好全局端口规划,更推荐的做法是让容器不直接暴露端口,统一经由反向代理对外提供服务。

这些配置在部署初期花费一些时间完成,却能帮你避开后续无数次的故障排查和“救火”工作。希望这篇来自实践的经验总结能对你有所帮助。

本文是「Docker生产最佳实践」系列第②篇。下一篇我们将探讨资源限制——CPU、内存、磁盘IO 该如何配置,才能避免一个失控的容器拖垮整台服务器。

如果你在配置过程中有其他心得或疑问,欢迎到技术社区交流探讨。




上一篇:从马可尼到6G:射频通信百年演进与在现代战争中的核心作用解析
下一篇:SAP与国产ERP的成本对象架构解耦:如何设计内部分摊与结算引擎
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-5 17:54 , Processed in 0.383629 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

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