在单台 Linux 服务器上部署 Docker,核心目标是在保证稳定性、安全性、可维护性的前提下,最大化资源利用率。以下是经过生产环境验证的最佳实践,涵盖系统层、Docker 配置层及运维策略。
一、操作系统与内核优化(基础层)
Docker 的底层依赖 Linux 内核特性(如 cgroups, namespaces),因此系统层面的调优至关重要。
-
内核版本选择
- 建议使用较新的 LTS 内核(如 Ubuntu 20.04/22.04 自带内核或 CentOS Stream/Rocky Linux 8+)。旧版内核可能缺乏对最新容器特性的支持(如 cgroup v2)。
- 注意:避免随意升级内核到非稳定版,除非有明确需求且经过充分测试。
-
文件系统挂载
- Swap 设置:Docker 官方建议关闭 Swap(
swapoff -a)。因为 Docker 的内存管理基于 cgroup,开启 Swap 可能导致 OOM Killer 行为不可预测,甚至引发性能抖动。若必须保留 Swap,需确保vm.swappiness极低(如 1)。 - 文件系统类型:推荐使用
XFS或ext4。避免使用网络文件系统(NFS)作为 Docker 数据目录,I/O 延迟和元数据锁竞争会严重拖慢容器启动和日志写入。
- Swap 设置:Docker 官方建议关闭 Swap(
-
资源限制
- 在
/etc/sysctl.conf中调整关键参数:# 允许更多文件句柄 fs.inotify.max_user_watches = 524288 fs.file-max = 65535 # 优化 TCP 连接 net.ipv4.tcp_max_syn_backlog = 2048 net.core.somaxconn = 2048
- 在
二、Docker 守护进程配置(核心层)
不要直接修改 /etc/docker/daemon.json 中的默认值,应根据业务场景定制。
-
存储驱动选择
- 推荐:
overlay2。这是目前大多数发行版的默认选项,性能最好,兼容性强。 - 避坑:除非有特殊需求(如极致的快照功能),否则不要使用
aufs或devicemapper(后者在单盘模式下容易因空间碎片化导致性能下降)。 - 配置示例:
{ "storage-driver": "overlay2", "exec-opts": ["native.cgroupdriver=cgroupfs"] } - 注:若服务器开启了 systemd,建议将
cgroupdriver设为systemd以保持一致性,防止 kubelet(如有后续扩展需求)报错。
- 推荐:
-
安全加固
- 无 Root 运行:虽然 Docker 守护进程通常需要 root,但应尽量避免容器内以 root 身份运行应用。在
Dockerfile中使用USER指令指定非特权用户。 - 只读根文件系统:对于无状态服务,尝试将容器根文件系统设为只读(
--read-only),仅挂载必要的临时目录(如/tmp,/var/run)。 - 能力裁剪:通过
--cap-drop=ALL移除所有权限,再按需添加特定能力(如--cap-add=NET_BIND_SERVICE),减少攻击面。 - Seccomp 与 AppArmor:启用默认的 Seccomp 配置文件,并根据需要配置 AppArmor/SELinux 策略。
- 无 Root 运行:虽然 Docker 守护进程通常需要 root,但应尽量避免容器内以 root 身份运行应用。在
-
日志驱动配置
- 默认风险:默认
json-file驱动如果不限制大小,极易撑爆磁盘。 - 最佳实践:强制设置日志轮转策略。
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } } - 进阶方案:对于高并发日志场景,可考虑接入
journald或对接 ELK/Loki 等集中式日志系统,避免本地磁盘 I/O 瓶颈。
- 默认风险:默认
三、镜像与资源管理(效率层)
-
镜像分层与清理
- 多阶段构建:在 CI/CD 流程中使用多阶段构建(Multi-stage builds),减小最终镜像体积,减少攻击面。
- 定期清理:单台服务器磁盘有限,必须建立定期清理机制。
# 删除未使用的容器、镜像、构建缓存 docker system prune -f --volumes # 每周定时任务(crontab)执行 - 标签管理:严禁在生产环境长期使用
latest标签。应使用具体的语义化版本号(如v1.2.3),确保可复现性。
-
资源配额(Cgroups)
- 即使单台服务器,也应为关键容器设置 CPU 和内存上限,防止某个异常容器耗尽整机资源(OOM)。
- CPU:使用
cpus参数(如--cpus="1.5")比传统的 CFS quota 更易理解。 - 内存:务必设置
--memory和--memory-swap。- 若设置
--memory=512m,建议同时设置--memory-swap=512m(即不启用 Swap 给该容器),避免容器在物理内存不足时触发系统级 OOM。
- 若设置
-
网络隔离
- 避免直接使用
host模式(除非是高性能网络探针等特殊场景),这会暴露宿主机端口。 - 优先使用
bridge网络,配合自定义子网,实现容器间隔离。 - 若涉及外部访问,建议在 Docker 前部署反向X_X(如 Nginx, Traefik)或使用云厂商的负载均衡器,而非直接映射大量端口。
- 避免直接使用
四、运维与监控(保障层)
-
健康检查(Healthcheck)
- 在
docker-compose.yml或run命令中定义HEALTHCHECK。这能让编排工具或监控脚本自动感知容器是否“假死”。 - 示例:
"healthcheck": { "test": ["CMD", "curl", "-f", "http://localhost/health"], "interval": 30s, "timeout": 10s, "retries": 3 }
- 在
-
监控指标
- 安装轻量级监控 agent(如 Node Exporter + Prometheus,或云厂商自带的监控插件)。
- 重点监控指标:
- Disk Inodes:单台机器常因大量小文件(如日志、临时文件)耗尽 Inode 导致无法写入。
- Container Memory Usage:区分
used和limit,防止内存泄漏。 - Network I/O:识别异常流量。
-
备份策略
- 数据卷(Volumes):Docker Volumes 是持久化数据的唯一可靠方式。必须制定定期备份策略(如
tar打包挂载目录),并异地存储。 - 配置备份:备份
daemon.json、docker-compose.yml及相关的网络配置脚本。
- 数据卷(Volumes):Docker Volumes 是持久化数据的唯一可靠方式。必须制定定期备份策略(如
五、国内云环境特别提示
如果你使用的是阿里云、腾讯云或华为云的 ECS/CVM:
- 安全组与防火墙:Docker 的端口映射(-p)依然受限于云控制台的安全组规则。务必在云控制台上放行必要端口,并在宿主机内部(firewalld/iptables)做二次校验。
- 云监控插件:各大云厂商通常提供 Agent(如云助手、云监控插件),建议安装以便获取更精准的底层硬件指标(磁盘 IO 等待时间、网络带宽限制等)。
- 快照与镜像:利用云厂商的“创建实例快照”功能来备份整个系统状态,而不仅仅是 Docker 数据卷。这在系统升级失败回滚时非常关键。
- 合规性:国内云环境对内容安全有严格要求。确保容器内运行的应用不涉及违规内容,且日志审计符合《网络安全法》要求(留存不少于 6 个月)。
总结
单台服务器的 Docker 部署,“少即是多”。不要过度复杂化,优先保证磁盘空间可控、内存限制明确、日志轮转有效。一旦这三点落实,90% 的生产故障都能被规避。定期执行 docker system df 查看资源占用,养成定期清理的习惯,是维持长期稳定的关键。
CLOUD云枢