今回はRed Hat 北山(OpenShiftのSA担当)がお届けします。
もうすぐKubeCon NAの季節ですね。ちなみに前夜祭(Oct 12th)にOpenShift Commons Gatheringが開催されますよっ!!
いつもアドベントカレンダーの季節くらいしかブログは書かないのですが、ちょうど Kubernetes Meetup Tokyo #45でLT の機会を頂いたので、その時間で触れられなかった内容を簡単にご紹介できればと思います。
今回は、まだあまり聞き慣れない Shipwright プロジェクトについてのご紹介です。
なお、まだ始まったばかりのプロジェクトなので、動向や紹介内容も温かい目で御覧くださいw
OpenShift Build v1
まずは、これまでのOpenShiftのビルド機構についておさらい。
OpenShift BuildConfigs
ところで皆さま、OpenShiftの BuildConfig って使用されていますか?
BuildConfig はOpenShiftにある、コンテナイメージの作成プロセスを自動化してくれる便利な独自機能の一つです。たとえば、Gitリポジトリ上のソースコード更新を契機に、Jenkinsパイプラインを動作させるといったビルドも、OpenShiftではこの BuildConfig を設定します。
独自機能と言いましたが、実体は BuildConfig というカスタムリソースです。
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
name: "ruby-sample-build"
spec:
runPolicy: "Serial"
triggers:
- type: "GitHub"
github:
secret: "secret101"
- type: "ImageChange"
source:
git:
uri: "https://github.com/openshift/ruby-hello-world"
strategy:
sourceStrategy:
from:
kind: "ImageStreamTag"
name: "ruby-20-centos7:latest"
output:
to:
kind: "ImageStreamTag"
name: "origin-ruby-sample:latest"
ここで重要なフィールドは、以下の3つ。
sourceフィールド : ビルドリソースに応じて、コードのGitリポジトリ、Dockerfile、またはバイナリのペイロードの場所を指定strategyフィールド : ビルドの実行に使用するビルド戦略(Docker Build, s2i Build, Custom Build, Pipeline Build)を記述outputフィールド : ビルドされたコンテナイメージをプッシュするレジストリを指定
これらを使用することで、コンテナビルドにおける作業の簡略化を行っています。
BuildConfig はOpenShift v3の頃からあるリソースであり、クラウドネイティブ黎明期にはKubernetes上でコンテナをどのようにビルドするのかという観点で、先陣を切るビルド機構でした。
BuildConfigの課題
しかし、Kubernetesが普及してきたと同時に、ビルドに関する機構も多様化したことから、OpenShiftのBuildConfigだけでは標準化としての課題がいくつかでてきました。
BuildConfig自体がOpenShift独自の機能(リソース)になってしまっている。(他のKubernetesとの親和性が薄い)BuildConfigのstrategyフィールドで利用できるビルド方式が固定される。BuildConfigに(Jenkinsの呼び出しや事後処理など)複数の機能/役割をもたせてしまっている。
これらを払拭すべく、OpenShiftでは次世代のクラウドネイティブなBuild機構 (OpenShift Builds v2) の導入検討が始まっています。

この候補に挙げられているのが、 Shipwright です。
Shipwrightの概要

ShipwrightとはKubernetes上でコンテナイメージをビルドするための拡張可能なフレームワークです。
開発者に、コンテナツールの予備知識を必要とせず、最小限のYAMLを定義することでコンテナイメージを構築するためのアプローチを提供しています。
このYAMLを定義することによって、ビルドツールに依存せずに同じ書式(YAML形式)で好きなビルドツール利用してコンテナイメージをつくることができます。

すでにThe Continuous Delivery Foundation(CDF)のInqubationプロジェクトとして登録されています。
Shipwightのアーキテクチャ
Shipwrightは、Kubernetes Operator パターンで提供されており、カスタムリソースとカスタムコントローラーからできています。ただし、BuildConfig のようにOpenShift独自のコントローラーではなく、どのKubernetes上にも展開できるOperatorとして提供されています。
OperatorHub.ioへの登録も始まっています。
OperatorHub.io | The registry for Kubernetes Operators
Shipwrightが管理するカスタムリソースは、主に以下の4つ。(2021/09時点)
Buildリソース: ビルド戦略、ビルド対象のソース(Gitリポジトリ)、ビルド後のイメージ出力先(コンテナレジストリ)を指定BuildRunリソース: イメージのビルドを実行する
(≒Tekton PipelinesのTaskRunを生成する)BuildStrategyリソース(ClusterBuildStrategyもある) : ビルドツールに応じた処理内容を抽象化する
(≒Tekton PipelinesのTaskのStepを定義する)

Shipwrightは、バックエンドでTekton PipelinesのTaskRunを利用することでビルド処理を行っています。
基本は Build オブジェクトにビルド定義を行い、BuildRun オブジェクトをつくるとTekton Pipelinesによってビルド処理が実行されます。この際にビルド機構( BuildStrategyオブジェクト )を予め登録しておくことで、使いたいビルド戦略(ビルドツール)を Build オブジェクト内に定義できます。
Shipwrightの導入
ということで、新しいツールは実装してみるのが一番理解が早いので触ってみましょう。手順としては以下の順番で行います。
- Tekton Pipelinesのインストール
- Tekton Pipelines CLIのインストール
- Shipwrightのインストール
1. Tekton Pipelinesのインストール
まずは、Shipwrightで利用するTekton Pipelinesを入れておきます。
OpenShiftにTekton Pipeliensをインストールする場合
$ oc new-project tekton-pipelines
$ oc adm policy add-scc-to-user anyuid -z tekton-pipelines-controller
$ oc adm policy add-scc-to-user anyuid -z tekton-pipelines-webhook
$ export TEKTON_PIPELINE_VERSION=v0.27.3
$ oc apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/${TEKTON_PIPELINE_VERSION}/release.notags.yaml
OperatorHubからのインストール1も可能です。
KubernetesにTekton Pipeliensをインストールする場合
$ kubectl create namespace tekton-pipelines
$ export TEKTON_PIPELINE_VERSION=v0.27.3
$ kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/${TEKTON_PIPELINE_VERSION}/release.yaml
2. Tekton Pipelines CLIのインストール
Tekton Pipelinesのオブジェクト管理は専用の tkn コマンドを使うと便利です。合わせてインストールしておきましょう。
$ export TEKTON_CLI_VERSION=v0.20.0
$ curl -LO https://github.com/tektoncd/cli/releases/download/${TEKTON_CLI_VERSION}/tkn_${TEKTON_CLI_VERSION#v}_Linux_x86_64.tar.gz
$ sudo tar xvzf tkn_${TEKTON_CLI_VERSION#v}_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
$ tkn version
Client version: 0.20.0
Pipeline version: v0.27.3
3. Shipwrightのインストール
ShipwrightのControllerは、shipwright-buildnamespacesにインストールされるため、あらかじめ設定しておきます。
$ kubectl create namespace shipwright-build ## OpenShiftの場合のみSCCの設定 $ oc adm policy add-scc-to-user anyuid -z shipwright-build-controller -n shipwright-build
次にShipwrightのCRDとControllerをインストール。
$ kubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.5.1/release.yaml
以上でShipwrightの設定は完了です。
Shipwrightの利用
いよいよShipwrightのオブジェクトを登録してビルドを開始しましょう。今回は sample-shipwright namespaceという名前空間でビルドを行います。なお、kubens2は事前に入れておいてくださいね。
$ kubectl create namespace sample-shipwright $ kubens sample-shipwright
OpenShift上で実装する場合は、SCCの設定から始めてください。
$ oc adm policy add-scc-to-user anyuid -z default -n sample-shipwright $ oc create serviceaccount pipeline -n sample-shipwright $ oc adm policy add-scc-to-user privileged -z pipeline -n sample-shipwright $ oc adm policy add-role-to-user edit -z pipeline -n sample-shipwright
Shipwrightの利用は、以下の手順で行います。
BuildStrategyオブジェクトの登録Buildオブジェクトの登録BuildRunオブジェクトの登録
a. BuildStrategyオブジェクトの登録
はじめにBuildStrategyオブジェクトを設定します。基本のBuildStrategyオブジェクトには以下のような種類があります。
BuildStrategyオブジェクトは各名前空間内に設定できますが、クラスター全体でビルド機構を再利用する場合はClusterBuildStrategyオブジェクトに設定します。 そして、今回はこのClusterBuildStrategyオブジェクトを登録します。
なお、基本のClusterBuildStrategyオブジェクトは、プロジェクトに用意 されており、一つ一つ登録せずとも1コマンドですべて登録が可能です。
$ kubectl apply -f https://github.com/shipwright-io/build/releases/download/nightly/default_strategies.yaml $ kubectl get cbs --show-kind=true NAME clusterbuildstrategy.shipwright.io/buildah clusterbuildstrategy.shipwright.io/buildkit clusterbuildstrategy.shipwright.io/buildpacks-v3 clusterbuildstrategy.shipwright.io/kaniko clusterbuildstrategy.shipwright.io/ko clusterbuildstrategy.shipwright.io/source-to-image
BuildStrategyオブジェクトの内容
ちなみに、このBuildStrategyオブジェクトの中身を見ると、Tekton PipelinesのTaskの内容ととても似ていることがわかります。つまり、各Step(buildStep)でTekton PipelinesのTaskRunを生成するための内容が定義されています。
apiVersion: shipwright.io/v1alpha1
kind: ClusterBuildStrategy
metadata:
name: kaniko
spec:
buildSteps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v1.6.0
workingDir: $(params.shp-source-root)
…
command:
- /kaniko/executor
args:
- --skip-tls-verify=true
- --dockerfile=$(build.dockerfile)
- --context=$(params.shp-source-context)
- --destination=$(params.shp-output-image)
- --oci-layout-path=/kaniko/oci-image-layout
- --snapshotMode=redo
- --push-retry=3
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 65Mi
b. Buildオブジェクトの登録
さて、つぎにBuildオブジェクトを登録しましょう。
認証情報の登録
あらかじめビルド時に使用するGitリポジトリやコンテナレジストリ用の認証情報が必要です。通常のPullSecret同様に認証情報をSecret形式で登録すればよいのですが、このSecretを確認するのは最終的にTekton Pipelinesです。したがって、Tekton Pipelinesで認識できる形でSecret登録しておくと認証が行われます。
ここではAccess Tokenを使ったBasic認証を行っています。
## GitLab.comの場合
$ export REPOSITORY_SERVER=gitlab.com
$ export REGISTRY_SERVER=registry.gitlab.com
$ export REGISTRY_REPO=<your registory repo name>
$ export REGISTRY_USER=<your registry name>
$ export REGISTRY_PASS=<your password>
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: gitlab-token
annotations:
tekton.dev/git-0: https://${REPOSITORY_SERVER}
tekton.dev/docker-0: https://${REGISTRY_SERVER}
build.shipwright.io/referenced.secret: "true"
type: kubernetes.io/basic-auth
stringData:
username: ${REGISTRY_USER}
password: ${REGISTRY_PASSWORD}
EOF
Buildオブジェクトの内容
Buildオブジェクトには以下の3つを定義します。
sourceフィールド: ビルド対象のソースコード、またはDockerfileが入ったGitリポジトリの指定strategyフィールド:ClusterBuildStrategyで登録したビルド機構の指定outputフィールド: ビルド後のコンテナイメージ格納先の指定
これらに先程登録した認証情報を関連付けます。
$ cat <<EOF | kubectl apply -f -
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: go-tutorial-kaniko
spec:
source:
url: https://github.com/shipwright-io/sample-go
contextDir: docker-build
strategy:
name: kaniko
kind: ClusterBuildStrategy
output:
image: ${REGISTRY_SERVER}/${REGISTRY_USER}/${REGISTRY_REPO}/go-tutorial
credentials:
name: gitlab-token
EOF
登録されているかを確認しておきましょう。ここでOpenShiftを利用している方は、APIの呼び出しに気をつけて下さい。OpenShiftにはもともとBuildConfig用のリソース(Build v1=builds.config.openshift.io)があるため、$ kubectl get buildsとしても出力されません。
$ kubectl get crd |grep builds builds.config.openshift.io 2021-09-23T06:36:15Z builds.shipwright.io 2021-09-23T08:15:09Z … $ kubectl get builds.shipwright.io go-tutorial-kaniko NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME go-tutorial-kaniko True Succeeded ClusterBuildStrategy kaniko 4d2h
c. BuildRunオブジェクトの登録
最後にBuildRunオブジェクトを登録し、ビルドを実行します。BuildRunオブジェクトでは、buildRefフィールドで先程登録したBuildオブジェクトを指定します。
$ cat <<EOF | kubectl create -f -
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
generateName: go-tutorial-kaniko-run-
spec:
buildRef:
name: go-tutorial-kaniko
EOF
これらを登録するとTekton TaskRunによるビルドが始まり、うまくいくとBuildオブジェクトで指定したコンテナレジストリにイメージが格納されます。
$ tkn taskrun list NAME STARTED DURATION STATUS go-tutorial-kaniko-run-w4ssd-z446p 13 seconds ago --- Running $ tkn taskrun logs -L … [build-and-push] INFO[0114] COPY --from=build /tmp/helloworld ./helloworld [build-and-push] INFO[0114] Taking snapshot of files... [build-and-push] INFO[0114] ENTRYPOINT [ "./helloworld" ] [build-and-push] INFO[0114] EXPOSE 8080 [build-and-push] INFO[0114] cmd: EXPOSE [build-and-push] INFO[0114] Adding exposed port: 8080/tcp [build-and-push] INFO[0114] Pushing image to registry.gitlab.com/<your registry name>/shipwright-tutorial/go-tutorial [build-and-push] INFO[0122] Pushed image to 1 destinations
ビルドが成功したら、自身のコンテナレジストリからも確認を行って見てください。

今回はKanikoを使ってBuildを行いましたが、BuildオブジェクトのClusterBuildStrategyを切り替えると、別の方式でビルドが可能です。
またTekton PipelinesのTaskRunの内容を見るとShipwrightの仕組みがよくわかります。BuildRunオブジェクトはTekton PipelinesのTaskオブジェクトは生成せずに、TaskRunのspec.taskSpecフィールドを使って、TaskRunオブジェクトを生成しています。
$ tkn task list No Tasks found ## TaskRunの名前を指定 $ kubectl get taskrun go-tutorial-kaniko-run-w4ssd-z446p -o yaml |less
つまり、このTaskRunの生成元がBuildStrategyオブジェクトということです。そのため、BuildStrategyオブジェクト自体をカスタマイズすると、いろんなビルドに対応することが可能です。
このあたりのカスタマイズは、参考資料のProject Shipwright In Depthも合わせて御覧ください。
まとめ
ということで、Shipwrightの導入についてご紹介しました。すこし興味をもっていただけたでしょうか?

今後のOpenShift Roadmapで紹介される OpenShift Builds v2 についても、楽しみにしておいてください!!
参考資料
- The future of Red Hat OpenShift builds
- Project Shipwright In Depth
- Project Shipwright
- Introduction to Shipwright
最後に宣伝
最後にとてもだいぢなお知らせをしておきます。ちなみに、ここが一番重要です。
Tekton / Argoを使ったCI/CDの新しい本が出るので、是非お買い求めください。
いじょ。またねー。