kaniko 能在无特权容器中安全执行 run 指令,关键在于其完全在用户空间模拟执行:解析 dockerfile 后,在内存中维护文件系统快照,以普通用户身份隔离运行命令,比对并打包文件差异为新镜像层,全程不依赖 docker 守护进程、不触碰特权内核接口、不挂载 docker.sock。

Kaniko 能在无特权容器里安全执行 RUN 指令,关键在于它不靠 Docker 守护进程、不依赖 root 权限,而是把整个构建过程“搬进用户空间”来完成。
RUN 指令在 Kaniko 中不是直接调用宿主机命令,而是被模拟执行的
Kaniko 的 executor 容器启动后,会按顺序解析 Dockerfile。遇到 RUN 时,它不会 fork 出新进程去调系统 sh -c,而是:
- 在内存中维护一个当前文件系统的状态快照(基于基础镜像解压后的 rootfs)
- 启动一个隔离的子进程(仍运行在容器普通用户上下文中),执行
RUN后面的命令(如apt-get update && apt install -y curl) - 命令结束后,扫描整个文件系统变化(通过文件路径 + 校验和比对),提取新增/修改/删除的文件
- 把这些差异打包成一个新的只读层(layer),追加到镜像层链中
这个过程全程不触碰 /proc、/sys 或其他需要特权的内核接口,也不挂载 docker.sock,更不需要 --privileged。
要确保 RUN 安全执行,注意这几点:
- ✅ 使用非 root 用户运行 Kaniko 容器(官方镜像默认以 UID 1001 运行)
- ✅ 避免
RUN中使用需要特权的操作,比如:-
modprobe、mount --bind、iptables - 写入
/etc/passwd或/etc/shadow(权限受限,会失败) - 直接操作设备节点(如
/dev/sda)
-
- ✅ 若需安装软件包,优先选
--no-install-recommends和精简基础镜像(如debian:slim),减少攻击面 - ✅ 多阶段构建中,
RUN只在对应 stage 的隔离环境中执行,上一阶段产物不会意外污染下一阶段
举个实际例子:
FROM alpine:3.19 RUN apk add --no-cache curl jq COPY entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh
Kaniko 会依次:
① 解压 alpine:3.19 的 tar 包到内存文件系统
② 执行 apk add ——该命令本身在 Alpine 容器内是普通用户可运行的
③ 记录 /usr/bin/curl、/usr/bin/jq 等新增文件,生成 layer
④ COPY 和第二个 RUN 同理,在同一文件系统上下文中继续变更
整个流程就像在一个沙盒里“重放”构建步骤,而不是在真实主机上执行。
本质上,Kaniko 把 RUN 从“操作系统级命令执行”降维成“文件系统状态迁移”,这才是它能在 Kubernetes Pod 里零特权跑通的根本原因。











