分类
devops

buildah-guide

Buildah 完全指南:无需 Docker Daemon 构建 OCI 镜像

什么是 Buildah

Buildah 是一个 OCI 镜像构建工具。与 Docker 最大区别:不需要 dockerd 守护进程。可以直接在用户空间构建镜像,原生支持 rootless。

Docker vs Buildah

Docker Buildah
需要 daemon 必须(dockerd) 不需要
rootless 需配置 原生支持
Dockerfile ✅ (bud 子命令)
多架构构建 buildx + QEMU --arch/--os + manifest
CI/CD 需 setup-buildx-action 一行 apt install
镜像存储 /var/lib/docker ~/.local/share/containers/storage

Ubuntu 安装

APT 安装(推荐)

sudo apt update
sudo apt install -y buildah

# 验证
buildah --version

安装最新版

. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" \
  | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list

curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" \
  | sudo apt-key add -

sudo apt update
sudo apt install -y buildah

QEMU 支持(跨架构构建)

# 安装 QEMU 用户态模拟
sudo apt install -y qemu-user-static

# 注册 binfmt
buildah info | grep -A5 'arch'

核心命令

构建容器(从零开始)

# 创建空容器
container=$(buildah from scratch)

# 或从基础镜像
buildah from alpine:latest

# 挂载容器文件系统
mnt=$(buildah mount $container)

# 写入文件
echo "hello" > $mnt/etc/motd

# 提交为镜像
buildah commit $container myimage:latest

构建镜像(Dockerfile)

buildah bud -t myapp:v1.0 .
# bud = build-using-dockerfile

支持标准 Dockerfile 指令:FROMRUNCOPYENVARGEXPOSECMDENTRYPOINT 等。

列出镜像

buildah images
buildah images --all

登录 Registry

buildah login docker.io -u <username> -p <password>
buildah login ghcr.io -u <username> --password-stdin

推送/拉取

# 推送
buildah push myapp:v1.0 docker://docker.io/myuser/myapp:v1.0

# 拉取
buildah pull docker.io/library/alpine:latest

多架构镜像

构建各架构

buildah bud --arch amd64 --os linux -t myapp:amd64 .
buildah bud --arch arm64 --os linux -t myapp:arm64 .

创建 Manifest List

buildah manifest create myapp:latest
buildah manifest add myapp:latest myapp:amd64
buildah manifest add myapp:latest myapp:arm64

推送多架构

# --all 推送 manifest list + 所有架构镜像
buildah manifest push --all myapp:latest docker://docker.io/myuser/myapp:latest

推送后,docker pull 会自动匹配客户端架构拉取对应镜像。

查看 Manifest

buildah manifest inspect myapp:latest
buildah manifest inspect docker.io/myuser/myapp:latest

GitHub Actions 集成

- name: Install buildah + qemu
  run: |
    sudo apt update
    sudo apt install -y buildah qemu-user-static

- name: Build multi-arch image
  run: |
    buildah login docker.io -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}

    buildah bud --arch amd64 -t app:amd64 .
    buildah bud --arch arm64 -t app:arm64 .

    buildah manifest create app:latest
    buildah manifest add app:latest app:amd64
    buildah manifest add app:latest app:arm64

    buildah manifest push --all app:latest docker://docker.io/${{ secrets.DOCKER_USERNAME }}/app:latest

Dockerfile 兼容性

标准 Dockerfile 完全兼容。不支持的特性:

特性 说明 替代方案
SHELL 指令 固定 /bin/sh RUN 中指定 shell
--mount=type=cache (BuildKit) 构建缓存挂载 COPY + RUN 分层
--mount=type=secret (BuildKit) 构建时注入密钥 COPY --chmod + RUN 后删除
--network=host 构建时网络模式 无直接替代

常用场景速查

# 从标准输入构建
echo 'FROM alpine\nRUN apk add curl' | buildah bud -t alpine-curl -

# 多阶段构建
buildah bud --target builder -t builder .
buildah bud -t final-image .

# 导出为 tar
buildah push myapp:latest docker-archive:/tmp/myapp.tar

# 本地 docker 跑
buildah push myapp:latest docker-daemon:myapp:latest
docker run myapp:latest

# 清理
buildah rm --all    # 删除所有容器
buildah rmi --all   # 删除所有镜像

总结

  • CI 场景:比 Docker setup-buildx-action 更轻量,一行 apt install
  • ROOTLESS:密钥/权限更安全
  • Dockerfile 兼容:绝大部分项目无需改动
  • 多架构--arch + manifest 两个步骤搞定