デーモンレスでコンテナをビルドする
従来のDockerデーモンは強い権限を持っており、コンテナ上で動作させるとホストマシンのデーモンを介して脆弱になるという課題があった。
この課題に対して「デーモンレス」と「ルートレス」という2つのアプローチが取られていた。
その成果として「ルートレス」なビルダーとしてDockerデーモンやBuildah、img等がある。
他にもデーモンレスなビルダーとして代表的なものが「Kaniko」である。
本記事では「Kaniko」を使ったコンテナイメージのビルドを試してみる。
Kanikoとは?
githubから抜粋
kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster.
kaniko doesn't depend on a Docker daemon and executes each command within a Dockerfile completely in userspace. This enables building container images in environments that can't easily or securely run a Docker daemon, such as a standard Kubernetes cluster.
Google謹製のk8s上でDockerfileからDockerDaemonを使わずにコンテナをビルドするためのツール、とのこと。
公式Github
Kanikoの動作イメージ
Kanikoは公式イメージをそのまま使用してビルドすることを推奨しているため、コンテキストの渡し方を考える必要がある。
コンテキストの渡し方には以下の図のように色々ある。
手動で docker run
するくらいならLocalDirectory方式で良いが、そうするとKanikoを使うメリットも享受できない。
コンテキストをtar.gzに固めてBinaryタイプのConfigMapでKanikoに渡してやるのがクレデンシャルも不要で一番スマートなように思う。
push先への認証
pushする際は credential-helper でコンテナレジストリに認証を行うようになっている。
単純に/kaniko
がHOMEディレクトリになるので、ここにdocker login
した時にできる$HOME/.docker/config.json
ファイルをマウント(/kaniko/.docker/config.json)すれば認証することができる。
ACRへの認証
ACRへの認証の場合は2つオプションがあるが、ドキュメントによるとそのうちcredHelpers
方式が推奨されている。
この場合、以下のようにPodを設定する。
- { “credHelpers”: {“mycr.azurecr.io”: “acr”} } を
/kaniko/.docker/config.json
に記載する。 - Podの環境変数にSP認証情報として
AZURE_CLIENT_ID
,AZURE_CLIENT_SECRET
,AZURE_TENANT_ID
の3つを設定する。
あるいはaz acr login -n <ACR名> --expose-token
コマンドで認証トークン(もといパスワード)を取得できる。パスワードと対になるユーザー名は00000000-0000-0000-0000-000000000000
と決まっているのでこれでdocker loginして.docker/config.json
を取得する形でも認証できる。
CI環境からの実行
AKS上でCI環境を実行している場合、CI環境のServiceAccountにPod作成の権限をつけておくことでkanikoをCIの中で起動できる。
ビルドが終わったらすぐにPodやSecret等のビルド資材を消すようにすればそこそこセキュアな環境になりそう。
出来上がったコンテナイメージの操作
regctl
というツールが便利だった。※
ダウンロードしてきたバイナリにパスを通すだけで使える。
PrivateDockerRegistryのイメージを削除したり、別のレジストリにコピーしたりできる。
似たようなツールでskopeo
というRedhat製のツールがあるが、こちらはシングルバイナリでないのでインストールしづらかった・・・。
もしもレジストリの認証情報をkanikoにわたすのが面倒な場合、
private-registryにregctlにコピーしてきて、
ビルド成果物をregctlでPushするのが楽かもしれない。