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

基于Apache Airflow镜像构建时启动Docker服务失败的问题排查

Docker-in-Docker在Airflow镜像构建中的问题解析

场景与问题描述

基于Apache Airflow 2.5.1基础镜像制作Dockerfile,希望在Airflow容器内使用Docker(通过挂载宿主/var/run/docker.sock实现),docker-compose.yaml已配置挂载规则:/var/run/docker.sock:/var/run/docker.sock。

我的Dockerfile内容

FROM apache/airflow:2.5.1
USER root
RUN apt-get update && apt-get install -y ca-certificates curl gnupg lsb-release nano
RUN mkdir -p /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
RUN echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt-get update
RUN apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
RUN groupadd -f docker
RUN usermod -a -G docker airflow
RUN service docker start
USER airflow

构建错误信息

执行RUN service docker start时触发错误:

Step 11/12 : RUN service docker start
 ---> Running in 77e9b044bcea
mkdir: cannot create directory ‘cpuset’: Read-only file system

宿主Docker Socket权限

$ ls -la /var/run/docker.sock
srw-rw---- 1 root docker 0 Jan 18 17:14 /var/run/docker.sock

疑问

  1. 为何构建Airflow镜像时RUN service docker start命令失败?
  2. 为何相同命令在Jenkins Dockerfile中能正常运行?

注意:希望避免使用chmod 777 /var/run/docker.sock的解决方案。


问题解答

1. Airflow镜像构建时service docker start失败的原因

  • 构建阶段文件系统限制:Docker镜像构建过程中,RUN命令在只读文件系统层执行,而service docker start会尝试创建cgroup相关目录(如cpuset),这类写入操作在只读环境下不被允许,直接触发报错。
  • 需求误解:无需启动容器内Docker Daemon:你当前采用的是挂载宿主/var/run/docker.sock的复用模式(即Docker-out-of-Docker,DOOD),这种模式下容器只需安装Docker客户端(docker-ce-cli)即可调用宿主的Docker服务,完全不需要启动自身的Docker Daemon。安装docker-ce(包含Daemon)属于冗余操作,且构建阶段根本无法完成Daemon启动。

2. Jenkins镜像构建成功的原因

本质是假成功:

  • Jenkins基础镜像对应的系统版本中,service docker start命令可能仅输出警告但返回0(成功)的退出码,让你误以为服务启动成功,但实际上Docker Daemon并未真正运行——构建阶段的只读文件系统限制是通用的,任何镜像都无法在该阶段启动需要写入cgroup目录的系统服务。
  • 即使Jenkins镜像构建时该命令执行完成,启动的服务也不会被保留到最终镜像中,这个操作本身没有实际意义。

正确的Dockerfile修改方案

去掉启动Docker服务的命令,仅保留客户端安装和用户组配置:

FROM apache/airflow:2.5.1
USER root
RUN apt-get update && apt-get install -y ca-certificates curl gnupg lsb-release nano
RUN mkdir -p /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
RUN echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt-get update
# 仅安装Docker客户端即可,无需Daemon
RUN apt-get install -y docker-ce-cli docker-compose-plugin
RUN groupadd -f docker
RUN usermod -a -G docker airflow
USER airflow

修改后,容器运行时通过挂载的/var/run/docker.sock即可直接调用宿主的Docker命令,满足测试需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:25:24