はじめに
こんにちは、(株)日立製作所 研究開発グループ サービスコンピューティング研究部の露木です。
最近のKubernetesの隆盛により,Dockerコンテナの実行環境はとても充実しています。一方で,コンテナイメージのビルド環境はどうでしょうか。開発者が,手元のノートPCの限られた計算リソースをやりくりしながら docker build しているのはよくある話です。Kubernetesクラスタには潤沢な計算リソースがあるのですから,これを利用してビルド環境も効率化してしまいましょう。
目指す構成
このような背景から,本記事では
- moby/buildkit を既存のKubernetesクラスタにデプロイ
- 手元のノートPCで開発したDockerfileをKubernetes上でビルド
- 社内にあるDockerレジストリへ自動的にpushする
までの手順を公開します。この構成では KubernetesからDockerレジストリへコンテナイメージを送信するため,手元のノートPCの計算リソースは一切消費しません。
なお,buildkitと同様にKubernetesでDockerfileをビルドするシステムにはKanikoがあります。 buildkitはDockerに組み込まれている ため,今回はこちらを利用することにしました。
前提環境
さっそくですが,buildkitを使う手順を解説していきます。本記事では,以下の環境はすでにあるものとします。
-
buildkitのクライアント側 (手元のノートPC)
- Ubuntu 18.04
- Docker 19.03
- kubectlの利用設定済み
-
buildkitのサーバ側 (KubernetesのPod)
- Buildkit version 0.5.1
-
プライベートなDockerレジストリのサーバがある
準備
buildkitを使えるように環境を整えていきます。ます,buildkitのクライアント側 (手元のノートPC) に操作用のコマンド buildctl
をインストールします。
wget https://github.com/moby/buildkit/releases/download/v0.5.1/buildkit-v0.5.1.linux-amd64.tar.gz
tar xzf buildkit-v0.5.1.linux-amd64.tar.gz
rm -f buildkit-v0.5.1.linux-amd64.tar.gz
sudo mv ./bin/* /usr/local/bin/
buildctl --version
次に,buildkitのサーバ側のDockerイメージを作成します。ここ実行する処理はSSL証明書 myoriginal.crt
を組み込むのみです (社内のオンプレ環境にあるDockerレジストリを利用したいから)。特別な証明書が必要ない場合は,この手順は不要です。
buildkitのコンテナイメージについて,技術的な詳細は 公式ドキュメント を参考にしてください。
FROM moby/buildkit:latest
# 証明書を追加
RUN apk update \
&& apk add ca-certificates \
&& rm -rf /var/cache/apk/*
ADD myoriginal.crt /usr/share/ca-certificates/
RUN echo myoriginal.crt >> /etc/ca-certificates.conf
RUN update-ca-certificates
上記のDockerfileをビルドし,DockerレジストリへPushしておきます。<DockerレジストリのURL>
と <プロジェクト名>
の部分はご自身の環境に合わせて書き換えてください。
docker login <DockerレジストリのURL>
docker build -t <DockerレジストリのURL>/<プロジェクト名>/buildkit .
docker push
buildkitのサーバをKubernetesへデプロイするための deployment.yaml
を作成します。
なお,公式ドキュメントにあるyamlとの差分は,image名のみです。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: buildkitd
name: buildkitd
spec:
selector:
matchLabels:
app: buildkitd
template:
metadata:
labels:
app: buildkitd
spec:
containers:
- image: <DockerレジストリのURL>/<プロジェクト名>/buildkit
args:
- --addr
- tcp://0.0.0.0:1234
name: buildkitd
ports:
- containerPort: 1234
securityContext:
privileged: true
buildkitのサーバをKubernetesへデプロイします。
kubectl apply -f deployment.yaml
以上で準備は終了です。
使い方
デプロイしたbuildkitのpod名を調べます。
kubectl get pods
buildkitのpodに接続できるように,kubectl port-forward
でportを転送します。もし,tcp (httpではない) でKubernetesに直接接続できるネットワーク環境であれば,この手順は不要です。
kubectl port-forward pod/<buildkitのpod名> 1234:1234
環境変数でbuildctlコマンドがport転送先を参照するように指定します。
export BUILDKIT_HOST=tcp://127.0.0.1:1234
buildctlコマンドでコンテナイメージのbuildを実行します。
コマンドオプションがとても長いのでスクリプト化して利用しましょう。
buildctl build --output type=image,name=<Dockerレジストリ名>/<プロジェクト名>/<イメージ名>:<タグ>,push=true --frontend=dockerfile.v0 --local context=. --local dockerfile=<ビルドしたいDockerfileのパス>
なお,Dockerfile名まで指定したい場合は,こちらのようなコマンドになります: specify name of dockerfile · Issue #684 · moby/buildkit · GitHub 。また,ビルドしたコンテナイメージのpushに失敗することがあるので,buildの最後に ERROR exporting to image
というエラーが出たら再度実行してみてください。
まとめ
以上の手順が正しく動作していれば,Dockerレジストリに新しいコンテナイメージが登録されているはずです。本記事で解説したようにbuildkitを使えばコンテナイメージのビルドもKubernetesで実行し,潤沢な計算リソースを利用できる利点があります。
補足
今回は利用しませんでしたが, docker
コマンドからbuildKitを利用可能にするdocker/buildxプラグインがあります。将来的にはこちらを利用すれば ,buildctlは不要になると思います。buildkitの動作確認をしていた時期 (2019年7月) には,このプラグインではレジストリへの自動pushする機能 (--push
オプション) を実行できず,ローカルマシンのストレージ容量を消費するため利用しませんでした。また,調べきれていませんが,環境変数 BUILDKIT_HOST
に対応する設定が見当たらず,リモートのbuildkitdを指定する方法も2019年7月当時には不明でした。
もし,buildxプラグインを使ってみたい場合は,下記手順を参考にしてください。
まず,docker/buildxプラグインをインストールします。
export DOCKER_BUILDKIT=1
docker build --platform=local -o . https://github.com/docker/buildx.git
mkdir -p ~/.docker/cli-plugins/
mv buildx ~/.docker/cli-plugins/docker-buildx
動作確認します。
~ $ docker buildx --help
Usage: docker buildx COMMAND
Build with BuildKit
Management Commands:
imagetools Commands to work on images in registry
Commands:
bake Build from a file
build Start a build
create Create a new builder instance
inspect Inspect current builder instance
ls List builder instances
rm Remove a builder instance
stop Stop builder instance
use Set the current builder instance
version Show buildx version information
Run 'docker buildx COMMAND --help' for more information on a command.
docker build
を docker buildx build
に差し替えます。
docker buildx install
docker build
で docker buildx build
が実行されることを確認します。
$ docker build
"docker buildx build" requires exactly 1 argument.
なお,元に戻すときは docker buildx uninstall
を実行すればOKです。