Red Hat OpenShift Study / コンテナのデプロイ - (3) s2i ビルド

# はじめに
前回の例では、GitHub上に管理されたDockerfileを元にOpenShift上でDockerイメージをビルドし、デプロイを行いました。
今回はs2i(source to image)ビルドという方法を用いてOpenShift上にコンテナをデプロイします。
今回の方法はプログラムのソースおよび、ビルダー・イメージと呼ばれる特殊なDockerイメージを用意しておき、それらを元に新たなイメージをビルドし、デプロイする、という流れになります。

今回のシナリオ: **ソース + ビルダー・イメージ => OpenShift上のPodとしてデプロイ**

## 関連記事
[Red Hat OpenShift Study / コンテナのデプロイ - (0) Dockerおさらい](https://qiita.com/tomotagwork/items/6b64cb54eaf45c057196)
[Red Hat OpenShift Study / コンテナのデプロイ - (1) Dockerイメージを元にしたデプロイ](https://qiita.com/tomotagwork/items/f7398ac3c71eefe24835)
[Red Hat OpenShift Study / コンテナのデプロイ - (2) Dockerビルド](https://qiita.com/tomotagwork/items/bb5919c27ed53a459d09)
[Red Hat OpenShift Study / コンテナのデプロイ - (3) s2i ビルド](https://qiita.com/tomotagwork/items/a86848e979b98910e4d4)

# 全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8505cc2b-8b7e-0f57-66a7-305a131815c0.png)

# s2iビルド補足
スクリプト言語の場合、アプリケーションのソースを開発して適切なディレクトリにそれらを配置すれば動かせるので、稼働環境を構築するのは比較的楽に行えます。
しかし、C/C++、Java、Go、COBOLなどの言語はコンパイラ言語であるため、基本的に事前にコンパイルを行って実行モジュールを作成するというステップが必要になります。さらにLibertyなどのミドルウェアが絡む場合は関連する定義が必要になるなど、稼働環境を整えるのに複雑な処理が関わってくることになります。
そのような複雑な制御をDockerfileだけで行うのは困難です。OpenShiftではs2iビルドという仕組みを提供しておりソースからアプリケーション稼働環境としてのイメージをビルドするステップを自動化する仕組みを提供してくれています。そこで使われるのが特殊な作法で作られた"ビルダー・イメージ"と呼ばれるDockerイメージです。
CやJavaなどのコンパイラ言語のビルドに必要な開発環境やビルド用のスクリプトを決まった作法でDockerイメージとして作成しておくと、そのビルダー・イメージとソースを与えれば、あとは自動的にビルド、デプロイが行われる、という仕組みです。
Javaなどのよく利用される言語については既にビルダー・イメージが提供されているのでそれをそのまま利用することもできますし、独自にカスタマイズしたビルダー・イメージを用意してそれを使うこともできます。
今回はビルダー・イメージの作成も含めてやってみます。ビルダー・イメージを作成する際は、source-to-image toolkitというツールが利用できます。
[GitHub: openshift/source-to-image](https://github.com/openshift/source-to-image)

※先の例ではGo言語を事前コンパイル無しで`go run`コマンドでスクリプト言語のように実行していましたが、実際には裏ではコンパイル(`go build`相当)が行われて実行モジュールが作成されてそれが実行される、という動きになっています。今回のシナリオでは先のGo言語の例を、コンパイルと実行をきちんと分けてs2iビルドの作法でデプロイしてみます。

s2iビルドで行われる内部処理の流れをざっくりと図で表すと以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/be48f8b7-deaa-8bce-16d6-d7682ecf9b88.png)
このような処理が自動で行われるので、開発環境およびassemble, run スクリプトを仕込んだビルダー・イメージを用意しておけば、ソースを作成/変更～デプロイまでの作業を容易に/迅速に行うことができます。

# 事前準備

## ソースの準備

これまでと同じGo言語のソースを使います。

```main.go
package main

import (
        "fmt"
        "log"
        "net/http"
)

func main(){
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){
                log.Println("received request")
                fmt.Fprintf(w, "Hello Docker!")
        })

        log.Println("start server")
        server := &http.Server{Addr: ":8080"}
        if err := server.ListenAndServe(); err != nil {
                log.Println(err)
        }
}
```

## ビルダー・イメージの準備

上のGo言語をビルドするためのビルダー・イメージを作成していきます。全体像の図中(3)～(6)に相当する操作です。
何をやっているのか分からなくなりそうなので、ここで実施する操作をもう少し詳細化した図を以下に整理しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8d0a5dad-4bcf-52af-e616-4a68c3bb3aec.png)

### source-to-image toolkitのインストール

作業用のLinuxにsource-to-image toolkitをインストールします。手順は以下のInstallationの箇所を参照。
[GitHub: openshift/source-to-image](https://github.com/openshift/source-to-image)

ダウンロード

```
# wget https://github.com/openshift/source-to-image/releases/download/v1.3.1/source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz
--2021-07-22 16:13:31--  https://github.com/openshift/source-to-image/releases/download/v1.3.1/source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz
github.com (github.com) をDNSに問いあわせています... 失敗しました: 名前またはサービスが不明です.
wget: ホストアドレス `github.com' を解決できませんでした。
[root@Test05 ~/openshift/test/s2i_toolkit]# set -o vi
[root@Test05 ~/openshift/test/s2i_toolkit]# wget https://github.com/openshift/source-to-image/releases/download/v1.3.1/source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz
--2021-07-22 16:13:45--  https://github.com/openshift/source-to-image/releases/download/v1.3.1/source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz
github.com (github.com) をDNSに問いあわせています... 52.192.72.89
github.com (github.com)|52.192.72.89|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 302 Found
場所: https://github-releases.githubusercontent.com/16323162/0ef32d00-0a3e-11eb-9ef9-25fa1793eb72?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210722%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210722T071344Z&X-Amz-Expires=300&X-Amz-Signature=8b95ce69b7e1e600f641fa30f9ca9c2e94da6d48d364ef5a997f176d49f729e6&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=16323162&response-content-disposition=attachment%3B%20filename%3Dsource-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz&response-content-type=application%2Foctet-stream [続く]
--2021-07-22 16:13:45--  https://github-releases.githubusercontent.com/16323162/0ef32d00-0a3e-11eb-9ef9-25fa1793eb72?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210722%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210722T071344Z&X-Amz-Expires=300&X-Amz-Signature=8b95ce69b7e1e600f641fa30f9ca9c2e94da6d48d364ef5a997f176d49f729e6&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=16323162&response-content-disposition=attachment%3B%20filename%3Dsource-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz&response-content-type=application%2Foctet-stream
github-releases.githubusercontent.com (github-releases.githubusercontent.com) をDNSに問いあわせています... 185.199.111.154, 185.199.108.154, 185.199.109.154, ...
github-releases.githubusercontent.com (github-releases.githubusercontent.com)|185.199.111.154|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 6692560 (6.4M) [application/octet-stream]
`source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz' に保存中

100%[====================================================================================================================================================>] 6,692,560   4.66MB/s 時間 1.4s

2021-07-22 16:13:47 (4.66 MB/s) - `source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz' へ保存完了 [6692560/6692560]
```

解凍してs2iをパスが通ったディレクトリに配置

```
# tar -xvf source-to-image-v1.3.1-a5a77147-linux-amd64.tar.gz
./
./sti
./s2i

# cp s2i /usr/local/bin/
```

確認

```
# s2i version
s2i v1.3.1
```

### ビルダー・イメージの作成

#### 雛形作成
`s2i create` コマンドでビルダー・イメージ作成の雛形となるディレクトリ構造、ファイル群が作成されます。これを編集していきます。

```
# s2i create gobuilder gobuilder
# tree --charset=C .
.
`-- gobuilder
    |-- Dockerfile
    |-- Makefile
    |-- README.md
    |-- s2i
    |   `-- bin
    |       |-- assemble
    |       |-- run
    |       |-- save-artifacts
    |       `-- usage
    `-- test
        |-- run
        `-- test-app
            `-- index.html

5 directories, 9 files
```

#### Dockerfile編集
ビルダー・イメージを作るためのDockerfileを作成します。
生成されたDockerfileを確認します。

<details><summary><font color="blue">Dockerfile(original)</font></summary><div>

```Dockerfile
# gobuilder
FROM openshift/base-centos7

# TODO: Put the maintainer name in the image metadata
# LABEL maintainer="Your Name <your@email.com>"

# TODO: Rename the builder environment variable to inform users about application you provide them
# ENV BUILDER_VERSION 1.0

# TODO: Set labels used in OpenShift to describe the builder image
#LABEL io.k8s.description="Platform for building xyz" \
#      io.k8s.display-name="builder x.y.z" \
#      io.openshift.expose-services="8080:http" \
#      io.openshift.tags="builder,x.y.z,etc."

# TODO: Install required packages here:
# RUN yum install -y ... && yum clean all -y
RUN yum install -y rubygems && yum clean all -y
RUN gem install asdf

# TODO (optional): Copy the builder files into /opt/app-root
# COPY ./<builder_folder>/ /opt/app-root/

# TODO: Copy the S2I scripts to /usr/libexec/s2i, since openshift/base-centos7 image
# sets io.openshift.s2i.scripts-url label that way, or update that label
COPY ./s2i/bin/ /usr/libexec/s2i

# TODO: Drop the root user and make the content of /opt/app-root owned by user 1001
# RUN chown -R 1001:1001 /opt/app-root

# This default user is created in the openshift/base-centos7 image
USER 1001

# TODO: Set the default port for applications built using this image
# EXPOSE 8080

# TODO: Set the default CMD for the image
# CMD ["/usr/libexec/s2i/usage"]
```

</div></details>

これを以下のように編集します。

```Dockerfile:Dockerfile
# gobuilder
FROM golang:latest

# TODO: Put the maintainer name in the image metadata
LABEL maintainer="Your Name <your@email.com>"

# TODO: Rename the builder environment variable to inform users about application you provide them
# ENV BUILDER_VERSION 1.0

# TODO: Set labels used in OpenShift to describe the builder image
LABEL io.k8s.description="Platform for building go" \
      io.k8s.display-name="builder go" \
      io.openshift.expose-services="8080:http" \
      io.openshift.tags="builder,go,golang"

# TODO: Install required packages here:
# RUN yum install -y ... && yum clean all -y
#RUN yum install -y rubygems && yum clean all -y
#RUN gem install asdf

# TODO (optional): Copy the builder files into /opt/app-root
# COPY ./<builder_folder>/ /opt/app-root/

# TODO: Copy the S2I scripts to /usr/libexec/s2i, since openshift/base-centos7 image
# sets io.openshift.s2i.scripts-url label that way, or update that label
COPY ./s2i/bin/ /usr/libexec/s2i

# TODO: Drop the root user and make the content of /opt/app-root owned by user 1001
# RUN chown -R 1001:1001 /opt/app-root

# This default user is created in the openshift/base-centos7 image
USER 1001

RUN mkdir test

# TODO: Set the default port for applications built using this image
EXPOSE 8080

# TODO: Set the default CMD for the image
CMD ["/usr/libexec/s2i/usage"]
```

#### assemble編集
生成されたassembleを確認します。

<details><summary><font color="blue">assemble(original)</font></summary><div>

```sh:assenble
#!/bin/bash -e
#
# S2I assemble script for the 'gobuilder' image.
# The 'assemble' script builds your application source so that it is ready to run.
#
# For more information refer to the documentation:
#       https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#

# If the 'gobuilder' assemble script is executed with the '-h' flag, print the usage.
if [[ "$1" == "-h" ]]; then
        exec /usr/libexec/s2i/usage
fi

# Restore artifacts from the previous build (if they exist).
#
if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then
  echo "---> Restoring build artifacts..."
  shopt -s dotglob
  mv /tmp/artifacts/* ./
  shopt -u dotglob
fi

echo "---> Installing application source..."
cp -Rf /tmp/src/. ./

echo "---> Building application from source..."
# TODO: Add build steps for your application, eg npm install, bundle install, pip install, etc.
```

</div></details>

assmbleはビルドを行うためのスクリプトです。/tmp/src/以下にソースがコピーされている前提で、そのソースをビルドするための処理をbashで記述します。
ここでは以下のように編集します。

```sh:assemble
#!/bin/bash -e
#
# S2I assemble script for the 'gobuilder' image.
# The 'assemble' script builds your application source so that it is ready to run.
#
# For more information refer to the documentation:
#       https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#

# If the 'gobuilder' assemble script is executed with the '-h' flag, print the usage.
if [[ "$1" == "-h" ]]; then
        exec /usr/libexec/s2i/usage
fi

# Restore artifacts from the previous build (if they exist).
#
#if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then
#  echo "---> Restoring build artifacts..."
#  shopt -s dotglob
#  mv /tmp/artifacts/* ./
#  shopt -u dotglob
#fi

echo "---> Installing application source..."
cp -Rf /tmp/src/. /go/test/

echo "---> Building application from source..."
# TODO: Add build steps for your application, eg npm install, bundle install, pip install, etc.
cd /go/test
export GOCACHE=/go/test;go build main.go
```

※今回は単純にmain.goというソースがある前提でそれをコンパイルするスクリプトを書いてしまっていますが、本来であればもっと汎用的に任意のソースが配置された場合でもビルドできるようなロジックにしておくことが望ましいと思われます。

#### run編集
生成されたrunを確認します。

<details><summary><font color="blue">run(original)</font></summary><div>

```sh:run
#!/bin/bash -e
#
# S2I run script for the 'gobuilder' image.
# The run script executes the server that runs your application.
#
# For more information see the documentation:
#       https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#

exec asdf -p 8080
```

</div></details>

runはコンテナが稼働する際に実行される処理を記載します(DockerfileのCMDで指定されるイメージ)。
ここでは以下のように編集します。

```sh:run
#!/bin/bash -e
#
# S2I run script for the 'gobuilder' image.
# The run script executes the server that runs your application.
#
# For more information see the documentation:
#       https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#

#exec asdf -p 8080
exec /go/test/main
```

#### usage編集
生成されたusageを確認します。

<details><summary><font color="blue">usage(original)</font></summary><div>

```sh:usage
#!/bin/bash -e
cat <<EOF
This is the gobuilder S2I image:
To use it, install S2I: https://github.com/openshift/source-to-image

Sample invocation:

s2i build <source code path/URL> gobuilder <application image>

You can then run the resulting image via:
docker run <application image>
EOF
```

</div></details>

usageにはビルダー・イメージのusageを記述するだけなので用途に合わせて適宜修正します。ここではそのまま。

#### ビルダー・イメージのビルド

ビルダー・イメージを作成するためのDockerfile、および、組み込むスクリプトが準備できたので、ビルダー・イメージをビルドしてみます。

```
[root@Test05 ~/]# cd gobuilder
[root@Test05 ~/gobuilder]# podman build -t gobuilder:latest .
STEP 1: FROM golang:latest
STEP 2: LABEL maintainer="Your Name <your@email.com>"
--> Using cache ba6a561e840d8d54246b0df4d988dae6fc5e84039ea603d919514fd5f8e70b64
STEP 3: LABEL io.k8s.description="Platform for building go"       io.k8s.display-name="builder go"       io.openshift.expose-services="8080:http"       io.openshift.tags="builder,go,golang"
--> Using cache db8025fdb90f29fef3e15a6cd27ae6ae1073e0862133806ed25814511f723878
STEP 4: COPY ./s2i/bin/ /usr/libexec/s2i
ace8c7b0f346f3084a0cfc1f097c379be230076a239917642dd50369d6c3f35d
STEP 5: USER 1001
bdf9ed9a6e8a2892e13a66633a3d18779bc5b123f08eff48432bc8c6ac7a87a9
STEP 6: RUN mkdir test
76ef4d60a55180425774b9121c2f3f2c1b6cc251752ca2dbd0ce345177e34e7c
STEP 7: EXPOSE 8080
32b5f049bb9bc9b199ee710ccbe93b953d714713855311741aef619b48cdbfa8
STEP 8: CMD ["/usr/libexec/s2i/usage"]
STEP 9: COMMIT gobuilder:latest
3d71b809338e71758372755da2c23a754ff6d50f207cae6addbdd57b9db00798
```

```
# podman images
REPOSITORY                                        TAG      IMAGE ID       CREATED          SIZE
localhost/gotemp                                  latest   61355a088666   5 minutes ago    890 MB
...
```

ビルダー・イメージが作成されました！

<details><summary><font color="blue">podman inspect localhost/gobuilder</font></summary><div>

```
# podman inspect localhost/gobuilder
[
    {
        "Id": "3d71b809338e71758372755da2c23a754ff6d50f207cae6addbdd57b9db00798",
        "Digest": "sha256:bb82e78e7bd559f2de7ee8c2fbf06bc11d27bddc497c5d491edd164d563287d1",
        "RepoTags": [
            "localhost/gobuilder:latest"
        ],
        "RepoDigests": [
            "localhost/gobuilder@sha256:bb82e78e7bd559f2de7ee8c2fbf06bc11d27bddc497c5d491edd164d563287d1"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-07-22T10:05:15.517825857Z",
        "Config": {
            "User": "1001",
            "ExposedPorts": {
                "8080/tcp": {}
            },
            "Env": [
                "PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOLANG_VERSION=1.16.5",
                "GOPATH=/go"
            ],
            "Cmd": [
                "/usr/libexec/s2i/usage"
            ],
            "WorkingDir": "/go",
            "Labels": {
                "io.k8s.description": "Platform for building go",
                "io.k8s.display-name": "builder go",
                "io.openshift.expose-services": "8080:http",
                "io.openshift.tags": "builder,go,golang",
                "maintainer": "Your Name <your@email.com>"
            }
        },
        "Version": "",
        "Author": "",
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 883376069,
        "VirtualSize": 883376069,
        "GraphDriver": {
            "Name": "overlay",
            "Data": {
                "LowerDir": "/var/lib/containers/storage/overlay/2730717756733fae47965783b31c126428eba48a2aef39a9bf283d21b3a24a0f/diff:/var/lib/containers/storage/overlay/63d3e8ef861456bb9b82ca50ca598a428f9d1d0cd9894a7b1194c0c62ffe93e8/diff:/var/lib/containers/storage/overlay/f3a724b7be77cdfc00633a81166358d96e7c89bb71fd5ac7dbca849674e7ce86/diff:/var/lib/containers/storage/overlay/6bf48fbcb5b3009d4744c1281b8cec7ce75630e498f3d9205446403969df3b00/diff:/var/lib/containers/storage/overlay/e8f903479abd1b42f5a36645c9e6508addbd4b346ed3758043aef6007c38c529/diff:/var/lib/containers/storage/overlay/4d7b07c79d022e914336d93a6bef40c805fba23722db65ec1e12fcfefe28fd05/diff:/var/lib/containers/storage/overlay/e0a4cbbbbd465a20f7eed2cb2b8f5788a862e315995c83b8544345ebf5c1d575/diff:/var/lib/containers/storage/overlay/688e187d6c79c46e8261890f0010fd5d178b8faa178959b0b46b2635aa1eeff3/diff",
                "UpperDir": "/var/lib/containers/storage/overlay/ab2fcfbd7badf53e2e45accd75dd909435b5ee7b81e601452c86b05cb2308ba0/diff",
                "WorkDir": "/var/lib/containers/storage/overlay/ab2fcfbd7badf53e2e45accd75dd909435b5ee7b81e601452c86b05cb2308ba0/work"
            }
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:688e187d6c79c46e8261890f0010fd5d178b8faa178959b0b46b2635aa1eeff3",
                "sha256:00bcea93703b384ab61d2344d6e721c75b0e47198b7912136a86759d8d885711",
                "sha256:ccb9b68523fdb47816f2a15d7590d06ff3d897dfdb3e0733e9c06a2bb79ebfc7",
                "sha256:685934357c8993799eda4a6d71c2bb2d2c54b1138d6e037f675eeeeffc719f2d",
                "sha256:9d52e952d0a781ee401640f2a7a9155f313c927ba5b3880959e055619a3391a9",
                "sha256:762eb5b089c5c496c946d1ffb5d8088a4b3b4648635fd46e8e4c82ee36c33687",
                "sha256:c92e53084342a99bee2b3d5a410f5f6d4df192eff4a8381c5c558cb0f150646d",
                "sha256:faa62677f96b77255f41c48bd897773edb0da9410aa6245c38629304d95d6fc8",
                "sha256:b64a360d1804e655c9f39bedd5705845bbd75203fa9942a12adad0565df94e66"
            ]
        },
        "Labels": {
            "io.k8s.description": "Platform for building go",
            "io.k8s.display-name": "builder go",
            "io.openshift.expose-services": "8080:http",
            "io.openshift.tags": "builder,go,golang",
            "maintainer": "Your Name <your@email.com>"
        },
        "Annotations": {},
        "ManifestType": "application/vnd.oci.image.manifest.v1+json",
        "User": "1001",
        "History": [
            {
                "created": "2021-05-12T01:21:03.394550564Z",
                "created_by": "/bin/sh -c #(nop) ADD file:1a1eae7a82c66d673971436ce2605e97d107e2934b7cdec876c64923ae6f4f85 in / "
            },
            {
                "created": "2021-05-12T01:21:03.936921102Z",
                "created_by": "/bin/sh -c #(nop)  CMD [\"bash\"]",
                "empty_layer": true
            },
            {
                "created": "2021-05-12T01:55:47.946102005Z",
                "created_by": "/bin/sh -c set -eux; \tapt-get update; \tapt-get install -y --no-install-recommends \t\tca-certificates \t\tcurl \t\tnetbase \t\twget \t; \trm -rf /var/lib/apt/lists/*"
            },
            {
                "created": "2021-05-12T01:55:55.914034892Z",
                "created_by": "/bin/sh -c set -ex; \tif ! command -v gpg > /dev/null; then \t\tapt-get update; \t\tapt-get install -y --no-install-recommends \t\t\tgnupg \t\t\tdirmngr \t\t; \t\trm -rf /var/lib/apt/lists/*; \tfi"
            },
            {
                "created": "2021-05-12T01:56:16.028664517Z",
                "created_by": "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends \t\tgit \t\tmercurial \t\topenssh-client \t\tsubversion \t\t\t\tprocps \t&& rm -rf /var/lib/apt/lists/*"
            },
            {
                "created": "2021-05-12T19:23:46.753720203Z",
                "created_by": "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends \t\tg++ \t\tgcc \t\tlibc6-dev \t\tmake \t\tpkg-config \t&& rm -rf /var/lib/apt/lists/*"
            },
            {
                "created": "2021-05-12T19:23:47.325489492Z",
                "created_by": "/bin/sh -c #(nop)  ENV PATH=/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "empty_layer": true
            },
            {
                "created": "2021-06-04T01:45:34.492829967Z",
                "created_by": "/bin/sh -c #(nop)  ENV GOLANG_VERSION=1.16.5",
                "empty_layer": true
            },
            {
                "created": "2021-06-04T01:45:51.158534306Z",
                "created_by": "/bin/sh -c set -eux; \t\tdpkgArch=\"$(dpkg --print-architecture)\"; \turl=; \tcase \"${dpkgArch##*-}\" in \t\t'amd64') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-amd64.tar.gz'; \t\t\tsha256='b12c23023b68de22f74c0524f10b753e7b08b1504cb7e417eccebdd3fae49061'; \t\t\t;; \t\t'armel') \t\t\texport GOARCH='arm' GOARM='5' GOOS='linux'; \t\t\t;; \t\t'armhf') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-armv6l.tar.gz'; \t\t\tsha256='93cacacfbe87e3106b5bf5821de106f0f0a43c8bd1029826d44445c15df795a5'; \t\t\t;; \t\t'arm64') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-arm64.tar.gz'; \t\t\tsha256='d5446b46ef6f36fdffa852f73dfbbe78c1ddf010b99fa4964944b9ae8b4d6799'; \t\t\t;; \t\t'i386') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-386.tar.gz'; \t\t\tsha256='a37c6b71d0b673fe8dfeb2a8b3de78824f05d680ad32b7ac6b58c573fa6695de'; \t\t\t;; \t\t'mips64el') \t\t\texport GOARCH='mips64le' GOOS='linux'; \t\t\t;; \t\t'ppc64el') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-ppc64le.tar.gz'; \t\t\tsha256='fad2da6c86ede8448d2d0e66e1776e2f0ae9169714eade29b9ffbbdede7fc6cc'; \t\t\t;; \t\t's390x') \t\t\turl='https://dl.google.com/go/go1.16.5.linux-s390x.tar.gz'; \t\t\tsha256='21085f6a3568fae639edf383cce78bcb00d8f415e5e3d7feb04b6124e8e9efc1'; \t\t\t;; \t\t*) echo >&2 \"error: unsupported architecture '$dpkgArch' (likely packaging update needed)\"; exit 1 ;; \tesac; \tbuild=; \tif [ -z \"$url\" ]; then \t\tbuild=1; \t\turl='https://dl.google.com/go/go1.16.5.src.tar.gz'; \t\tsha256='7bfa7e5908c7cc9e75da5ddf3066d7cbcf3fd9fa51945851325eebc17f50ba80'; \t\techo >&2; \t\techo >&2 \"warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source\"; \t\techo >&2; \tfi; \t\twget -O go.tgz.asc \"$url.asc\" --progress=dot:giga; \twget -O go.tgz \"$url\" --progress=dot:giga; \techo \"$sha256 *go.tgz\" | sha256sum --strict --check -; \t\texport GNUPGHOME=\"$(mktemp -d)\"; \tgpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys 'EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796'; \tgpg --batch --verify go.tgz.asc go.tgz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" go.tgz.asc; \t\ttar -C /usr/local -xzf go.tgz; \trm go.tgz; \t\tif [ -n \"$build\" ]; then \t\tsavedAptMark=\"$(apt-mark showmanual)\"; \t\tapt-get update; \t\tapt-get install -y --no-install-recommends golang-go; \t\t\t\t( \t\t\tcd /usr/local/go/src; \t\t\texport GOROOT_BOOTSTRAP=\"$(go env GOROOT)\" GOHOSTOS=\"$GOOS\" GOHOSTARCH=\"$GOARCH\"; \t\t\t./make.bash; \t\t); \t\t\t\tapt-mark auto '.*' > /dev/null; \t\tapt-mark manual $savedAptMark > /dev/null; \t\tapt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \t\trm -rf /var/lib/apt/lists/*; \t\t\t\tgo install std; \t\t\t\trm -rf \t\t\t/usr/local/go/pkg/*/cmd \t\t\t/usr/local/go/pkg/bootstrap \t\t\t/usr/local/go/pkg/obj \t\t\t/usr/local/go/pkg/tool/*/api \t\t\t/usr/local/go/pkg/tool/*/go_bootstrap \t\t\t/usr/local/go/src/cmd/dist/dist \t\t; \tfi; \t\tgo version"
            },
            {
                "created": "2021-06-04T01:45:52.437406165Z",
                "created_by": "/bin/sh -c #(nop)  ENV GOPATH=/go",
                "empty_layer": true
            },
            {
                "created": "2021-06-04T01:45:52.737942801Z",
                "created_by": "/bin/sh -c #(nop)  ENV PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "empty_layer": true
            },
            {
                "created": "2021-06-04T01:45:54.354693931Z",
                "created_by": "/bin/sh -c mkdir -p \"$GOPATH/src\" \"$GOPATH/bin\" && chmod -R 777 \"$GOPATH\""
            },
            {
                "created": "2021-06-04T01:45:54.644455418Z",
                "created_by": "/bin/sh -c #(nop) WORKDIR /go",
                "empty_layer": true
            },
            {
                "created": "2021-07-22T08:28:46.550795102Z",
                "created_by": "/bin/sh -c #(nop) LABEL maintainer=\"Your Name <your@email.com>\"",
                "empty_layer": true
            },
            {
                "created": "2021-07-22T08:28:46.619209217Z",
                "created_by": "/bin/sh -c #(nop) LABEL io.k8s.description=\"Platform for building go\"       io.k8s.display-name=\"builder go\"       io.openshift.expose-services=\"8080:http\"       io.openshift.tags=\"builder,go,golang\"",
                "empty_layer": true
            },
            {
                "created": "2021-07-22T10:05:14.783344889Z",
                "created_by": "/bin/sh -c #(nop) COPY dir:af2c12a3e738106ec0cbbea7562d4511b47ba661299e771ea8c2f771c1feda77 in /usr/libexec/s2i "
            },
            {
                "created": "2021-07-22T10:05:14.908149901Z",
                "created_by": "/bin/sh -c #(nop) USER 1001",
                "empty_layer": true
            },
            {
                "created": "2021-07-22T10:05:15.317008831Z",
                "created_by": "/bin/sh -c mkdir test"
            },
            {
                "created": "2021-07-22T10:05:15.442013069Z",
                "created_by": "/bin/sh -c #(nop) EXPOSE 8080",
                "empty_layer": true
            },
            {
                "created": "2021-07-22T10:05:15.517825857Z",
                "created_by": "/bin/sh -c #(nop) CMD [\"/usr/libexec/s2i/usage\"]",
                "empty_layer": true
            }
        ]
    }
]
```

</div></details>


### ローカルでのビルダー・イメージ/ソースのテスト
さて、ビルダー・イメージとソースが準備できましたが、これがきちんと動作するかローカルのLinux環境でテストしておきます。
s2i toolkitではこのビルダー・イメージのテストもできます。つまり、本来OpenShift上で実施されるビルド処理を、ローカルの環境で疑似的にテストできるということです。

適当なディレクトリにapp/main.go(Goのソース)を配置し、出力用のディレクトリgotempを作成しておきます。

```
[root@Test05 ~/openshift/test/s2i_test]# ls -la app
合計 4
drwxr-xr-x. 2 root root  21  7月 22 17:32 .
drwxr-xr-x. 5 root root  48  7月 22 18:43 ..
-rw-r--r--. 1 root root 453  7月 22 17:32 main.go

[root@Test05 ~/openshift/test/s2i_test]# mkdir gotemp
```

s2i toolkitの `s2i build`コマンドを使用すると、ソースとビルダー・イメージから目的のイメージを生成させることができます。
基本的なsyntaxとしてはこんな感じです。
`s2i build <source_dir> <builder_image> <generated_image>`
デフォルトだとdocker環境にイメージを生成しようとするようですが、今回はpodman使っているので、一旦Dockerfileとしてイメージを生成させるために--as-dockerfileオプションで出力先ディレクトリを指定します。

```
[root@Test05 ~/openshift/test/s2i_test]# s2i build app/ gobuilder:latest gotemp --as-dockerfile gotemp/Dockerfile
Application dockerfile generated in gotemp/Dockerfile

[root@Test05 ~/openshift/test/s2i_test]# tree --charset=C gotemp
gotemp
|-- Dockerfile
|-- downloads
|   |-- defaultScripts
|   `-- scripts
`-- upload
    |-- scripts
    `-- src
        `-- main.go

6 directories, 2 files
```

これでs2iビルドが疑似的に行われてソースとビルダー・イメージから新たにDockerイメージ(gotemp)が作成されました。
これがちゃんと動くか試してみます。

podmanでビルド

```
# podman build -t gotemp gotemp/
STEP 1: FROM gobuilder:latest
STEP 2: LABEL "io.openshift.s2i.build.image"="gobuilder:latest"       "io.openshift.s2i.build.source-location"="app/"       "io.k8s.display-name"="gotemp"
8cea6c19c949cbce7e47ad6816cd60ab9f172adb35071bd0e8ff6afd01c9639e
STEP 3: USER root
da65043e040e483e880c6ce6765027ba056a4078c4bf262f992bc91133f0938e
STEP 4: COPY upload/src /tmp/src
d510bab52d352bed4b62813c01e10c3ec141f741fc72a59ead8177f910583e31
STEP 5: RUN chown -R 1001:0 /tmp/src
2bfeb96adc158850e6bf9f7cdc04dd9508756a647d67450bf2725bf60d97e559
STEP 6: USER 1001
52ca32821f2391830315d5c4543646130cc66e78fe755e346be3b870e91d7444
STEP 7: RUN /usr/libexec/s2i/assemble
---> Installing application source...
---> Building application from source...
cb855d169b3e2aeafc95c06eb0a391c7fba8c9ac2bc735ce26559124e6ea067e
STEP 8: CMD /usr/libexec/s2i/run
STEP 9: COMMIT gotemp
4a9c4ff80c34b46244bfb146119ff3cc148f67805905cf76f8542e0e9da52bac
```

実行/テスト

```
# podman run --rm -d -u 1001 -p 8080:8080  --name gotemp  gotemp
4ecfde2e81c77867047a04f2ae789cdf5f427882d35040f9d43e84da96381e4b

# curl localhost:8080
Hello Docker!

# podman stop gotemp
4ecfde2e81c77867047a04f2ae789cdf5f427882d35040f9d43e84da96381e4b
```

アクセスできました！ すなわち、先に作ったビルダー・イメージとソースがきちんと意図した通りに動いていることが確認できました。

## ビルダー・イメージ/ソースの配置
ビルダー・イメージとソースが問題なさそうなことをローカルで確認できたので、これらをOpenShiftから参照できる所に配置します。

### ビルダー・イメージをQuay.ioに配置
ビルダー・イメージは直接OpenShift内の内部レジストリに配置してもよいのですが、ここでは外部のレジストリサービス(Quay.io)を使ってみます。

```
# podman login -u tomotagwork quay.io
Password:
Login Succeeded!

# skopeo copy containers-storage:localhost/gobuilder:latest docker://quay.io/tomotagwork/gobuilder
Getting image source signatures
Copying blob 685934357c89 done
Copying blob 9d52e952d0a7 done
Copying blob 688e187d6c79 done
Copying blob 00bcea93703b done
Copying blob ccb9b68523fd done
Copying blob 762eb5b089c5 done
Copying blob faa62677f96b done
Copying blob c92e53084342 done
Copying blob b64a360d1804 done
Copying config 3d71b80933 done
Writing manifest to image destination
Copying config 3d71b80933 done
Writing manifest to image destination
Storing signatures
```

確認

```
[root@Test05 ~]# skopeo inspect docker://quay.io/tomotagwork/gobuilder
{
    "Name": "quay.io/tomotagwork/gobuilder",
    "Digest": "sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6",
    "RepoTags": [
        "latest"
    ],
    "Created": "2021-07-22T10:05:15.517825857Z",
    "DockerVersion": "",
    "Labels": {
        "io.k8s.description": "Platform for building go",
        "io.k8s.display-name": "builder go",
        "io.openshift.expose-services": "8080:http",
        "io.openshift.tags": "builder,go,golang",
        "maintainer": "Your Name \u003cyour@email.com\u003e"
    },
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed",
        "sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3",
        "sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57",
        "sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5",
        "sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58",
        "sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664",
        "sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27",
        "sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e",
        "sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd"
    ],
    "Env": [
        "PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "GOLANG_VERSION=1.16.5",
        "GOPATH=/go"
    ]
}
```

ブラウザからも参照できる状態になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/8ce16c0a-6884-30f4-e23e-2939cef34b5f.png)

### ソースをGitHub上に配置

先に作ったopenshift-testというリポジトリに別のフォルダ"gotest_s2i_src"というフォルダを用意し、そこにGoのソース(main.go)を配置しておきます。
(通常のgitの操作なのでここでは手順の詳細は省略)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132331/b6747fb6-aa19-d5ad-3b9b-8473512dcfbd.png)

# コンテナのデプロイ
上で準備したビルダー・イメージとソースを元に、s2iビルド、デプロイを実施してみます。全体像の図の(7)～(10)を実行します。

## プロジェクト作成

```
# oc new-project tomotag-test03
Now using project "tomotag-test03" on server "https://c100-e.jp-tok.containers.cloud.ibm.com:30549".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/serve_hostname
```

## GitHubアクセス用シークレット作成
前回の記事と同じ要領でGitHubアクセス用シークレットを作成します。
参考: [OpneShift Container Platform V4.5 - ビルド - 3.4 Gitソース](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.5/html/builds/builds-source-code_creating-build-inputs#builds-adding-source-clone-secrets_creating-build-inputs)

Basic認証用にユーザーIDとパスワードをLiteralで指定。

```
# oc create secret generic github --from-literal=username=tomotagwork --from-literal=password=xxxxx --type=kubernetes.io/basic-auth
secret/github created
```

アノテーションを付与する。

```
# oc annotate secret github 'build.openshift.io/source-secret-match-uri-1=https://github.com/tomotagwork/*'
secret/github annotated
```

以下のようなシークレットがネームスペースtomotag-test03に作成されました。

```
# oc get secret github -o yaml
apiVersion: v1
data:
  password: xxx
  username: dG9tb3RhZ3dvcms=
kind: Secret
metadata:
  annotations:
    build.openshift.io/source-secret-match-uri-1: https://github.com/tomotagwork/*
  creationTimestamp: "2021-07-23T02:31:07Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:password: {}
        f:username: {}
      f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2021-07-23T02:31:07Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:build.openshift.io/source-secret-match-uri-1: {}
    manager: kubectl-annotate
    operation: Update
    time: "2021-07-23T02:31:46Z"
  name: github
  namespace: tomotag-test03
  resourceVersion: "75003647"
  selfLink: /api/v1/namespaces/tomotag-test03/secrets/github
  uid: 72dd3745-c1b8-41ed-8d7e-80ab8104f4cf
type: kubernetes.io/basic-auth
```


## Quay.ioアクセス用シークレット作成
これも前の記事の要領でQuay.ioアクセス用のシークレットを作成します。

```
# podman login -u tomotagwork quay.io
Password:
Login Succeeded!

# oc create secret generic quayio --from-file .dockerconfigjson=${XDG_RUNTIME_DIR}/containers/auth.json --type kubernetes.io/dockerconfigjson
secret/quayio created
````

## ビルダー・イメージのImageStream作成
今回は外部のレジストリ上にあるビルダー・イメージを使用することを想定しているため、`oc import-image` コマンドを使用して事前にこのビルダー・イメージを参照するImageStreamを作成しておきます。

※`oc import-image`コマンドで外部のレジストリにアクセスする際は、現在のプロジェクト内のシークレットを検索し、レジストリーのホスト名と一致するものを探して一致するものを使用してくれるようです。


```
# oc import-image gobuilder:latest --from quay.io/tomotagwork/gobuilder:latest --confirm
imagestream.image.openshift.io/gobuilder imported

Name:                   gobuilder
Namespace:              tomotag-test03
Created:                Less than a second ago
Labels:                 <none>
Annotations:            openshift.io/image.dockerRepositoryCheck=2021-07-23T02:47:22Z
Image Repository:       image-registry.openshift-image-registry.svc:5000/tomotag-test03/gobuilder
Image Lookup:           local=false
Unique Images:          1
Tags:                   1

latest
  tagged from quay.io/tomotagwork/gobuilder:latest

  * quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
      Less than a second ago

Image Name:     gobuilder:latest
Docker Image:   quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Name:           sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Created:        Less than a second ago
Annotations:    image.openshift.io/dockerLayersOrder=ascending
Image Size:     333.9MB in 9 layers
Layers:         52.19MB sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
                8.079MB sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
                10.22MB sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
                54.48MB sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
                71.95MB sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
                136.9MB sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
                181B    sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
                1.233kB sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
                274B    sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
Image Created:  17 hours ago
Author:         <none>
Arch:           amd64
Command:        /usr/libexec/s2i/usage
Working Dir:    /go
User:           1001
Exposes Ports:  8080/tcp
Docker Labels:  io.k8s.description=Platform for building go
                io.k8s.display-name=builder go
                io.openshift.expose-services=8080:http
                io.openshift.tags=builder,go,golang
                maintainer=Your Name <your@email.com>
Environment:    PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                GOLANG_VERSION=1.16.5
                GOPATH=/go
```

内部レジストリにもイメージが取り込まれたことが確認できます。

```
# podman search --tls-verify=false image-registry-openshift-image-registry.xxx.containers.appdomain.cloud/tomotag-test03
INDEX             NAME                                                                                              DESCRIPTION   STARS   OFFICIAL   AUTOMATED
appdomain.cloud   image-registry-openshift-image-registry.xxx.containers.appdomain.cloud/tomotag-test03/gobuilder                 0
```

## ビルド&デプロイ
デフォルトではビルド時には"builder"というサービスアカウントが使用されます。ビルドする際に元になるDockerイメージのレジストリに対して認証情報が必要な場合は、"builder"アカウントに対して先に作成したsecretをリンクしておく必要があります。

```
# oc secrets link builder quayio
```

これで一通り準備は整ったので、いよいよoc new-appコマンドでコンテナをデプロイします。
syntaxとしては以下のような感じです。
oc new-app --as-deployment-config --name *appName* --strategy=source *builderImage*~*sourceRepository* --context-dir *sourceFolder*

*builderImage*: ここでは上で作成した イメージ・ストリーム `gobuilder:latest` を指定します。
*sourceRepository*: ここではGitHub上に用意したリポジトリのmainブランチを指定します。(`https://github.com/tomotagwork/openshift-test#main`)
*sourceFolder*: ここではターゲットのソースが配置されたGitHubリポジトリ上のフォルダ `gotest_s2i_src` を指定します。


```
[root@Test05 ~]# oc new-app --as-deployment-config --name gotest --strategy=source gobuilder:latest~https://github.com/tomotagwork/openshift-test#main --context-dir gotest_s2i_src
--> Found image 3d71b80 (17 hours old) in image stream "tomotag-test03/gobuilder" under tag "latest" for "gobuilder:latest"

    builder go
    ----------
    Platform for building go

    Tags: builder, go, golang

    * A source build using source code from https://github.com/tomotagwork/openshift-test#main will be created
      * The resulting image will be pushed to image stream tag "gotest:latest"
      * Use 'oc start-build' to trigger a new build
    * This image will be deployed in deployment config "gotest"
    * Port 8080/tcp will be load balanced by service "gotest"
      * Other containers can access this service through the hostname "gotest"

--> Creating resources ...
    imagestream.image.openshift.io "gotest" created
    buildconfig.build.openshift.io "gotest" created
    deploymentconfig.apps.openshift.io "gotest" created
    service "gotest" created
--> Success
    Build scheduled, use 'oc logs -f buildconfig/gotest' to track its progress.
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose service/gotest'
    Run 'oc status' to view your app.
```

```
[root@Test05 ~]# oc get all
NAME                  READY   STATUS      RESTARTS   AGE
pod/gotest-1-build    0/1     Completed   0          2m52s
pod/gotest-1-deploy   0/1     Completed   0          75s
pod/gotest-1-dhtgm    1/1     Running     0          72s

NAME                             DESIRED   CURRENT   READY   AGE
replicationcontroller/gotest-1   1         1         1       75s

NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/gotest   ClusterIP   172.21.xxx.xxx   <none>        8080/TCP   2m52s

NAME                                        REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/gotest   1          1         1         config,image(gotest:latest)

NAME                                    TYPE     FROM       LATEST
buildconfig.build.openshift.io/gotest   Source   Git@main   1

NAME                                TYPE     FROM          STATUS     STARTED         DURATION
build.build.openshift.io/gotest-1   Source   Git@8b7b10f   Complete   2 minutes ago   1m36s

NAME                                       IMAGE REPOSITORY                                                            TAGS     UPDATED
imagestream.image.openshift.io/gobuilder   image-registry.openshift-image-registry.svc:5000/tomotag-test03/gobuilder   latest   22 minutes ago
imagestream.image.openshift.io/gotest      image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest      latest   About a minute ago
```

PodがRunningになりました！

ビルド時のログを確認しておきます。

<details><summary><font color="blue">oc logs bc/gotest -f</font></summary><div>

```
# oc logs bc/gotest -f
Cloning "https://github.com/tomotagwork/openshift-test" ...
        Commit: 8b7b10f5111363d494a26911856303a90d32d701 (add s2i source)
        Author: Tomohiro Taguchi <tomotagwork@gmail.com>
        Date:   Fri Jul 23 11:04:34 2021 +0900
Caching blobs under "/var/cache/blobs".
Getting image source signatures
Copying blob sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
Copying blob sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
Copying blob sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
Copying blob sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
Copying blob sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
Copying blob sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
Copying blob sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
Copying blob sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
Copying blob sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
Copying config sha256:3d71b809338e71758372755da2c23a754ff6d50f207cae6addbdd57b9db00798
Writing manifest to image destination
Storing signatures
Generating dockerfile with builder image quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Adding transient rw bind mount for /run/secrets/rhsm
STEP 1: FROM quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
STEP 2: LABEL "io.openshift.build.commit.message"="add s2i source"       "io.openshift.build.source-context-dir"="gotest_s2i_src"       "io.openshift.build.image"="quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6"       "io.openshift.build.commit.author"="Tomohiro Taguchi <tomotagwork@gmail.com>"       "io.openshift.build.commit.date"="Fri Jul 23 11:04:34 2021 +0900"       "io.openshift.build.commit.id"="8b7b10f5111363d494a26911856303a90d32d701"       "io.openshift.build.commit.ref"="main"
STEP 3: ENV OPENSHIFT_BUILD_NAME="gotest-1"     OPENSHIFT_BUILD_NAMESPACE="tomotag-test03"     OPENSHIFT_BUILD_SOURCE="https://github.com/tomotagwork/openshift-test"     OPENSHIFT_BUILD_REFERENCE="main"     OPENSHIFT_BUILD_COMMIT="8b7b10f5111363d494a26911856303a90d32d701"
STEP 4: USER root
STEP 5: COPY upload/src /tmp/src
STEP 6: RUN chown -R 1001:0 /tmp/src
STEP 7: USER 1001
STEP 8: RUN /usr/libexec/s2i/assemble
---> Installing application source...
---> Building application from source...
STEP 9: CMD /usr/libexec/s2i/run
STEP 10: COMMIT temp.builder.openshift.io/tomotag-test03/gotest-1:e58c8673
Getting image source signatures
Copying blob sha256:688e187d6c79c46e8261890f0010fd5d178b8faa178959b0b46b2635aa1eeff3
Copying blob sha256:00bcea93703b384ab61d2344d6e721c75b0e47198b7912136a86759d8d885711
Copying blob sha256:ccb9b68523fdb47816f2a15d7590d06ff3d897dfdb3e0733e9c06a2bb79ebfc7
Copying blob sha256:685934357c8993799eda4a6d71c2bb2d2c54b1138d6e037f675eeeeffc719f2d
Copying blob sha256:9d52e952d0a781ee401640f2a7a9155f313c927ba5b3880959e055619a3391a9
Copying blob sha256:762eb5b089c5c496c946d1ffb5d8088a4b3b4648635fd46e8e4c82ee36c33687
Copying blob sha256:c92e53084342a99bee2b3d5a410f5f6d4df192eff4a8381c5c558cb0f150646d
Copying blob sha256:faa62677f96b77255f41c48bd897773edb0da9410aa6245c38629304d95d6fc8
Copying blob sha256:b64a360d1804e655c9f39bedd5705845bbd75203fa9942a12adad0565df94e66
Copying blob sha256:0bd010cbbf006b8d038f0855f14bd907a9c44df4b88564956884c462bec0f71d
Copying config sha256:77153729a12350f3304698ac3f51e2306a4ae88bdfd90c8d25a736ea1e99009f
Writing manifest to image destination
Storing signatures
--> 77153729a12
77153729a12350f3304698ac3f51e2306a4ae88bdfd90c8d25a736ea1e99009f

Pushing image image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest:latest ...
Getting image source signatures
Copying blob sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
Copying blob sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
Copying blob sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
Copying blob sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
Copying blob sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
Copying blob sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
Copying blob sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
Copying blob sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
Copying blob sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
Copying blob sha256:0bd010cbbf006b8d038f0855f14bd907a9c44df4b88564956884c462bec0f71d
Copying config sha256:77153729a12350f3304698ac3f51e2306a4ae88bdfd90c8d25a736ea1e99009f
Writing manifest to image destination
Storing signatures
Successfully pushed image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
Push successful
```

</div></details>

# 稼働確認
作成されたserviceをrouteとして公開して実際にアクセスしてみます

```
# oc get svc
NAME     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
gotest   ClusterIP   172.21.xxx.xxx   <none>        8080/TCP   4m30s

[root@Test05 ~]# oc expose svc gotest
route.route.openshift.io/gotest exposed

[root@Test05 ~]# oc get route
NAME     HOST/PORT                                                                                                            PATH   SERVICES   PORT       TERMINATION   WILDCARD
gotest   gotest-tomotag-test03.xxx.containers.appdomain.cloud          gotest     8080-tcp                 None
```

curlでアクセスしてみる。

```
[root@Test05 ~]# curl gotest-tomotag-test03.xxx.containers.appdomain.cloud
Hello Docker!
```

きちんと結果が返されました！

# 生成されたリソースの確認

oc new-appコマンドで生成されたリソースを確認しておきます。

## BuildConfig

<details><summary><font color="blue">oc get bc/gotest -o yaml</font></summary><div>

```yaml
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: "2021-07-23T03:07:16Z"
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
  managedFields:
  - apiVersion: build.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/generated-by: {}
        f:labels:
          .: {}
          f:app: {}
          f:app.kubernetes.io/component: {}
          f:app.kubernetes.io/instance: {}
      f:spec:
        f:output:
          f:to:
            .: {}
            f:kind: {}
            f:name: {}
        f:runPolicy: {}
        f:source:
          f:contextDir: {}
          f:git:
            .: {}
            f:ref: {}
            f:uri: {}
          f:type: {}
        f:strategy:
          f:sourceStrategy:
            .: {}
            f:from:
              .: {}
              f:kind: {}
              f:name: {}
              f:namespace: {}
          f:type: {}
    manager: oc
    operation: Update
    time: "2021-07-23T03:07:16Z"
  - apiVersion: build.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:triggers: {}
      f:status:
        f:lastVersion: {}
    manager: openshift-apiserver
    operation: Update
    time: "2021-07-23T03:07:17Z"
  name: gotest
  namespace: tomotag-test03
  resourceVersion: "75011831"
  selfLink: /apis/build.openshift.io/v1/namespaces/tomotag-test03/buildconfigs/gotest
  uid: b1a3abdb-baa9-40a6-b99a-8756d936f2f9
spec:
  failedBuildsHistoryLimit: 5
  nodeSelector: null
  output:
    to:
      kind: ImageStreamTag
      name: gotest:latest
  postCommit: {}
  resources: {}
  runPolicy: Serial
  source:
    contextDir: gotest_s2i_src
    git:
      ref: main
      uri: https://github.com/tomotagwork/openshift-test
    sourceSecret:
      name: github
    type: Git
  strategy:
    sourceStrategy:
      from:
        kind: ImageStreamTag
        name: gobuilder:latest
        namespace: tomotag-test03
    type: Source
  successfulBuildsHistoryLimit: 5
  triggers:
  - github:
      secret: fO1pxZQIUHf2ZwXq5wME
    type: GitHub
  - generic:
      secret: nlrxHWHRo0KErXvTc7Fr
    type: Generic
  - type: ConfigChange
  - imageChange:
      lastTriggeredImageID: quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
    type: ImageChange
status:
  lastVersion: 1
```

</div></details>

<details><summary><font color="blue">oc describe bc/gotest</font></summary><div>

```
Name:           gotest
Namespace:      tomotag-test03
Created:        8 minutes ago
Labels:         app=gotest
                app.kubernetes.io/component=gotest
                app.kubernetes.io/instance=gotest
Annotations:    openshift.io/generated-by=OpenShiftNewApp
Latest Version: 1

Strategy:       Source
URL:            https://github.com/tomotagwork/openshift-test
Ref:            main
ContextDir:     gotest_s2i_src
Source Secret:  github
From Image:     ImageStreamTag tomotag-test03/gobuilder:latest
Output to:      ImageStreamTag gotest:latest

Build Run Policy:       Serial
Triggered by:           Config, ImageChange
Webhook GitHub:
        URL:    https://c100-e.jp-tok.containers.cloud.ibm.com:30549/apis/build.openshift.io/v1/namespaces/tomotag-test03/buildconfigs/gotest/webhooks/<secret>/github
Webhook Generic:
        URL:            https://c100-e.jp-tok.containers.cloud.ibm.com:30549/apis/build.openshift.io/v1/namespaces/tomotag-test03/buildconfigs/gotest/webhooks/<secret>/generic
        AllowEnv:       false
Builds History Limit:
        Successful:     5
        Failed:         5

Build           Status          Duration        Creation Time
gotest-1        complete        1m36s           2021-07-23 12:07:17 +0900 JST

Events: <none>
```

</div></details>


## ImageStream

<details><summary><font color="blue">oc get is/gobuilder -o yaml</font></summary><div>

```yaml
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/image.dockerRepositoryCheck: "2021-07-23T02:47:22Z"
  creationTimestamp: "2021-07-23T02:47:22Z"
  generation: 1
  name: gobuilder
  namespace: tomotag-test03
  resourceVersion: "75007324"
  selfLink: /apis/image.openshift.io/v1/namespaces/tomotag-test03/imagestreams/gobuilder
  uid: 23e8525b-7cce-4853-928e-7f0ff466c3ba
spec:
  lookupPolicy:
    local: false
  tags:
  - annotations: null
    from:
      kind: DockerImage
      name: quay.io/tomotagwork/gobuilder:latest
    generation: 1
    importPolicy: {}
    name: latest
    referencePolicy:
      type: Source
status:
  dockerImageRepository: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gobuilder
  tags:
  - items:
    - created: "2021-07-23T02:47:22Z"
      dockerImageReference: quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
      generation: 1
      image: sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
    tag: latest
```

</div></details>

<details><summary><font color="blue">oc describe is/gobuilder</font></summary><div>

```
Name:                   gobuilder
Namespace:              tomotag-test03
Created:                29 minutes ago
Labels:                 <none>
Annotations:            openshift.io/image.dockerRepositoryCheck=2021-07-23T02:47:22Z
Image Repository:       image-registry.openshift-image-registry.svc:5000/tomotag-test03/gobuilder
Image Lookup:           local=false
Unique Images:          1
Tags:                   1

latest
  tagged from quay.io/tomotagwork/gobuilder:latest

  * quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
      29 minutes ago
```

</div></details>

<details><summary><font color="blue">oc get is/gotest -o yaml</font></summary><div>

```yaml
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: "2021-07-23T03:07:16Z"
  generation: 1
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
  managedFields:
  - apiVersion: image.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/generated-by: {}
        f:labels:
          .: {}
          f:app: {}
          f:app.kubernetes.io/component: {}
          f:app.kubernetes.io/instance: {}
    manager: oc
    operation: Update
    time: "2021-07-23T03:07:16Z"
  name: gotest
  namespace: tomotag-test03
  resourceVersion: "75012225"
  selfLink: /apis/image.openshift.io/v1/namespaces/tomotag-test03/imagestreams/gotest
  uid: f66c9005-71d4-41d3-82b6-d138e9036162
spec:
  lookupPolicy:
    local: false
status:
  dockerImageRepository: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest
  tags:
  - items:
    - created: "2021-07-23T03:08:53Z"
      dockerImageReference: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
      generation: 1
      image: sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    tag: latest
```

</div></details>

<details><summary><font color="blue">oc describe is/gotest</font></summary><div>

```
Name:                   gotest
Namespace:              tomotag-test03
Created:                11 minutes ago
Labels:                 app=gotest
                        app.kubernetes.io/component=gotest
                        app.kubernetes.io/instance=gotest
Annotations:            openshift.io/generated-by=OpenShiftNewApp
Image Repository:       image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest
Image Lookup:           local=false
Unique Images:          1
Tags:                   1

latest
  no spec tag

  * image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
      9 minutes ago
```

</div></details>

## ImageStreamTag

<details><summary><font color="blue">oc get istag/gobuilder:latest -o yaml</font></summary><div>

```yaml
apiVersion: image.openshift.io/v1
generation: 1
image:
  dockerImageLayers:
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
    size: 52190749
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
    size: 8078517
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
    size: 10217855
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
    size: 54478208
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
    size: 71951156
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
    size: 136942435
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
    size: 181
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
    size: 1233
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
    size: 274
  dockerImageManifestMediaType: application/vnd.docker.distribution.manifest.v2+json
  dockerImageMetadata:
    Architecture: amd64
    Config:
      Cmd:
      - /usr/libexec/s2i/usage
      Env:
      - PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - GOLANG_VERSION=1.16.5
      - GOPATH=/go
      ExposedPorts:
        8080/tcp: {}
      Labels:
        io.k8s.description: Platform for building go
        io.k8s.display-name: builder go
        io.openshift.expose-services: 8080:http
        io.openshift.tags: builder,go,golang
        maintainer: Your Name <your@email.com>
      User: "1001"
      WorkingDir: /go
    ContainerConfig: {}
    Created: "2021-07-22T10:05:15Z"
    Id: sha256:3d71b809338e71758372755da2c23a754ff6d50f207cae6addbdd57b9db00798
    Size: 333868161
    apiVersion: "1.0"
    kind: DockerImage
  dockerImageMetadataVersion: "1.0"
  dockerImageReference: quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
  metadata:
    annotations:
      image.openshift.io/dockerLayersOrder: ascending
    creationTimestamp: "2021-07-23T02:47:22Z"
    name: sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
    resourceVersion: "75007323"
    uid: ac97906e-28ab-4363-8c24-beb946b50aad
kind: ImageStreamTag
lookupPolicy:
  local: false
metadata:
  creationTimestamp: "2021-07-23T02:47:22Z"
  name: gobuilder:latest
  namespace: tomotag-test03
  resourceVersion: "75007324"
  selfLink: /apis/image.openshift.io/v1/namespaces/tomotag-test03/imagestreamtags/gobuilder:latest
  uid: 23e8525b-7cce-4853-928e-7f0ff466c3ba
tag:
  annotations: null
  from:
    kind: DockerImage
    name: quay.io/tomotagwork/gobuilder:latest
  generation: 1
  importPolicy: {}
  name: latest
  referencePolicy:
    type: Source
```

</div></details>

<details><summary><font color="blue">oc describe istag/gobuilder:latest</font></summary><div>

```
Image Name:     sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Docker Image:   quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Name:           sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
Created:        32 minutes ago
Annotations:    image.openshift.io/dockerLayersOrder=ascending
Image Size:     333.9MB in 9 layers
Layers:         52.19MB sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
                8.079MB sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
                10.22MB sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
                54.48MB sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
                71.95MB sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
                136.9MB sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
                181B    sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
                1.233kB sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
                274B    sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
Image Created:  17 hours ago
Author:         <none>
Arch:           amd64
Command:        /usr/libexec/s2i/usage
Working Dir:    /go
User:           1001
Exposes Ports:  8080/tcp
Docker Labels:  io.k8s.description=Platform for building go
                io.k8s.display-name=builder go
                io.openshift.expose-services=8080:http
                io.openshift.tags=builder,go,golang
                maintainer=Your Name <your@email.com>
Environment:    PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                GOLANG_VERSION=1.16.5
                GOPATH=/go
```

</div></details>

<details><summary><font color="blue">oc get istag/gotest:latest -o yaml</font></summary><div>

```yaml
apiVersion: image.openshift.io/v1
generation: 1
image:
  dockerImageLayers:
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
    size: 52190749
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
    size: 8078517
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
    size: 10217855
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
    size: 54478208
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
    size: 71951156
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
    size: 136942435
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
    size: 181
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
    size: 1233
  - mediaType: application/vnd.docker.image.rootfs.diff.tar
    name: sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
    size: 274
  - mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
    name: sha256:fb0108444aec71b3574f50a7ac7f500e98f0bb6e1207969b88bbbbd4a5fbc337
    size: 3369398
  dockerImageManifestMediaType: application/vnd.docker.distribution.manifest.v2+json
  dockerImageMetadata:
    Architecture: amd64
    Config:
      Cmd:
      - /bin/sh
      - -c
      - /usr/libexec/s2i/run
      Env:
      - PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - GOLANG_VERSION=1.16.5
      - GOPATH=/go
      - OPENSHIFT_BUILD_NAME=gotest-1
      - OPENSHIFT_BUILD_NAMESPACE=tomotag-test03
      - OPENSHIFT_BUILD_SOURCE=https://github.com/tomotagwork/openshift-test
      - OPENSHIFT_BUILD_REFERENCE=main
      - OPENSHIFT_BUILD_COMMIT=8b7b10f5111363d494a26911856303a90d32d701
      ExposedPorts:
        8080/tcp: {}
      Hostname: 7309088bd49c
      Labels:
        io.k8s.description: Platform for building go
        io.k8s.display-name: builder go
        io.openshift.build.commit.author: Tomohiro Taguchi <tomotagwork@gmail.com>
        io.openshift.build.commit.date: Fri Jul 23 11:04:34 2021 +0900
        io.openshift.build.commit.id: 8b7b10f5111363d494a26911856303a90d32d701
        io.openshift.build.commit.message: add s2i source
        io.openshift.build.commit.ref: main
        io.openshift.build.image: quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
        io.openshift.build.source-context-dir: gotest_s2i_src
        io.openshift.expose-services: 8080:http
        io.openshift.tags: builder,go,golang
        maintainer: Your Name <your@email.com>
      User: "1001"
      WorkingDir: /go
    Container: 728d021d349f977c8a2ecfce5a81e6a52cb573658a61b0de1ee0d039db6fb10d
    ContainerConfig:
      Cmd:
      - /bin/sh
      - -c
      - /usr/libexec/s2i/run
      Env:
      - PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - GOLANG_VERSION=1.16.5
      - GOPATH=/go
      - OPENSHIFT_BUILD_NAME=gotest-1
      - OPENSHIFT_BUILD_NAMESPACE=tomotag-test03
      - OPENSHIFT_BUILD_SOURCE=https://github.com/tomotagwork/openshift-test
      - OPENSHIFT_BUILD_REFERENCE=main
      - OPENSHIFT_BUILD_COMMIT=8b7b10f5111363d494a26911856303a90d32d701
      ExposedPorts:
        8080/tcp: {}
      Hostname: 7309088bd49c
      Labels:
        io.k8s.description: Platform for building go
        io.k8s.display-name: builder go
        io.openshift.build.commit.author: Tomohiro Taguchi <tomotagwork@gmail.com>
        io.openshift.build.commit.date: Fri Jul 23 11:04:34 2021 +0900
        io.openshift.build.commit.id: 8b7b10f5111363d494a26911856303a90d32d701
        io.openshift.build.commit.message: add s2i source
        io.openshift.build.commit.ref: main
        io.openshift.build.image: quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
        io.openshift.build.source-context-dir: gotest_s2i_src
        io.openshift.expose-services: 8080:http
        io.openshift.tags: builder,go,golang
        maintainer: Your Name <your@email.com>
      User: "1001"
      WorkingDir: /go
    Created: "2021-07-23T03:08:44Z"
    Id: sha256:77153729a12350f3304698ac3f51e2306a4ae88bdfd90c8d25a736ea1e99009f
    Parent: sha256:3d71b809338e71758372755da2c23a754ff6d50f207cae6addbdd57b9db00798
    Size: 337241996
    apiVersion: "1.0"
    kind: DockerImage
  dockerImageMetadataVersion: "1.0"
  dockerImageReference: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
  metadata:
    annotations:
      image.openshift.io/dockerLayersOrder: ascending
      image.openshift.io/manifestBlobStored: "true"
      openshift.io/image.managed: "true"
    creationTimestamp: "2021-07-23T03:08:53Z"
    name: sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    resourceVersion: "75012224"
    uid: 557710b8-0836-4eab-9d94-4d4d06d72750
kind: ImageStreamTag
lookupPolicy:
  local: false
metadata:
  creationTimestamp: "2021-07-23T03:08:53Z"
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
  name: gotest:latest
  namespace: tomotag-test03
  resourceVersion: "75012225"
  selfLink: /apis/image.openshift.io/v1/namespaces/tomotag-test03/imagestreamtags/gotest:latest
  uid: f66c9005-71d4-41d3-82b6-d138e9036162
tag: null
```

</div></details>

<details><summary><font color="blue">oc describe istag/gotest:latest</font></summary><div>

```
Image Name:     sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
Docker Image:   image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
Name:           sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
Created:        12 minutes ago
Annotations:    image.openshift.io/dockerLayersOrder=ascending
                image.openshift.io/manifestBlobStored=true
                openshift.io/image.managed=true
Image Size:     337.2MB in 10 layers
Layers:         52.19MB sha256:47528640bafc58742142cfa0e153cba4b8d266af54e906436351bd6a49d7e5ed
                8.079MB sha256:b0141febd267c2a990df3786ac8fb691d65b7fa028ef81079b7e4bd5a6b993e3
                10.22MB sha256:4e1fdd77bbac6bfaf67ff8c1e074d31a98e1f8e80bdf7dd4815483b405277d57
                54.48MB sha256:16b46970de2a55311c713efea5927bd9339f3616e38c6158852b1ca9bae63ee5
                71.95MB sha256:236e29628a836a6fdf6227ed8ace133adb2b81880c910d5b89a01be6a7cbab58
                136.9MB sha256:7e4e360464de08d89aa1aed4418a5668254d8a5a23cea924cc58f44b94e64664
                181B    sha256:992584736a55339d46bad944a150f8c5785136cf2301dc80b46750ce95a6cb27
                1.233kB sha256:08aa47fa729ce702aac3d7533e47dd047ca6c04f1c6e70e328e2bef86c75071e
                274B    sha256:5af2525b506dd32e959275110b45f45462af1fb4c8edc5abc6820e83620651fd
                3.369MB sha256:fb0108444aec71b3574f50a7ac7f500e98f0bb6e1207969b88bbbbd4a5fbc337
Image Created:  12 minutes ago
Author:         <none>
Arch:           amd64
Command:        /bin/sh -c /usr/libexec/s2i/run
Working Dir:    /go
User:           1001
Exposes Ports:  8080/tcp
Docker Labels:  io.k8s.description=Platform for building go
                io.k8s.display-name=builder go
                io.openshift.build.commit.author=Tomohiro Taguchi <tomotagwork@gmail.com>
                io.openshift.build.commit.date=Fri Jul 23 11:04:34 2021 +0900
                io.openshift.build.commit.id=8b7b10f5111363d494a26911856303a90d32d701
                io.openshift.build.commit.message=add s2i source
                io.openshift.build.commit.ref=main
                io.openshift.build.image=quay.io/tomotagwork/gobuilder@sha256:4a5bc168c7d044e0ff83841ff2725eafbbd141a74446bc4044101bf13db6c5d6
                io.openshift.build.source-context-dir=gotest_s2i_src
                io.openshift.expose-services=8080:http
                io.openshift.tags=builder,go,golang
                maintainer=Your Name <your@email.com>
Environment:    PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                GOLANG_VERSION=1.16.5
                GOPATH=/go
                OPENSHIFT_BUILD_NAME=gotest-1
                OPENSHIFT_BUILD_NAMESPACE=tomotag-test03
                OPENSHIFT_BUILD_SOURCE=https://github.com/tomotagwork/openshift-test
                OPENSHIFT_BUILD_REFERENCE=main
                OPENSHIFT_BUILD_COMMIT=8b7b10f5111363d494a26911856303a90d32d701
```

</div></details>

## DeploymentConfig

<details><summary><font color="blue">oc get dc/gotest -o yaml</font></summary><div>

```yaml
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: "2021-07-23T03:07:17Z"
  generation: 2
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
  managedFields:
  - apiVersion: apps.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/generated-by: {}
        f:labels:
          .: {}
          f:app: {}
          f:app.kubernetes.io/component: {}
          f:app.kubernetes.io/instance: {}
      f:spec:
        f:replicas: {}
        f:selector:
          .: {}
          f:deploymentconfig: {}
        f:strategy:
          f:activeDeadlineSeconds: {}
          f:rollingParams:
            .: {}
            f:intervalSeconds: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
            f:timeoutSeconds: {}
            f:updatePeriodSeconds: {}
          f:type: {}
        f:template:
          .: {}
          f:metadata:
            .: {}
            f:annotations:
              .: {}
              f:openshift.io/generated-by: {}
            f:creationTimestamp: {}
            f:labels:
              .: {}
              f:deploymentconfig: {}
          f:spec:
            .: {}
            f:containers:
              .: {}
              k:{"name":"gotest"}:
                .: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":8080,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:protocol: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: oc
    operation: Update
    time: "2021-07-23T03:07:17Z"
  - apiVersion: apps.openshift.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:template:
          f:spec:
            f:containers:
              k:{"name":"gotest"}:
                f:image: {}
        f:triggers: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:details:
          .: {}
          f:causes: {}
          f:message: {}
        f:latestVersion: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:unavailableReplicas: {}
        f:updatedReplicas: {}
    manager: openshift-controller-manager
    operation: Update
    time: "2021-07-23T03:09:04Z"
  name: gotest
  namespace: tomotag-test03
  resourceVersion: "75012329"
  selfLink: /apis/apps.openshift.io/v1/namespaces/tomotag-test03/deploymentconfigs/gotest
  uid: cb4d5c5d-e7cd-48e8-a653-2d9f27c3af54
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    deploymentconfig: gotest
  strategy:
    activeDeadlineSeconds: 21600
    resources: {}
    rollingParams:
      intervalSeconds: 1
      maxSurge: 25%
      maxUnavailable: 25%
      timeoutSeconds: 600
      updatePeriodSeconds: 1
    type: Rolling
  template:
    metadata:
      annotations:
        openshift.io/generated-by: OpenShiftNewApp
      creationTimestamp: null
      labels:
        deploymentconfig: gotest
    spec:
      containers:
      - image: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
        imagePullPolicy: Always
        name: gotest
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  test: false
  triggers:
  - type: ConfigChange
  - imageChangeParams:
      automatic: true
      containerNames:
      - gotest
      from:
        kind: ImageStreamTag
        name: gotest:latest
        namespace: tomotag-test03
      lastTriggeredImage: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    type: ImageChange
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2021-07-23T03:09:03Z"
    lastUpdateTime: "2021-07-23T03:09:03Z"
    message: Deployment config has minimum availability.
    status: "True"
    type: Available
  - lastTransitionTime: "2021-07-23T03:08:58Z"
    lastUpdateTime: "2021-07-23T03:09:04Z"
    message: replication controller "gotest-1" successfully rolled out
    reason: NewReplicationControllerAvailable
    status: "True"
    type: Progressing
  details:
    causes:
    - type: ConfigChange
    message: config change
  latestVersion: 1
  observedGeneration: 2
  readyReplicas: 1
  replicas: 1
  unavailableReplicas: 0
  updatedReplicas: 1
```

</div></details>

<details><summary><font color="blue">oc describe dc/gotest</font></summary><div>

```
Name:           gotest
Namespace:      tomotag-test03
Created:        14 minutes ago
Labels:         app=gotest
                app.kubernetes.io/component=gotest
                app.kubernetes.io/instance=gotest
Annotations:    openshift.io/generated-by=OpenShiftNewApp
Latest Version: 1
Selector:       deploymentconfig=gotest
Replicas:       1
Triggers:       Config, Image(gotest@latest, auto=true)
Strategy:       Rolling
Template:
Pod Template:
  Labels:       deploymentconfig=gotest
  Annotations:  openshift.io/generated-by: OpenShiftNewApp
  Containers:
   gotest:
    Image:              image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    Port:               8080/TCP
    Host Port:          0/TCP
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>

Deployment #1 (latest):
        Name:           gotest-1
        Created:        13 minutes ago
        Status:         Complete
        Replicas:       1 current / 1 desired
        Selector:       deployment=gotest-1,deploymentconfig=gotest
        Labels:         app.kubernetes.io/component=gotest,app.kubernetes.io/instance=gotest,app=gotest,openshift.io/deployment-config.name=gotest
        Pods Status:    1 Running / 0 Waiting / 0 Succeeded / 0 Failed

Events:
  Type          Reason                  Age     From                            Message
  ----          ------                  ----    ----                            -------
  Normal        DeploymentCreated       13m     deploymentconfig-controller     Created new replication controller "gotest-1" for version 1

```

</div></details>

## ReplicationController

<details><summary><font color="blue">oc get rc/gotest-1 -o yaml</font></summary><div>

```yaml
apiVersion: v1
kind: ReplicationController
metadata:
  annotations:
    openshift.io/deployer-pod.completed-at: 2021-07-23 03:09:03 +0000 UTC
    openshift.io/deployer-pod.created-at: 2021-07-23 03:08:54 +0000 UTC
    openshift.io/deployer-pod.name: gotest-1-deploy
    openshift.io/deployment-config.latest-version: "1"
    openshift.io/deployment-config.name: gotest
    openshift.io/deployment.phase: Complete
    openshift.io/deployment.replicas: "1"
    openshift.io/deployment.status-reason: config change
    openshift.io/encoded-deployment-config: |
      {"kind":"DeploymentConfig","apiVersion":"apps.openshift.io/v1","metadata":{"name":"gotest","namespace":"tomotag-test03","selfLink":"/apis/apps.openshift.io/v1/namespaces/tomotag-test03/deploymentconfigs/gotest","uid":"cb4d5c5d-e7cd-48e8-a653-2d9f27c3af54","resourceVersion":"75012230","generation":2,"creationTimestamp":"2021-07-23T03:07:17Z","labels":{"app":"gotest","app.kubernetes.io/component":"gotest","app.kubernetes.io/instance":"gotest"},"annotations":{"openshift.io/generated-by":"OpenShiftNewApp"},"managedFields":[{"manager":"oc","operation":"Update","apiVersion":"apps.openshift.io/v1","time":"2021-07-23T03:07:17Z","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:openshift.io/generated-by":{}},"f:labels":{".":{},"f:app":{},"f:app.kubernetes.io/component":{},"f:app.kubernetes.io/instance":{}}},"f:spec":{"f:replicas":{},"f:selector":{".":{},"f:deploymentconfig":{}},"f:strategy":{"f:activeDeadlineSeconds":{},"f:rollingParams":{".":{},"f:intervalSeconds":{},"f:maxSurge":{},"f:maxUnavailable":{},"f:timeoutSeconds":{},"f:updatePeriodSeconds":{}},"f:type":{}},"f:template":{".":{},"f:metadata":{".":{},"f:annotations":{".":{},"f:openshift.io/generated-by":{}},"f:creationTimestamp":{},"f:labels":{".":{},"f:deploymentconfig":{}}},"f:spec":{".":{},"f:containers":{".":{},"k:{\"name\":\"gotest\"}":{".":{},"f:imagePullPolicy":{},"f:name":{},"f:ports":{".":{},"k:{\"containerPort\":8080,\"protocol\":\"TCP\"}":{".":{},"f:containerPort":{},"f:protocol":{}}},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}}}},{"manager":"openshift-controller-manager","operation":"Update","apiVersion":"apps.openshift.io/v1","time":"2021-07-23T03:08:54Z","fieldsType":"FieldsV1","fieldsV1":{"f:spec":{"f:template":{"f:spec":{"f:containers":{"k:{\"name\":\"gotest\"}":{"f:image":{}}}}},"f:triggers":{}},"f:status":{"f:conditions":{".":{},"k:{\"type\":\"Available\"}":{".":{},"f:lastTransitionTime":{},"f:lastUpdateTime":{},"f:message":{},"f:status":{},"f:type":{}}},"f:details":{".":{},"f:causes":{},"f:message":{}},"f:latestVersion":{},"f:observedGeneration":{}}}}]},"spec":{"strategy":{"type":"Rolling","rollingParams":{"updatePeriodSeconds":1,"intervalSeconds":1,"timeoutSeconds":600,"maxUnavailable":"25%","maxSurge":"25%"},"resources":{},"activeDeadlineSeconds":21600},"triggers":[{"type":"ConfigChange"},{"type":"ImageChange","imageChangeParams":{"automatic":true,"containerNames":["gotest"],"from":{"kind":"ImageStreamTag","namespace":"tomotag-test03","name":"gotest:latest"},"lastTriggeredImage":"image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f"}}],"replicas":1,"revisionHistoryLimit":10,"test":false,"selector":{"deploymentconfig":"gotest"},"template":{"metadata":{"creationTimestamp":null,"labels":{"deploymentconfig":"gotest"},"annotations":{"openshift.io/generated-by":"OpenShiftNewApp"}},"spec":{"containers":[{"name":"gotest","image":"image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f","ports":[{"containerPort":8080,"protocol":"TCP"}],"resources":{},"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"Always"}],"restartPolicy":"Always","terminationGracePeriodSeconds":30,"dnsPolicy":"ClusterFirst","securityContext":{},"schedulerName":"default-scheduler"}}},"status":{"latestVersion":1,"observedGeneration":1,"replicas":0,"updatedReplicas":0,"availableReplicas":0,"unavailableReplicas":0,"details":{"message":"config change","causes":[{"type":"ConfigChange"}]},"conditions":[{"type":"Available","status":"False","lastUpdateTime":"2021-07-23T03:07:17Z","lastTransitionTime":"2021-07-23T03:07:17Z","message":"Deployment config does not have minimum availability."}]}}
  creationTimestamp: "2021-07-23T03:08:54Z"
  generation: 2
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
    openshift.io/deployment-config.name: gotest
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:availableReplicas: {}
        f:fullyLabeledReplicas: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
    manager: kube-controller-manager
    operation: Update
    time: "2021-07-23T03:09:03Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/deployer-pod.completed-at: {}
          f:openshift.io/deployer-pod.created-at: {}
          f:openshift.io/deployer-pod.name: {}
          f:openshift.io/deployment-config.latest-version: {}
          f:openshift.io/deployment-config.name: {}
          f:openshift.io/deployment.phase: {}
          f:openshift.io/deployment.replicas: {}
          f:openshift.io/deployment.status-reason: {}
          f:openshift.io/encoded-deployment-config: {}
        f:labels:
          .: {}
          f:app: {}
          f:app.kubernetes.io/component: {}
          f:app.kubernetes.io/instance: {}
          f:openshift.io/deployment-config.name: {}
        f:ownerReferences:
          .: {}
          k:{"uid":"cb4d5c5d-e7cd-48e8-a653-2d9f27c3af54"}:
            .: {}
            f:apiVersion: {}
            f:blockOwnerDeletion: {}
            f:controller: {}
            f:kind: {}
            f:name: {}
            f:uid: {}
      f:spec:
        f:replicas: {}
        f:selector:
          .: {}
          f:deployment: {}
          f:deploymentconfig: {}
        f:template:
          .: {}
          f:metadata:
            .: {}
            f:annotations:
              .: {}
              f:openshift.io/deployment-config.latest-version: {}
              f:openshift.io/deployment-config.name: {}
              f:openshift.io/deployment.name: {}
              f:openshift.io/generated-by: {}
            f:creationTimestamp: {}
            f:labels:
              .: {}
              f:deployment: {}
              f:deploymentconfig: {}
          f:spec:
            .: {}
            f:containers:
              .: {}
              k:{"name":"gotest"}:
                .: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":8080,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:protocol: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: openshift-controller-manager
    operation: Update
    time: "2021-07-23T03:09:04Z"
  name: gotest-1
  namespace: tomotag-test03
  ownerReferences:
  - apiVersion: apps.openshift.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: DeploymentConfig
    name: gotest
    uid: cb4d5c5d-e7cd-48e8-a653-2d9f27c3af54
  resourceVersion: "75012328"
  selfLink: /api/v1/namespaces/tomotag-test03/replicationcontrollers/gotest-1
  uid: 3ea1f1ab-1d37-4b9f-a46b-7d5af6920b86
spec:
  replicas: 1
  selector:
    deployment: gotest-1
    deploymentconfig: gotest
  template:
    metadata:
      annotations:
        openshift.io/deployment-config.latest-version: "1"
        openshift.io/deployment-config.name: gotest
        openshift.io/deployment.name: gotest-1
        openshift.io/generated-by: OpenShiftNewApp
      creationTimestamp: null
      labels:
        deployment: gotest-1
        deploymentconfig: gotest
    spec:
      containers:
      - image: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
        imagePullPolicy: Always
        name: gotest
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  fullyLabeledReplicas: 1
  observedGeneration: 2
  readyReplicas: 1
  replicas: 1
```

</div></details>

<details><summary><font color="blue">oc describe rc/gotest-1</font></summary><div>

```
Name:         gotest-1
Namespace:    tomotag-test03
Selector:     deployment=gotest-1,deploymentconfig=gotest
Labels:       app=gotest
              app.kubernetes.io/component=gotest
              app.kubernetes.io/instance=gotest
              openshift.io/deployment-config.name=gotest
Annotations:  openshift.io/deployer-pod.completed-at: 2021-07-23 03:09:03 +0000 UTC
              openshift.io/deployer-pod.created-at: 2021-07-23 03:08:54 +0000 UTC
              openshift.io/deployer-pod.name: gotest-1-deploy
              openshift.io/deployment-config.latest-version: 1
              openshift.io/deployment-config.name: gotest
              openshift.io/deployment.phase: Complete
              openshift.io/deployment.replicas: 1
              openshift.io/deployment.status-reason: config change
              openshift.io/encoded-deployment-config:
                {"kind":"DeploymentConfig","apiVersion":"apps.openshift.io/v1","metadata":{"name":"gotest","namespace":"tomotag-test03","selfLink":"/apis/...
Replicas:     1 current / 1 desired
Pods Status:  1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:       deployment=gotest-1
                deploymentconfig=gotest
  Annotations:  openshift.io/deployment-config.latest-version: 1
                openshift.io/deployment-config.name: gotest
                openshift.io/deployment.name: gotest-1
                openshift.io/generated-by: OpenShiftNewApp
  Containers:
   gotest:
    Image:        image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                    Message
  ----    ------            ----  ----                    -------
  Normal  SuccessfulCreate  14m   replication-controller  Created pod: gotest-1-dhtgm
```

</div></details>

## Pod

<details><summary><font color="blue">oc get pod/gotest-1-dhtgm -o yaml</font></summary><div>

```yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/podIP: 172.30.xx.xxx/32
    cni.projectcalico.org/podIPs: 172.30.xx.xxx/32
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "k8s-pod-network",
          "ips": [
              "172.30.xx.xxx"
          ],
          "default": true,
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks-status: |-
      [{
          "name": "k8s-pod-network",
          "ips": [
              "172.30.xx.xxx"
          ],
          "default": true,
          "dns": {}
      }]
    openshift.io/deployment-config.latest-version: "1"
    openshift.io/deployment-config.name: gotest
    openshift.io/deployment.name: gotest-1
    openshift.io/generated-by: OpenShiftNewApp
    openshift.io/scc: dbb-scc
  creationTimestamp: "2021-07-23T03:08:57Z"
  generateName: gotest-1-
  labels:
    deployment: gotest-1
    deploymentconfig: gotest
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/deployment-config.latest-version: {}
          f:openshift.io/deployment-config.name: {}
          f:openshift.io/deployment.name: {}
          f:openshift.io/generated-by: {}
        f:generateName: {}
        f:labels:
          .: {}
          f:deployment: {}
          f:deploymentconfig: {}
        f:ownerReferences:
          .: {}
          k:{"uid":"3ea1f1ab-1d37-4b9f-a46b-7d5af6920b86"}:
            .: {}
            f:apiVersion: {}
            f:blockOwnerDeletion: {}
            f:controller: {}
            f:kind: {}
            f:name: {}
            f:uid: {}
      f:spec:
        f:containers:
          k:{"name":"gotest"}:
            .: {}
            f:image: {}
            f:imagePullPolicy: {}
            f:name: {}
            f:ports:
              .: {}
              k:{"containerPort":8080,"protocol":"TCP"}:
                .: {}
                f:containerPort: {}
                f:protocol: {}
            f:resources: {}
            f:terminationMessagePath: {}
            f:terminationMessagePolicy: {}
        f:dnsPolicy: {}
        f:enableServiceLinks: {}
        f:restartPolicy: {}
        f:schedulerName: {}
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kube-controller-manager
    operation: Update
    time: "2021-07-23T03:08:57Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:cni.projectcalico.org/podIP: {}
          f:cni.projectcalico.org/podIPs: {}
    manager: calico
    operation: Update
    time: "2021-07-23T03:08:59Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:k8s.v1.cni.cncf.io/network-status: {}
          f:k8s.v1.cni.cncf.io/networks-status: {}
    manager: multus
    operation: Update
    time: "2021-07-23T03:08:59Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:conditions:
          k:{"type":"ContainersReady"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
          k:{"type":"Initialized"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
          k:{"type":"Ready"}:
            .: {}
            f:lastProbeTime: {}
            f:lastTransitionTime: {}
            f:status: {}
            f:type: {}
        f:containerStatuses: {}
        f:hostIP: {}
        f:phase: {}
        f:podIP: {}
        f:podIPs:
          .: {}
          k:{"ip":"172.30.xx.xxx"}:
            .: {}
            f:ip: {}
        f:startTime: {}
    manager: kubelet
    operation: Update
    time: "2021-07-23T03:09:03Z"
  name: gotest-1-dhtgm
  namespace: tomotag-test03
  ownerReferences:
  - apiVersion: v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicationController
    name: gotest-1
    uid: 3ea1f1ab-1d37-4b9f-a46b-7d5af6920b86
  resourceVersion: "75012317"
  selfLink: /api/v1/namespaces/tomotag-test03/pods/gotest-1-dhtgm
  uid: 6ef38bf2-6605-4b81-b7b7-c73704de1285
spec:
  containers:
  - image: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    imagePullPolicy: Always
    name: gotest
    ports:
    - containerPort: 8080
      protocol: TCP
    resources: {}
    securityContext:
      capabilities:
        drop:
        - KILL
        - MKNOD
        - SETGID
        - SETUID
      runAsUser: 1000640000
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-g6n8l
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  imagePullSecrets:
  - name: default-dockercfg-vptph
  nodeName: 10.129.xxx.xx
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext:
    fsGroup: 1000640000
    seLinuxOptions:
      level: s0:c25,c20
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-g6n8l
    secret:
      defaultMode: 420
      secretName: default-token-g6n8l
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2021-07-23T03:08:57Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2021-07-23T03:09:03Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2021-07-23T03:09:03Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2021-07-23T03:08:57Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: cri-o://2e8f42d0858fbcee01c718f11475e0a64efd89dd501a061985b7774f022dac7e
    image: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    imageID: image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    lastState: {}
    name: gotest
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2021-07-23T03:09:02Z"
  hostIP: 10.129.xxx.xxx
  phase: Running
  podIP: 172.30.xx.xxx
  podIPs:
  - ip: 172.30.xx.xxx
  qosClass: BestEffort
  startTime: "2021-07-23T03:08:57Z"
```

</div></details>

<details><summary><font color="blue">oc describe pod/gotest-1-dhtgm</font></summary><div>

```
Name:         gotest-1-dhtgm
Namespace:    tomotag-test03
Priority:     0
Node:         10.129.xxx.xx/10.129.xxx.xx
Start Time:   Fri, 23 Jul 2021 12:08:57 +0900
Labels:       deployment=gotest-1
              deploymentconfig=gotest
Annotations:  cni.projectcalico.org/podIP: 172.30.xx.xxx/32
              cni.projectcalico.org/podIPs: 172.30.xx.xxx/32
              k8s.v1.cni.cncf.io/network-status:
                [{
                    "name": "k8s-pod-network",
                    "ips": [
                        "172.30.xx.xxx"
                    ],
                    "default": true,
                    "dns": {}
                }]
              k8s.v1.cni.cncf.io/networks-status:
                [{
                    "name": "k8s-pod-network",
                    "ips": [
                        "172.30.xx.xxx"
                    ],
                    "default": true,
                    "dns": {}
                }]
              openshift.io/deployment-config.latest-version: 1
              openshift.io/deployment-config.name: gotest
              openshift.io/deployment.name: gotest-1
              openshift.io/generated-by: OpenShiftNewApp
              openshift.io/scc: dbb-scc
Status:       Running
IP:           172.30.xx.xxx
IPs:
  IP:           172.30.xx.xxx
Controlled By:  ReplicationController/gotest-1
Containers:
  gotest:
    Container ID:   cri-o://2e8f42d0858fbcee01c718f11475e0a64efd89dd501a061985b7774f022dac7e
    Image:          image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    Image ID:       image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 23 Jul 2021 12:09:02 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-g6n8l (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-g6n8l:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-g6n8l
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason          Age   From               Message
  ----    ------          ----  ----               -------
  Normal  Scheduled       15m   default-scheduler  Successfully assigned tomotag-test03/gotest-1-dhtgm to 10.129.xxx.xx
  Normal  AddedInterface  15m   multus             Add eth0 [172.30.xx.xxx/32]
  Normal  Pulling         15m   kubelet            Pulling image "image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f"
  Normal  Pulled          15m   kubelet            Successfully pulled image "image-registry.openshift-image-registry.svc:5000/tomotag-test03/gotest@sha256:6a759cf8b8d4585c6f80bad599c5e52375907cdc1ff2da63fd23f6a425bf4c8f"
  Normal  Created         15m   kubelet            Created container gotest
  Normal  Started         15m   kubelet            Started container gotest
```

</div></details>

## Service

<details><summary><font color="blue">oc get svc/gotest -o yaml</font></summary><div>

```yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: "2021-07-23T03:07:17Z"
  labels:
    app: gotest
    app.kubernetes.io/component: gotest
    app.kubernetes.io/instance: gotest
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/generated-by: {}
        f:labels:
          .: {}
          f:app: {}
          f:app.kubernetes.io/component: {}
          f:app.kubernetes.io/instance: {}
      f:spec:
        f:ports:
          .: {}
          k:{"port":8080,"protocol":"TCP"}:
            .: {}
            f:name: {}
            f:port: {}
            f:protocol: {}
            f:targetPort: {}
        f:selector:
          .: {}
          f:deploymentconfig: {}
        f:sessionAffinity: {}
        f:type: {}
    manager: oc
    operation: Update
    time: "2021-07-23T03:07:17Z"
  name: gotest
  namespace: tomotag-test03
  resourceVersion: "75011824"
  selfLink: /api/v1/namespaces/tomotag-test03/services/gotest
  uid: a434ff37-f387-4291-992b-50603428c243
spec:
  clusterIP: 172.21.xxx.xxx
  ports:
  - name: 8080-tcp
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    deploymentconfig: gotest
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
```

</div></details>

<details><summary><font color="blue">oc describe svc/gotest</font></summary><div>

```
Name:              gotest
Namespace:         tomotag-test03
Labels:            app=gotest
                   app.kubernetes.io/component=gotest
                   app.kubernetes.io/instance=gotest
Annotations:       openshift.io/generated-by: OpenShiftNewApp
Selector:          deploymentconfig=gotest
Type:              ClusterIP
IP:                172.21.xxx.xxx
Port:              8080-tcp  8080/TCP
TargetPort:        8080/TCP
Endpoints:         172.30.xx.xxx:8080
Session Affinity:  None
Events:            <none>
```

</div></details>

# おわりに
ここでは基本的なフローのみを確認していますが、assembleなどのスクリプトをoc new-app時に置き換えたり(カスタムs2iスクリプト)、ビルド後に簡易的なテストをしてNGだった場合にデプロイを取りやめる処理を組み込んだり(post-commitビルドフック)するなど、他にも拡張機能があるようです。なかなか奥が深い...