Red Hat OpenShift on IBM CloudでのShipwright Buildオペレーターの利用

# はじめに
OpenShiftのロードマップに「Shipwright」が登場しました。

> 1H CY2022: APP/DEV Shipwright (TP) with local build」

https://speakerdeck.com/redhatlivestreaming/whats-next-in-red-hat-openshift-q4-cy2021

「Shipwright」は、以下の記事で次世代のBuild機構候補として挙げられていたものです。

https://rheb.hatenablog.com/entry/2021/09/28/%E3%80%8CShipwright%E3%80%8D%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%83%93%E3%83%AB%E3%83%89%E3%81%AE%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF

ローカルのDockerfileに対して、BuildConfig(oc new-build)を用意して、コンテナイメージを作成(oc start-build)することが多いのですが、この記事では「Red Hat OpenShift on IBM Cloud(バージョン4.8.18)」にShipwright Buildオペレーターを導入して、コンテナイメージを作成してみます。

# 1. オペレーターの導入
OpenShiftコンソールのOperatorHubからオペレーターを導入します。StarwrightはTektonのTaskRunとしてコンテナイメージを作成するため、「Red Hat OpenShift Pipelines」オペレーターを前提として導入しています。

■ Red Hat OpenShift Pipelinesオペレーター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/910ad45c-3b3d-80aa-67d3-74802a0087b8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/f3f12818-dc7f-72f8-5f1c-359c2aa441e8.png)
■ Shipwright Buildオペレーター
 ![ship1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/3d65f56c-fd57-eab5-ecfc-b56281875d31.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413476/8d7b081f-e678-19a6-f588-4dca963a47df.png)

# 2. コンテナイメージ作成資材準備
コンテナイメージ作成のための資材をGitHubに用意します。
`https://github.com/y-akio/container.git`

アプリケーション(spring-liberty-plain.war)については、こちらの[記事](https://qiita.com/y-akio/items/155ae44188a6df02138c)を参照ください。

```bash:資材
ls -l container/shipwright-test/
### 標準出力↓
合計 12840
-rw-r--r--. 1 root root      147 11月 30 22:48 Dockerfile
-rw-r--r--. 1 root root      737 11月 30 22:48 server.xml
-rw-r--r--. 1 root root 13139005 11月 30 22:48 spring-liberty-plain.war
```

```Dockerfile:Dockerfile
FROM docker.io/library/open-liberty:21.0.0.11-full-java11-openj9

COPY server.xml /config/
COPY spring-liberty-plain.war /config/apps/

EXPOSE 9080
```

```xml:server.xml
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
    <!-- Enable features -->
    <featureManager>
        <feature>jsp-2.3</feature>
    </featureManager>

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" />

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

    <webApplication contextRoot="/" location="spring-liberty-plain.war" />
</server>
```

# 3. Shipwrightによるコンテナイメージの作成
最初にコンテナイメージ作成処理をTektonのTaskRunとして実行できるように権限の設定を行います。

```bash
oc new-project spring-liberty
oc adm policy add-scc-to-user anyuid -z default -n spring-liberty
oc adm policy add-scc-to-user privileged -z pipeline -n spring-liberty
oc adm policy add-role-to-user edit -z pipeline -n spring-liberty
```

次に「BuildStrategy」と「Build」マニフェストを適用します。
buildahで作成したコンテナイメージをOpenShiftイメージレジストリに格納する内容になっています。
buildahではなくbuildpack等を利用したり、コンテナイメージの格納先をDocker Hubとすることも可能です。
※Docker Hubに格納する場合はSecretの追加が必要です。

```bash
oc apply -f build-strategy.yaml
oc apply -f build.yaml
```

```yaml:build-strategy.yaml
kind: BuildStrategy
metadata:
  name: buildah
spec:
  buildSteps:
    - name: buildah-bud
      image: quay.io/buildah/stable:latest
      workingDir: /workspace/source
      securityContext:
        privileged: true
      command:
        - /usr/bin/buildah
      args:
        - bud
        - --tag=$(build.output.image)
        - --file=$(build.dockerfile)
        - $(build.source.contextDir)
      volumeMounts:
        - name: buildah-images
          mountPath: /var/lib/containers/storage
    - name: buildah-push
      image: quay.io/buildah/stable:latest
      securityContext:
        privileged: true
      command:
        - /usr/bin/buildah
      args:
        - push
        - --tls-verify=false
        - $(build.output.image)
        - docker://$(build.output.image)
      volumeMounts:
        - name: buildah-images
          mountPath: /var/lib/containers/storage
```

```yaml:build.yaml
apiVersion: build.dev/v1alpha1
kind: Build
metadata:
  name: spring-liberty-build
spec:
  source:
    url: https://github.com/y-akio/container.git
    revision: main
    contextDir: shipwright-test
  strategy:
    name: buildah
    kind: BuildStrategy
  dockerfile: Dockerfile
  output:
    image: image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty
```

「BuildRun」マニフェストを適用することで、コンテナイメージが作成され、OpenShiftイメージレジストリへ格納されます。このとき、イメージストリームも作成されて、「Deployment」などからimageとして参照できる状態になります。

```bash
oc apply -f build-run.yaml

oc get pod -w
### 標準出力↓
NAME                                      READY   STATUS            RESTARTS   AGE
spring-liberty-buildrun-lpg8h-pod-47zl9   0/5     Init:0/2    0          2s
spring-liberty-buildrun-lpg8h-pod-47zl9   0/5     Init:1/2    0          2s
spring-liberty-buildrun-lpg8h-pod-47zl9   0/5     PodInitializing   0          3s
spring-liberty-buildrun-lpg8h-pod-47zl9   5/5     Running           0          20s
spring-liberty-buildrun-lpg8h-pod-47zl9   5/5     Running           0          20s
spring-liberty-buildrun-lpg8h-pod-47zl9   4/5     NotReady          0          22s
spring-liberty-buildrun-lpg8h-pod-47zl9   3/5     NotReady          0          25s
spring-liberty-buildrun-lpg8h-pod-47zl9   2/5     NotReady          0          52s
spring-liberty-buildrun-lpg8h-pod-47zl9   0/5     Completed         0          86s
spring-liberty-buildrun-lpg8h-pod-47zl9   0/5     Completed         0          87s

oc get pod spring-liberty-buildrun-lpg8h-pod-47zl9 -o jsonpath='{.spec.containers[*].name}'
### 標準出力↓
step-create-dir-image-4pk4j step-git-source-source-vgwvv step-buildah-bud step-buildah-push step-image-digest-exporter-sjbwg

oc get buildrun
### 標準出力↓
NAME                      SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
spring-liberty-buildrun   True        Succeeded   2m9s        42s

tkn taskrun list
### 標準出力↓
NAME                            STARTED          DURATION    STATUS
spring-liberty-buildrun-lpg8h   -9 minutes ago   1 minute    Succeeded

oc get is
### 標準出力↓
NAME             IMAGE REPOSITORY                                                                 TAGS     UPDATED
spring-liberty   image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty   latest   About a minute ago
```

```yaml:build-run.yaml
apiVersion: build.dev/v1alpha1
kind: BuildRun
metadata:
  name: spring-liberty-buildrun
spec:
  buildRef:
    name: spring-liberty-build
```

「BuildStrategy」のbuildSteps(buildah-bud、buildah-push)が、TaskRunの『STEP』に対応しています。

```bash
tkn taskrun logs spring-liberty-buildrun-lpg8h
### 標準出力↓
[git-source-source-vgwvv] {"level":"info","ts":1638578571.6257725,"caller":"git/git.go:169","msg":"Successfully cloned https://github.com/y-akio/container.git @ 42ce9d8bcbf7b4b42810515c6c87d222e71dffa0 (grafted, HEAD, origin/main) in path /workspace/source"}
[git-source-source-vgwvv] {"level":"info","ts":1638578571.6640522,"caller":"git/git.go:207","msg":"Successfully initialized and updated submodules in path /workspace/source"}

[buildah-bud] STEP 1/4: FROM docker.io/library/open-liberty:21.0.0.11-full-java11-openj9
[buildah-bud] Trying to pull docker.io/library/open-liberty:21.0.0.11-full-java11-openj9...
[buildah-bud] Getting image source signatures
[buildah-bud] Copying blob sha256:0e1b773c86017db4d8c567adab304d4ae1ebef26c81e239abc0fc717d9502ef7
[buildah-bud] Copying blob sha256:237daeb1ae282fe20092079ef6d5de7924746d0f2e9ad88797d08524a4d842fd
[buildah-bud] Copying blob sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54
[buildah-bud] Copying blob sha256:5ee473db920b121910771cc982528ead91b08134f8f3070d600d35ece5d65c4f
[buildah-bud] Copying blob sha256:ce36bf06e05233bcff80fd0e8b51da4ef18619fe44a2ad87ec70816590b9db66
[buildah-bud] Copying blob sha256:40bf402539426e4f2d82bd2e8e4e73bb90754d1a0756824a8cc43380a0d5287c
[buildah-bud] Copying blob sha256:237daeb1ae282fe20092079ef6d5de7924746d0f2e9ad88797d08524a4d842fd
[buildah-bud] Copying blob sha256:0e1b773c86017db4d8c567adab304d4ae1ebef26c81e239abc0fc717d9502ef7
[buildah-bud] Copying blob sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54
[buildah-bud] Copying blob sha256:ce36bf06e05233bcff80fd0e8b51da4ef18619fe44a2ad87ec70816590b9db66
[buildah-bud] Copying blob sha256:40bf402539426e4f2d82bd2e8e4e73bb90754d1a0756824a8cc43380a0d5287c
[buildah-bud] Copying blob sha256:25be17d35c1cf4379b449099501f9e27b5cd0eb8baade509da9349664b69e687
[buildah-bud] Copying blob sha256:8631fad2b4cc9b5b147371d571eca7610f21fb105d9bdda28a0332aaf6ba7eff
[buildah-bud] Copying blob sha256:4be3c2cbcb0fbb4e54bc854a0769b127bc3729c60a6d11239e35612da3dc9162
[buildah-bud] Copying blob sha256:5ee473db920b121910771cc982528ead91b08134f8f3070d600d35ece5d65c4f
[buildah-bud] Copying blob sha256:25be17d35c1cf4379b449099501f9e27b5cd0eb8baade509da9349664b69e687
[buildah-bud] Copying blob sha256:3bdda9346fc4c0b1709bca48547afda96804bc3cb22b36f0966ff98ac526cca8
[buildah-bud] Copying blob sha256:8631fad2b4cc9b5b147371d571eca7610f21fb105d9bdda28a0332aaf6ba7eff
[buildah-bud] Copying blob sha256:4be3c2cbcb0fbb4e54bc854a0769b127bc3729c60a6d11239e35612da3dc9162
[buildah-bud] Copying blob sha256:3bdda9346fc4c0b1709bca48547afda96804bc3cb22b36f0966ff98ac526cca8
[buildah-bud] Copying config sha256:37333a74cc7b4921a2eacedafb8a67f3b239c5be97d6bddffa66bb7ab30d54db
[buildah-bud] Writing manifest to image destination
[buildah-bud] Storing signatures
[buildah-bud] STEP 2/4: COPY server.xml /config/
[buildah-bud] STEP 3/4: COPY spring-liberty-plain.war /config/apps/
[buildah-bud] STEP 4/4: EXPOSE 9080
[buildah-bud] COMMIT image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty
[buildah-bud] Getting image source signatures
[buildah-bud] Copying blob sha256:9f54eef412758095c8079ac465d494a2872e02e90bf1fb5f12a1641c0d1bb78b
[buildah-bud] Copying blob sha256:e72da1fc3ecfdb1971f2946630367242cc805d816886249a8efd307e4b6cb9a0
[buildah-bud] Copying blob sha256:1e77f3fea317897f76c8d60a5752afd5ce214f25330367f75d4affeb3ae61163
[buildah-bud] Copying blob sha256:e02b196ff4a821ae65d8412c97aded572b0e6af286ca7448600b526958984730
[buildah-bud] Copying blob sha256:338ad4bc99bf7dd0dd9e0ecaa87baf63eddc55832c256a79074c532543f7e6a1
[buildah-bud] Copying blob sha256:2b102dd1d514db74bdf20f9986394de3362292ecaf791e0dc0999c36f6d106db
[buildah-bud] Copying blob sha256:18bd00b0c037a00cd40bcea29f9e61190a3e4e4204a55accb079fb219adee9d9
[buildah-bud] Copying blob sha256:b0e68b4540aef6584d7386360df0cda916ca2dd064cbb9dfeb52135521bfe7da
[buildah-bud] Copying blob sha256:2969e95b0a7016ca7d87b5de047e4b6e76554b936ac9ea4ddafa6445a0e0d095
[buildah-bud] Copying blob sha256:72664b7e0d8d6bc83bf6f2881b9f2ddca7b950900d978de82e6f1a483855601e
[buildah-bud] Copying blob sha256:a92bc23967c770b16f721e90a2e8237b9f643ddb72f3dd278c8e5084c42ecd5b
[buildah-bud] Copying config sha256:2b2814fc0501cb7e8e103bce12cd6807068037078e3ba3bc97f2897a09c205c4
[buildah-bud] Writing manifest to image destination
[buildah-bud] Storing signatures
[buildah-bud] --> 2b2814fc050
[buildah-bud] Successfully tagged image-registry.openshift-image-registry.svc:5000/spring-liberty/spring-liberty:latest
[buildah-bud] 2b2814fc0501cb7e8e103bce12cd6807068037078e3ba3bc97f2897a09c205c4

[buildah-push] Getting image source signatures
[buildah-push] Copying blob sha256:2b102dd1d514db74bdf20f9986394de3362292ecaf791e0dc0999c36f6d106db
[buildah-push] Copying blob sha256:338ad4bc99bf7dd0dd9e0ecaa87baf63eddc55832c256a79074c532543f7e6a1
[buildah-push] Copying blob sha256:e02b196ff4a821ae65d8412c97aded572b0e6af286ca7448600b526958984730
[buildah-push] Copying blob sha256:e72da1fc3ecfdb1971f2946630367242cc805d816886249a8efd307e4b6cb9a0
[buildah-push] Copying blob sha256:1e77f3fea317897f76c8d60a5752afd5ce214f25330367f75d4affeb3ae61163
[buildah-push] Copying blob sha256:9f54eef412758095c8079ac465d494a2872e02e90bf1fb5f12a1641c0d1bb78b
[buildah-push] Copying blob sha256:b0e68b4540aef6584d7386360df0cda916ca2dd064cbb9dfeb52135521bfe7da
[buildah-push] Copying blob sha256:2969e95b0a7016ca7d87b5de047e4b6e76554b936ac9ea4ddafa6445a0e0d095
[buildah-push] Copying blob sha256:18bd00b0c037a00cd40bcea29f9e61190a3e4e4204a55accb079fb219adee9d9
[buildah-push] Copying blob sha256:a92bc23967c770b16f721e90a2e8237b9f643ddb72f3dd278c8e5084c42ecd5b
[buildah-push] Copying blob sha256:72664b7e0d8d6bc83bf6f2881b9f2ddca7b950900d978de82e6f1a483855601e
[buildah-push] Copying config sha256:2b2814fc0501cb7e8e103bce12cd6807068037078e3ba3bc97f2897a09c205c4
[buildah-push] Writing manifest to image destination
[buildah-push] Storing signatures

[image-digest-exporter-sjbwg] {"severity":"INFO","timestamp":"2021-12-04T00:43:53.33655066Z","caller":"logging/config.go:116","message":"Successfully created the logger."}
[image-digest-exporter-sjbwg] {"severity":"INFO","timestamp":"2021-12-04T00:43:53.336886873Z","caller":"logging/config.go:117","message":"Logging level set to: info"}
[image-digest-exporter-sjbwg] {"severity":"INFO","timestamp":"2021-12-04T00:43:53.336940836Z","caller":"logging/config.go:79","message":"Fetch GitHub commit ID from kodata failed","error":"\"KO_DATA_PATH\" does not exist or is empty"}
[image-digest-exporter-sjbwg] {"severity":"INFO","timestamp":"2021-12-04T00:43:53.337073638Z","caller":"imagedigestexporter/main.go:59","message":"No index.json found for: image"}
```

# 参考
https://developers.redhat.com/articles/2021/06/14/project-shipwright-and-future-red-hat-openshift-builds#project_shipwright

https://github.com/shipwright-io/build