buildahは、kubernetesなどのコンテナイメージをビルドするツールで、Dockerとは独立した実装です。
Debian系ディストリビューションには同名のパッケージがあり、apt install
でセットアップできます。
CLIはdocker
を踏襲しており、次のように実行します。
$ cat Dockerfile | buildah build -f - \
[--platform linux/arm64/v8] \
-t <image-tag-name> .
--platform
オプションはホストと異なるアーキテクチャのコンテナイメージをビルドする際のオプションです。
クロスコンパイルには、qemu-user-binfmt
パッケージが追加で必要になります。
レジストリへのpush
イメージタグをレジストリアドレスつきのFQDNに指定したうえで、buildah push <image-tag-with-FQDN>
コマンドでpushできます。
当然ながらレジストリごとの認証をあらかじめセットアップしておく必要はあります。
コンテナでイメージビルド
buildahのコンテナイメージを用いてコンテナ内でビルドすることは一応可能です。
ただし、privileged
権限を必要とするため、ホスト上なら一般ユーザーでビルドできるにも関わらず、コンテナで実行するとroot権限を取得してしまうため、セキュリティ面のメリットはありません。
Tektonのstep
記述例の抜粋は次のとおりです。
steps:
- name: buildah-build
image: quay.io/buildah/stable:latest
securityContext:
privileged: true
script: |
#!/bin/bash -eu
cat Dockerfile | buildah build \
-t $(params.registry)/$(params.image):$(params.version) \
-f - --platform linux/arm64/v8 .
buildah push $(params.registry)/$(params.image):$(params.version)
volumeMounts:
#NOTE: for Multi stage build
- name: artifact
mountPath: /var/lib/containers/storage
volumes:
- name: artifact
emptyDir: {}
fuseをコンテナ内で動作させるための権限供給
現状、kubernetesのコンテナ内でfuseを動作させる手軽な方法がありません。
結論として動作しない設定例ですが、kernelのcapabilityとAppArmorに限れば、次の方法で設定は可能です。
steps:
- name: buildah-build
image: quay.io/buildah/stable:latest
securityContext:
#privileged: true
capabilities:
add:
- "SYS_ADMIN"
appArmorProfile:
type: Unconfined
volumeMounts:
- name: device-fuse
mountPath: /dev/fuse
readOnly: false
volumes:
- name: device-fuse
hostPath:
path: /dev/fuse
type: CharDevice
AppArmorは、本来はホスト上のプロファイルを参照するオプションを指定するのが適切です。
この例ではそもそも動作しないので、AppArmorがネックにならないようunconfined
を指定しています。
/dev/fuse
のファイルアクセスが可能か否かはmanifestでは制御できず、クラスタの設定に依存します。
このようにcapability, AppArmor, ファイルアクセスを許可しても/dev/fuseをマウントできず、おそらくSeccompの権限を獲得できていません。
Seccompもmanifestで設定できないため、クラスタ全体の挙動を変えることになってしまいます。
コンテナのkernel権限は、セキュアに設定しようと思っても現状その方法がないケースがあります。