kanikoをAWS CodeBuildで使う

最近kanikoの話題を見るようになってきて,どういう動作をするのかなと気になり触ることにした.

普段はGCPではなくAWSの方を使っているのもあり,CodeBuildの方でもkanikoを使えないかと試してみたメモ.

動かすまでに試した記録と動作するサンプルリポジトリを以下に書いていく.

gcr.io/kaniko-project/executorはCodeBuildでは利用できない

まずハマったこととして,公式で提供されているイメージはCodeBuild上で動かすには様々な問題があり,利用することができない.

そのハマった点とその対処を順に書いていく.

CodeBuildではscratchイメージを動かすことができない

CodeBuildのベースイメージとしてgcr.io/kaniko-project/executorを指定すると.以下のようなエラーが出てしまい実行することができない.

SINGLE_BUILD_CONTAINER_DEAD: Build container found dead before completing the build. Build container died because it was out of memory, or the Docker image is not supported*1

いくつか実験してみると,これはexecutorのイメージがscratchベースであるためだということがわかり,おそらくCodeBuildの実行に必要なものが何か揃っていないと考えることができる.*2

kanikoにはgcr.io/kaniko-project/executor:debugというshellとbusyboxが追加で入ったイメージも用意されているが,こちらも同様にエラーになってしまい使うことができない.

alpineイメージは以前にCodeBuild上で動作することを確認していたため*3,今回も最終イメージをalpineに変更することで回避することができた.

CodeBuildで動かすためのPATHが不十分

利用するイメージをalpineに変更したところ,今度は以下のような別のエラーが発生した.

Internal Service Error: CodeBuild is experiencing issues

このエラーでGoogle検索しても1件しかヒットせず,しかもあまり参考にならないと思われる情報*4だったため,しばらくは解決方法がわからない状態だった.

そんな中,executorのDockerfileを見るとPATH/usr/local/bin:/kanikoしか書いていない*5という事に気づき,もしやと思って/bin/usr/binを追加したところ動作するようになった.

以上の対応を踏まえて,CodeBuildで動かすことのできるkanikoのalpineベースのイメージを作成した.

https://hub.docker.com/r/cohalz/kaniko-alpine

公式イメージの中身をそのまま持ってきているのもあり,公式イメージの代わりとしてCodeBuild以外でも使うことができる.

また,公式のdebugイメージと同様にshellやbusyboxも使えるようになるのでデバッグ時に便利である.

docker run -v $(pwd):/workspace -it --entrypoint="" cohalz/kaniko-alpine sh

実行コマンドをCodeBuildの形式に合わせる

GCPのCloud Buildでは実行したいコンテナとその引数を書いていく形式*6なのに対し,AWSのCodeBuild(や他のCIサービス)は実行環境がコンテナの内部になるほか,その環境で実行したいシェルスクリプトを書くという形式*7になっている.

そのため,CodeBuildで実行する際には,Cloud Buildで指定した引数の前にコマンド名である/kaniko/executorと,コンテナ内で実行するということで--forceオプションの2つを追加する必要がある.

つまり,CodeBuild上でビルドできるか確認するための最低限のbuildspec.ymlはこうなる.

version: 0.2

phases:
  build:
    commands:
      - /kaniko/executor --force --no-push"

CodeBuildからECRにpushできるようにする

上のを踏まえ,buildspec.ymlをこのように書くことでECRにpushできるようになる.

version: 0.2

phases:
  build:
    commands:
      - echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json
      - /kaniko/executor --force -d "${ECR_REPO}"

コマンドの一行目はECRへプッシュする際に必要で,kanikoではECRへプッシュする際には/kaniko/.docker/config.jsoncredsStoreもしくはcredHelpersにECRを使えるような変更が必要なための対応になる.*8

ECRの認証はCodeBuildのロールを使うため,そのロールにECRへpushする権限も必要.

CodeBuildの動作確認用のリポジトリ&CloudFormation

CodeBuildで動作するkanikoイメージを作ったので,動作確認がしやすいようにサンプルプロジェクトとCloudFormationテンプレートを作ってみた.

github.com

リポジトリにあるexample/using-kaniko-image/template.ymlファイルをデプロイすることで,このリポジトリにあるDockerfileをkanikoを使ってビルドしECRにpushするという動作を確認することができる.

実行するとこのようにCodeBuildのビルドログがkanikoの表示になっているのが確認できる.

f:id:cohalz:20190610003852p:plain
CodeBuildのコンソール画面

終わりに

動かすまでが意外と大変だったけど,終わってみると結構簡単に使えるようにできたので良かった.

CodeBuildはローカルやS3のキャッシュも使えるのでkanikoとの相性もいいと思う(権限もCodeBuildのロールで制御できる).

CodeBuildは元からBuildKitも利用できるので,kanikoとBuildKitのどちらを使うか適材適所で選んでいけると良いと思う.