单台Linux服务器部署Docker的最佳实践有哪些?

在单台 Linux 服务器上部署 Docker,核心目标是在保证稳定性、安全性、可维护性的前提下,最大化资源利用率。以下是经过生产环境验证的最佳实践,涵盖系统层、Docker 配置层及运维策略。

一、操作系统与内核优化(基础层)

Docker 的底层依赖 Linux 内核特性(如 cgroups, namespaces),因此系统层面的调优至关重要。

  1. 内核版本选择

    • 建议使用较新的 LTS 内核(如 Ubuntu 20.04/22.04 自带内核或 CentOS Stream/Rocky Linux 8+)。旧版内核可能缺乏对最新容器特性的支持(如 cgroup v2)。
    • 注意:避免随意升级内核到非稳定版,除非有明确需求且经过充分测试。
  2. 文件系统挂载

    • Swap 设置:Docker 官方建议关闭 Swap(swapoff -a)。因为 Docker 的内存管理基于 cgroup,开启 Swap 可能导致 OOM Killer 行为不可预测,甚至引发性能抖动。若必须保留 Swap,需确保 vm.swappiness 极低(如 1)。
    • 文件系统类型:推荐使用 XFSext4。避免使用网络文件系统(NFS)作为 Docker 数据目录,I/O 延迟和元数据锁竞争会严重拖慢容器启动和日志写入。
  3. 资源限制

    • /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 中的默认值,应根据业务场景定制。

  1. 存储驱动选择

    • 推荐overlay2。这是目前大多数发行版的默认选项,性能最好,兼容性强。
    • 避坑:除非有特殊需求(如极致的快照功能),否则不要使用 aufsdevicemapper(后者在单盘模式下容易因空间碎片化导致性能下降)。
    • 配置示例
      {
        "storage-driver": "overlay2",
        "exec-opts": ["native.cgroupdriver=cgroupfs"]
      }
    • :若服务器开启了 systemd,建议将 cgroupdriver 设为 systemd 以保持一致性,防止 kubelet(如有后续扩展需求)报错。
  2. 安全加固

    • 无 Root 运行:虽然 Docker 守护进程通常需要 root,但应尽量避免容器内以 root 身份运行应用。在 Dockerfile 中使用 USER 指令指定非特权用户。
    • 只读根文件系统:对于无状态服务,尝试将容器根文件系统设为只读(--read-only),仅挂载必要的临时目录(如 /tmp, /var/run)。
    • 能力裁剪:通过 --cap-drop=ALL 移除所有权限,再按需添加特定能力(如 --cap-add=NET_BIND_SERVICE),减少攻击面。
    • Seccomp 与 AppArmor:启用默认的 Seccomp 配置文件,并根据需要配置 AppArmor/SELinux 策略。
  3. 日志驱动配置

    • 默认风险:默认 json-file 驱动如果不限制大小,极易撑爆磁盘。
    • 最佳实践:强制设置日志轮转策略。
      {
        "log-driver": "json-file",
        "log-opts": {
          "max-size": "100m",
          "max-file": "3"
        }
      }
    • 进阶方案:对于高并发日志场景,可考虑接入 journald 或对接 ELK/Loki 等集中式日志系统,避免本地磁盘 I/O 瓶颈。

三、镜像与资源管理(效率层)

  1. 镜像分层与清理

    • 多阶段构建:在 CI/CD 流程中使用多阶段构建(Multi-stage builds),减小最终镜像体积,减少攻击面。
    • 定期清理:单台服务器磁盘有限,必须建立定期清理机制。
      # 删除未使用的容器、镜像、构建缓存
      docker system prune -f --volumes
      # 每周定时任务(crontab)执行
    • 标签管理:严禁在生产环境长期使用 latest 标签。应使用具体的语义化版本号(如 v1.2.3),确保可复现性。
  2. 资源配额(Cgroups)

    • 即使单台服务器,也应为关键容器设置 CPU 和内存上限,防止某个异常容器耗尽整机资源(OOM)。
    • CPU:使用 cpus 参数(如 --cpus="1.5")比传统的 CFS quota 更易理解。
    • 内存:务必设置 --memory--memory-swap
      • 若设置 --memory=512m,建议同时设置 --memory-swap=512m(即不启用 Swap 给该容器),避免容器在物理内存不足时触发系统级 OOM。
  3. 网络隔离

    • 避免直接使用 host 模式(除非是高性能网络探针等特殊场景),这会暴露宿主机端口。
    • 优先使用 bridge 网络,配合自定义子网,实现容器间隔离。
    • 若涉及外部访问,建议在 Docker 前部署反向X_X(如 Nginx, Traefik)或使用云厂商的负载均衡器,而非直接映射大量端口。

四、运维与监控(保障层)

  1. 健康检查(Healthcheck)

    • docker-compose.ymlrun 命令中定义 HEALTHCHECK。这能让编排工具或监控脚本自动感知容器是否“假死”。
    • 示例:
      "healthcheck": {
        "test": ["CMD", "curl", "-f", "http://localhost/health"],
        "interval": 30s,
        "timeout": 10s,
        "retries": 3
      }
  2. 监控指标

    • 安装轻量级监控 agent(如 Node Exporter + Prometheus,或云厂商自带的监控插件)。
    • 重点监控指标:
      • Disk Inodes:单台机器常因大量小文件(如日志、临时文件)耗尽 Inode 导致无法写入。
      • Container Memory Usage:区分 usedlimit,防止内存泄漏。
      • Network I/O:识别异常流量。
  3. 备份策略

    • 数据卷(Volumes):Docker Volumes 是持久化数据的唯一可靠方式。必须制定定期备份策略(如 tar 打包挂载目录),并异地存储。
    • 配置备份:备份 daemon.jsondocker-compose.yml 及相关的网络配置脚本。

五、国内云环境特别提示

如果你使用的是阿里云、腾讯云或华为云的 ECS/CVM:

  1. 安全组与防火墙:Docker 的端口映射(-p)依然受限于云控制台的安全组规则。务必在云控制台上放行必要端口,并在宿主机内部(firewalld/iptables)做二次校验。
  2. 云监控插件:各大云厂商通常提供 Agent(如云助手、云监控插件),建议安装以便获取更精准的底层硬件指标(磁盘 IO 等待时间、网络带宽限制等)。
  3. 快照与镜像:利用云厂商的“创建实例快照”功能来备份整个系统状态,而不仅仅是 Docker 数据卷。这在系统升级失败回滚时非常关键。
  4. 合规性:国内云环境对内容安全有严格要求。确保容器内运行的应用不涉及违规内容,且日志审计符合《网络安全法》要求(留存不少于 6 个月)。

总结

单台服务器的 Docker 部署,“少即是多”。不要过度复杂化,优先保证磁盘空间可控内存限制明确日志轮转有效。一旦这三点落实,90% 的生产故障都能被规避。定期执行 docker system df 查看资源占用,养成定期清理的习惯,是维持长期稳定的关键。

未经允许不得转载:CLOUD云枢 » 单台Linux服务器部署Docker的最佳实践有哪些?