Knative Buildのbuild templateにBazelをつかいビルドする
KnativeはKubernetesを基盤としたプラットフォームをビルド、デプロイを管理するためフレームワークを提供する。Serving、Build、そしてEventingの3つのコンポーネントで構成されている。これら3つが疎結合に連携する。
Kubernetesを基盤にサービスをデプロイするにはDeploymentやService、Ingressなどの理解が必要であるがKnativeはそれらを抽象化してよりフレームワークに沿った扱い方を提供してくれている印象がある。
モチベーション
今回のエントリでは3つのコンポーネントのうち Build
に注目していきたい。これまでBazelをつかいGoプロジェクトをビルドする方法をまとめてきた。KnativeのBuildにはbuild templateという概念がありテンプレートの1つにBazelがサポートされている。KnativeのBuildのbuild templateにBazelをつかいGoプロジェクトをビルドする手順をまとめる。
インストール
Kubernetes環境が整っていれば次のリソースをapplyすればKnative Buildの環境がセットアップできる。
istioのインストール
# Install istio $ kubectl apply --filename https://raw.githubusercontent.com/knative/serving/v0.2.2/third_party/istio-1.0.2/istio.yaml # Label the default namespace with istio-injection=enabled: $ kubectl label namespace default istio-injection=enabled
istio関連のPodがRunningかCompletedになれば完了
$ kubectl get pods --namespace istio-system --watch NAME READY STATUS RESTARTS AGE istio-citadel-84fb7985bf-shfdl 0/1 ContainerCreating 0 54s istio-cleanup-secrets-zg9n6 0/1 Completed 0 1m istio-egressgateway-bd9fb967d-z7gfr 0/1 ContainerCreating 0 54s istio-galley-655c4f9ccd-d9mgh 0/1 ContainerCreating 0 54s istio-ingressgateway-688865c5f7-2p5gk 0/1 ContainerCreating 0 54s istio-pilot-6cd69dc444-ts67c 0/2 ContainerCreating 0 54s istio-policy-6b9f4697d-d4ndh 0/2 ContainerCreating 0 54s istio-sidecar-injector-8975849b4-8x722 0/1 ContainerCreating 0 54s istio-statsd-prom-bridge-7f44bb5ddb-qwdqv 1/1 Running 0 55s istio-telemetry-6b5579595f-g2vm4 0/2 ContainerCreating 0 54s
参考: https://github.com/knative/docs/blob/master/install/Knative-with-any-k8s.md
Knative Buildのインストール
$ kubectl apply --filename https://raw.githubusercontent.com/knative/serving/v0.2.2/third_party/config/build/release.yaml
Build関連のPodがRunningになれば完了
kubectl get pods --namespace knative-build --watch NAME READY STATUS RESTARTS AGE build-controller-747b8fd966-dwbdd 0/1 ContainerCreating 0 16s build-webhook-6dc78d8f6d-vvkqm 0/1 ContainerCreating 0 16s
knative-build
のnamespaceが追加されている。以降に追加するリソースはknative-buildのnamespaceに追加していくのでcontextを切り替える。
Knative Buildを理解するための4つの要素
Knative Buildを理解するために次の4つの要素は抑えておきたい。
- Build
- BuildTemplate
- Builder
- ServiceAccount
Build
docs/builds.md at master · knative/docs · GitHub
BuildはBuildTemplate、Builder、ServiceAccountを集約した概念であり、それらをまとめたmanifestを作成する。
BuildTemplate
docs/build-templates.md at master · knative/docs · GitHub
BuildTemplateはparameter
とsteps
を定義する。stepはビルド手順をまとめビルドに必要な変数をparameterで定義する。テンプレートはBazelがサポートされている。今後もその他のサポートが追加されることが期待される。
GitHub - knative/build-templates: A library of build templates.
Builder
docs/builder-contract.md at master · knative/docs · GitHub
BuilderはBuildTemplateでも触れたsteps
の概念である。ビルドするために複数の手順があればstepsに追加していく。ビルドの完了までにBazelのtargerを複数実行したい場合はstepsにtargetを定義していく。
ServiceAccount
docs/auth.md at master · knative/docs · GitHub
ServiceAccountはKnative Buildにおける新概念ではなくビルドする過程で必要な認証をsecretリソースと一緒にセットアップすることでBuildリソースにアサインする。GitHubからソースのチェックアウトやリモートレジストリへのプッシュなどに必要な認証アカウントをServiceAccountリソースとして定義する。
Knative BuildでBazelをつかいビルドする
先述した4つの概念を頭に入れてBazelでビルドする方法をまとめていく。
ServiceAccountを作成する
BazelのtargetにはDocker hubにイメージをプッシュする工程が含まれているのでDocker hubに認証するSecretリソースを追加する。
# pkg/ops/k8s/knative-build/secret.yaml apiVersion: v1 kind: Secret metadata: name: docker-hub-account annotations: build.knative.dev/docker-0: https://index.docker.io/v1/ type: kubernetes.io/basic-auth stringData: username: "<username>" # not base64 encoded password: "<password>" # not base64 encoded
リソースを追加する。
(bazel-multiprojects) $ kubectl apply -f pkg/ops/k8s/knative-build/secret.yaml secret/docker-hub-account created
次にServiceAccountリソースを追加する。
# pkg/ops/k8s/knative-build/service-account.yaml apiVersion: v1 kind: ServiceAccount metadata: name: docker-hub-account secrets: - name: docker-hub-account
リソースを追加する。
(bazel-multiprojects) $ kubectl apply -f service-account.yaml serviceaccount/docker-hub-account created
これでDocker hubに認証するSecretリソースを参照しているdocker-hub-account
のServiceAccountが追加できた。
BuildTemplateリソースの追加
BuildTemplateリソースを追加する。
# pkg/ops/k8s/knative-build/build-template-bazel.yaml apiVersion: build.knative.dev/v1alpha1 kind: BuildTemplate metadata: name: bazel spec: parameters: - name: TARGET description: The name of the Bazel "container_push" target to run - name: IMAGE_TAG description: The tag of image steps: - name: build-and-push image: gcr.io/cloud-builders/bazel args: ['run', '--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64', '--define', 'IMAGE_TAG=${IMAGE_TAG}', '${TARGET}']
bazel run
コマンドのオプションを変数化して必要な変数をparameterとして定義している。
リソースを追加する。
(bazel-multiprojects) $ kubectl apply -f pkg/ops/k8s/knative-build/build-template-bazel.yaml buildtemplate.build.knative.dev/bazel created
これでBuildTemplateリソースのbazel
が追加できた。
Buildリソースの追加
Buildリソースを定義する。
# pkg/ops/k8s/knative-build/bazel-build.yaml apiVersion: build.knative.dev/v1alpha1 kind: Build metadata: name: bazel-build spec: serviceAccountName: docker-hub-account source: git: url: https://github.com/soushin/bazel-multiprojects revision: master template: name: bazel arguments: - name: TARGET value: //pkg/public_go:container_push - name: IMAGE_TAG value: latest
spec.serviceAccountName
に追加したServiceAccount docker-hub-account
を参照している。そしてspec.template.name
には追加したBuildTemplate bazel
を参照している。また//pkg/public_go:container_push
のBazel targetを実行するためのソースをspec.source
に定義している。
ビルドの実行
Buildリソースであるpkg/ops/k8s/knative-build/bazel-build.yaml
をapplyしてビルドを実行する。
(bazel-multiprojects) $ kubectl apply -f pkg/ops/k8s/knative-build/bazel-build.yaml build.build.knative.dev/bazel-build created
ポッドが起動しているのを確認する。
(bazel-multiprojects) $ kubectl get pods --namespace knative-build --watch NAME READY STATUS RESTARTS AGE bazel-build-9jzhc 0/1 Init:2/3 0 1m build-controller-747b8fd966-dwbdd 1/1 Running 0 1h build-webhook-6dc78d8f6d-vvkqm 1/1 Running 0 1h
Completedになればビルド完了。
(bazel-multiprojects) $ kubectl get pods --namespace knative-build --watch NAME READY STATUS RESTARTS AGE dbuild-controller-747b8fd966-dwbdd 1/1 Running 0 3h build-webhook-6dc78d8f6d-vvkqm 1/1 Running 0 3h bazel-build-9jzhc 0/1 Pending 0 0s bazel-build-9jzhc 0/1 Pending 0 0s bazel-build-9jzhc 0/1 Init:0/3 0 0s bazel-build-9jzhc 0/1 Init:1/3 0 1s bazel-build-9jzhc 0/1 Init:1/3 0 3s bazel-build-9jzhc 0/1 Init:2/3 0 4s bazel-build-9jzhc 0/1 Init:2/3 0 6s bazel-build-9jzhc 0/1 PodInitializing 0 5m bazel-build-9jzhc 0/1 Completed 0 5m
まとめ
- Knative Buildのbuild templateにBazelをつかいビルドする方法をまとめた
- ビルドを実行するとPodが立ち上がりPod内でビルドが行われる。BazelやDockerといったビルドに必要なコンポーネントのセットアップをせずにビルドできるのは便利である。
- ビルドが完了するとPodがCompletedになるが再度同じようにapplyを実行してもビルドが行われない。Podを削除した後にapplyを実行すると再度ビルドができた。
- もしかすると定義したBuildはEventingと結合して進化を発揮するのかしれない。EventigはGitHubのイベントをソースに扱える。マージのイベントでKnative Buildを実行するイメージである。
- Evenitngの理解がまだ浅いので引き続きEventingの理解も進めていく。
コード
紹介したyamlコードは次のレポジトリに置いてあります。