You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Swarm更新时卷行为与磁盘占用过高问题咨询

Docker Swarm部署中「设备空间不足」问题排查与疑问

问题现象

在Docker Swarm集群通过CI/CD部署应用时,频繁触发「设备空间不足」错误,但所有镜像大小均小于500MB,服务器初始存储占用也不多。

排查操作

执行以下命令定位空间占用:

sudo du -a -h / | sort -n -r | head -n 5

输出结果:

5G   /var/lib/docker/overlay2/ec1a3324f4cb66327ff13907af28b101ab15d1a0a27a04f0adedf50017f1612e/merged/etc
6G   /var/lib/docker/overlay2/98f9e5f2c28a7ee7972cadfeaa069210238c06b5f806c2f5e039da9d57778817/merged/etc
2G   /var/lib/docker/overlay2/7fe5364228810e035090c86448b5327150f7372c9d2216b8ab4f8c626e679ba0/merged/etc
1G   /var/lib/docker/overlay2/5f80f0b1a72b83553c9089a54226c260b2e695dbba69b9e06ecc18fc18e3d107/merged/etc

发现/var/lib/docker/overlay2目录占用大量空间,随后执行清理命令:

docker system prune -a -f --volumes

核心疑问

  1. 怀疑部署新服务实例时,卷挂载切换到新容器后,旧容器仍向自身文件系统写入数据,导致overlay2目录膨胀。想明确Docker Swarm部署新镜像时,卷的实际行为:是否会断开旧节点的卷映射并连接到新容器,进而导致旧实例写入自身文件系统?
  2. 配置中myApp.deploy.update_config.order: start-first是否是问题诱因?
  3. 如何避免此类空间占用问题?

附deploy-stack.yml配置示例

version: "3.9"
services:
  myApp:
    image: myRepo/myApp:latest
    depends_on:
      - db
    volumes:
      - /var/data/uploads:/app/uploads
      - /var/data/logs:/app/logs
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        order: start-first
        failure_action: rollback
        monitor: 30s
      restart_policy:
        condition: any
    ports:
      - "80:80"
 
  db:
    image: "postgres:15beta3-alpine"
    container_name: db_pg
    environment:
      POSTGRES_PASSWORD: XXXXXXXXXXXX
      PGDATA: /var/lib/postgresql/data
    volumes:
      - /var/data/db_pg:/var/lib/postgresql/data
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        failure_action: rollback
        monitor: 30s
      restart_policy:
        condition: any
  seq:
    image: datalust/seq:latest
    environment:
      ACCEPT_EULA: "Y"
      SEQ_FIRSTRUN_ADMINPASSWORDHASH: XXXXXXXXXXXXXXX
    ports:
      - 8888:80
    volumes:
      - /var/data/seq:/data
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        failure_action: rollback
        monitor: 30s
      restart_policy:
        condition: any
networks:
  default:
    external: true
    name: app-network

问题解答

1. Docker Swarm更新时的卷行为

你使用的是绑定挂载(主机目录直接映射到容器),而非Docker管理的命名卷。这种场景下:

  • 新容器启动时会直接挂载主机上的/var/data/uploads、/var/data/logs等目录,和旧容器共享同一主机目录资源,不存在「断开旧映射连新容器」的情况——旧容器的挂载依然有效,新旧容器会同时读写同一个主机目录。
  • 只有当应用写入路径未正确指向挂载目录(比如代码写死向容器内/app/logs写入,但挂载配置失效),才会导致数据写入容器自身的overlay2层,进而撑大空间。

2. start-first是否是诱因

是的,start-first是关键诱因之一:

  • 默认更新顺序为stop-first:先停止旧容器,再启动新容器。而start-first会先启动新容器,等新容器健康后再停止旧容器。
  • 新旧容器共存期间,如果应用有大量写入操作(比如日志、临时文件)且部分写入未落到绑定挂载目录,会同时在两个容器的overlay2层产生数据,短时间内快速消耗磁盘空间。
  • 若旧容器停止后未被及时清理(比如Swarm垃圾回收延迟),残留的overlay2层数据会持续占用空间。

3. 避免空间问题的措施

  • 修正应用写入路径:确保所有持久化数据(日志、上传文件)的写入路径完全对应绑定挂载目录,禁止向容器内未挂载路径写入大量数据。
  • 调整更新顺序:若应用允许短时间停机,将update_config.order改回stop-first,避免新旧容器共存期间的双重写入。若必须用start-first,缩短monitor时间,确保旧容器能被快速停止清理。
  • 开启Docker自动垃圾回收:配置Docker的--storage-opt dm.min_free_space设置最低剩余空间阈值,或启用Swarm自动清理:
    docker swarm update --task-history-limit 1
    
    限制任务历史数量,旧容器会被更快清理。
  • 定期清理overlay2残留:在CI/CD流程中添加轻量清理步骤(避免prune -a误删有用镜像):
    docker system prune -f --filter "until=24h"
    
  • 监控磁盘占用:给服务器配置磁盘告警,当空间占用超过80%时触发通知,提前处理。

内容的提问来源于stack exchange,提问作者user3620691

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:03:18