OpenShiftを無償で簡単に試す手順（Sandbox環境の作成からアプリデプロイまで）

# 前提

[Developer Sandbox for Red Hat OpenShift](https://developers.redhat.com/developer-sandbox)という無償環境を利用してみたので、覚え書きです。
OpenShiftは本来有償のツールですが、Developer Sandboxを利用することで、権限の少なさや環境の保持期限などいくつか制限はあるものの、実際のOpenShiftの操作などを無料で体験することができます。

今回は前半後半に分けて、OpenShiftのSandbox環境を用意する手順と、`oc new-app`コマンドでGitHubリポジトリ上にあるNode.jsアプリを素早く簡単にデプロイしてみる手順をご紹介します。


### おおまかな手順
【前半】Sandbox環境の準備：Red Hat Developer Sandboxにアクセスし、クラスタをセットアップ。
【後半】サンプルNode.jsアプリのデプロイ：GitHub上に公開されているNode.jsアプリをOpenShiftの機能で簡単にデプロイ。


### 環境
* 利用ツール　　　　　　：Developer Sandbox for Red Hat OpenShift
* クラスターバージョン　：4.18.4
* ocバージョン　　　　　：OpenShift v4.18.4 Windows Client
* ocを利用している環境　：Windows 11のコマンドプロンプトから
* 操作　　　　　　　　　：oc(OpenShift CLI)を利用したコマンド操作でできるだけ進めますが、必要な手順は別途、Webコンソールを使用していきます。



# 【前半】Sandbox環境の準備

以下の記事を参考にさせていただきました。基本的に手順はすべて一緒です。画面が少し変化しているものがあったのでスクショ多めでご紹介していきます。

https://qiita.com/c3drive/items/234f4314a3b174c0d940

1. 事前にRedhatアカウントを作成しておく。
1. Sandboxの利用を開始する。以下にアクセスして「無料トライアルを始める」。
[Red Hat OpenShift を無料で使い始める | Red Hat](https://www.redhat.com/ja/technologies/cloud-computing/openshift/get-started)
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/972ad872-d68f-4f4f-b179-e254976ce904.png)
1. その後、遷移した画面の「開発者サンドボックス」内でもう一度「無料トライアルを始める」。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/be976010-5e84-409f-bbd1-ef303284dab5.png)
1. 画面遷移もしくは、以下にアクセスして「Get started」。
[Developer Sandbox | OpenShift AI - OpenShift AI | OpenShift](https://console.redhat.com/openshift/sandbox/)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/ed598791-2db4-4620-853c-eae21a306e7b.png)
1. 画面遷移し、「Got it」。
![op_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/795770a1-a704-4073-b02b-d88c5ad8f805.png)
1. 画面遷移して「OpenShift」を「Launch」し、ログイン。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/3217c041-6fb7-4ba5-ac02-a572673bf9a3.png)
1. Webコンソール画が表示されるので、左上から「⚙管理者向け表示」に切り替え。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/146b75d7-cfcf-471a-b824-a0f7c6e89007.png)
1. 「管理」→「クラスター設定」を開き、自分のOpenShiftクラスタのバージョンを確認。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/b25298b2-c988-41fc-a384-b9953ca1adcc.png)
1. 確認したバージョンに対応するOpenShift CLI (oc)を自分のPCにダウンロードし、パスを通す。Windowsの場合の手順は以下を参考にする。
    * [1.2.11.2. Windows への OpenShift CLI のインストール | RHV へのインストール | OpenShift Container Platform | 4.6 | Red Hat Documentation](https://docs.redhat.com/ja/documentation/openshift_container_platform/4.6/html/installing_on_rhv/cli-installing-cli-on-windows_installing-rhv-customizations)
1. ocが無事に利用できることを確認。現段階ではまだocでログインしていないため警告が出ます。（今回はコマンドプロンプトでocを利用していくため、以降のコマンドは特に記載がない限りコマンドプロンプトから実行します。）
    ```bash:ocが使えるか確認するコマンドと、出力例
    > oc version
    Client Version: 4.18.4
    Kustomize Version: v5.4.2
    error: You must be logged in to the server (Unauthorized)
    ```
1. Webコンソールの右上のほうからログインコマンドをコピー、コマンドプロンプトに貼り付けてログイン。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/16ed9e5a-5b27-47a7-909d-dff88cd64698.png)
    ```bash:ログインコマンドの例と、出力例
    > oc login --token=sha256~ABCD_EFG-1234567890 --server=https://api.rm3.7wse.p1.openshiftapps.com:6443
    Logged into "https://api.rm3.7wse.p1.openshiftapps.com:6443" as "nishiooi" using the token provided.
    
    You have access to the following projects and can switch between them with 'oc project <projectname>':
    
      * nishiooi-dev
        openshift-virtualization-os-images
    
    Using project "nishiooi-dev".
    ```



# 【後半】サンプルNode.jsアプリのデプロイ

:::note info
以下の手順では、コマンド実行後の出力結果なども一緒に載せています。
必要なコマンドだけ簡単に確認したい方は[ocコマンドだけまとめ](###-ocコマンドだけまとめ)を見ていただけると早いです。
:::

Node.jsで動作し、CRUDサンプルアプリケーションをOpenshift上でデプロイします。
こちらのGitHubリポジトリを参考にしています。
[sclorg/nodejs-ex: node.js example](https://github.com/sclorg/nodejs-ex)

本来であれば、アプリのデプロイごとにクラスタ上に新しくプロジェクトを作成した方が運用がすっきりするのですが、Sandbox環境の制約により新規のプロジェクト作成はできません。
今回は最初に自動作成されるプロジェクト（例：`<username>-dev`）上ですべて進めていきます。

1. 念のため今指定しているプロジェクトを確認。
    ```bash
    > oc project
    Using project "nishiooi-dev" on server "https://api.rm3.7wse.p1.openshiftapps.com:6443".
    ```
1. Node.jsアプリの動作に必要なPostgres DBを先にデプロイ。
    ```bash
    > oc new-app -e POSTGRESQL_USER=luke -e POSTGRESQL_PASSWORD=secret -e POSTGRESQL_DATABASE=my_data centos/postgresql-10-centos7 --name=my-database
    --> Found container image ecc4d3f (3 years old) from Docker Hub for "centos/postgresql-10-centos7"
    
        PostgreSQL 10
        -------------
        PostgreSQL is an advanced Object-Relational database management system (DBMS). The image contains the client and s
        erver programs that you'll need to create, run, maintain and access a PostgreSQL DBMS server.
    
        Tags: database, postgresql, postgresql10, rh-postgresql10
    
        * An image stream tag will be created as "my-database:latest" that will track this image
    
    --> Creating resources ...
        imagestream.image.openshift.io "my-database" created
        deployment.apps "my-database" created
        service "my-database" created
    --> Success
        Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
         'oc expose service/my-database'
        Run 'oc status' to view your app.
    ```
1. 作成されたイメージストリーム、デプロイメント、サービス、ポッドそれぞれと、プロジェクト全体の現況を確認。（※`modelmesh-serving`というサービスが表示されていますが、これは環境にデフォルトで用意されているもので、消せない設定になっています。今回やりたいことに干渉しないので気にせずそのままにします。）
    ```bash
    > oc get is,deploy,svc,po
    NAME                                         IMAGE REPOSITORY                                                                                     TAGS     UPDATED
    imagestream.image.openshift.io/my-database   default-route-openshift-image-registry.apps.rm3.7wse.p1.openshiftapps.com/nishiooi-dev/my-database   latest   2 minutes ago
    
    NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-database   1/1     1            1           2m9s
    
    NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                               AGE
    service/modelmesh-serving   ClusterIP   None             <none>        8033/TCP,8008/TCP,8443/TCP,2112/TCP   157m
    service/my-database         ClusterIP   172.30.155.192   <none>        5432/TCP                              2m8s
    
    NAME                               READY   STATUS    RESTARTS   AGE
    pod/my-database-758cf6b9cc-9s64b   1/1     Running   0          2m9s

    
    > oc status
    Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
    In project nishiooi-dev on server https://api.rm3.7wse.p1.openshiftapps.com:6443
    
    svc/modelmesh-serving (headless) ports 8033, 8008, 8443, 2112
    
    svc/my-database - 172.30.155.192:5432
      deployment/my-database deploys istag/my-database:latest
        deployment #2 running for 2 minutes - 1 pod
        deployment #1 deployed 2 minutes ago
    
    
    1 info identified, use 'oc status --suggest' to see details.
    ```
1. Node.jsアプリ本体をデプロイ。
    ```
    > oc new-app nodejs https://github.com/openshift/nodejs-ex --name=nodejs-app
    --> Found image 6061449 (5 months old) in image stream "openshift/nodejs" under tag "20-ubi9" for "nodejs"
    
        Node.js 20
        ----------
        Node.js 20 available as container is a base platform for building and running various Node.js 20 applications and frameworks. Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
    
        Tags: builder, nodejs, nodejs20
    
        * The source repository appears to match: nodejs
        * A source build using source code from https://github.com/openshift/nodejs-ex will be created
          * The resulting image will be pushed to image stream tag "nodejs-app:latest"
          * Use 'oc start-build' to trigger a new build
    
    --> Creating resources ...
        imagestream.image.openshift.io "nodejs-app" created
        buildconfig.build.openshift.io "nodejs-app" created
        deployment.apps "nodejs-app" created
        service "nodejs-app" created
    --> Success
        Build scheduled, use 'oc logs -f buildconfig/nodejs-app' 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/nodejs-app'
        Run 'oc status' to view your app.
    ```
1. 作成されたイメージストリーム、ビルドコンフィグ、デプロイメント、サービス、ポッドそれぞれと、プロジェクト全体の現況を確認。
    ```bash
    > oc get is,bc,deploy,svc,po
    NAME                                         IMAGE REPOSITORY                                                                                     TAGS     UPDATED
    imagestream.image.openshift.io/my-database   default-route-openshift-image-registry.apps.rm3.7wse.p1.openshiftapps.com/nishiooi-dev/my-database   latest   11 minutes ago
    imagestream.image.openshift.io/nodejs-app    default-route-openshift-image-registry.apps.rm3.7wse.p1.openshiftapps.com/nishiooi-dev/nodejs-app    latest   3 minutes ago
    
    NAME                                        TYPE     FROM   LATEST
    buildconfig.build.openshift.io/nodejs-app   Source   Git    1
    
    NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-database   1/1     1            1           11m
    deployment.apps/nodejs-app    1/1     1            1           4m56s
    
    NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                               AGE
    service/modelmesh-serving   ClusterIP   None             <none>        8033/TCP,8008/TCP,8443/TCP,2112/TCP   167m
    service/my-database         ClusterIP   172.30.155.192   <none>        5432/TCP                              11m
    service/nodejs-app          ClusterIP   172.30.100.42    <none>        8080/TCP                              4m56s
    
    NAME                               READY   STATUS      RESTARTS   AGE
    pod/my-database-758cf6b9cc-9s64b   1/1     Running     0          16m
    pod/nodejs-app-1-build             0/1     Completed   0          10m
    pod/nodejs-app-74975b945f-thkt6    1/1     Running     0          8m35s
    
    > oc status
    Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
    In project nishiooi-dev on server https://api.rm3.7wse.p1.openshiftapps.com:6443
    
    svc/modelmesh-serving (headless) ports 8033, 8008, 8443, 2112
    
    svc/my-database - 172.30.155.192:5432
      deployment/my-database deploys istag/my-database:latest
        deployment #2 running for 11 minutes - 1 pod
        deployment #1 deployed 11 minutes ago
    
    svc/nodejs-app - 172.30.100.42:8080
      deployment/nodejs-app deploys istag/nodejs-app:latest <-
        bc/nodejs-app source builds https://github.com/openshift/nodejs-ex on openshift/nodejs:20-ubi9
        deployment #2 running for 3 minutes - 1 pod
        deployment #1 deployed 5 minutes ago
    
    
    2 infos identified, use 'oc status --suggest' to see details.   
    ```
1. `oc status`コマンドの出力に「2 infos identified, use 'oc status --suggest' to see details.」という文が見えるので詳細を確認。どうやらliveness probeがデフォルトで設定されておらず、手動で定義する必要があったようです。
    ```bash
    > oc status --suggest
    Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
    In project nishiooi-dev on server https://api.rm3.7wse.p1.openshiftapps.com:6443
    
    svc/modelmesh-serving (headless) ports 8033, 8008, 8443, 2112
    
    svc/my-database - 172.30.155.192:5432
      deployment/my-database deploys istag/my-database:latest
        deployment #2 running for 23 minutes - 1 pod
        deployment #1 deployed 23 minutes ago
    
    svc/nodejs-app - 172.30.100.42:8080
      deployment/nodejs-app deploys istag/nodejs-app:latest <-
        bc/nodejs-app source builds https://github.com/openshift/nodejs-ex on openshift/nodejs:20-ubi9
        deployment #2 running for 15 minutes - 1 pod
        deployment #1 deployed 16 minutes ago
    
    Info:
      * deployment/my-database has no liveness probe to verify pods are still running.
        try: oc set probe deployment/my-database --liveness ...
      * deployment/nodejs-app has no liveness probe to verify pods are still running.
        try: oc set probe deployment/nodejs-app --liveness ...
    ```
1. liveness probeを設定。
    ```bash
    > oc set probe deployment/my-database --liveness --open-tcp=5432 --initial-delay-seconds=30 --timeout-seconds=3
    > oc set probe deployment/nodejs-app --liveness --get-url=http://:8080/ --initial-delay-seconds=30 --timeout-seconds=3
    ```
1. 設定ができたか確認。
    ```bash
    > oc describe deployment/my-database
    Name:                   my-database
    （略）
    Pod Template:
      Labels:       deployment=my-database
      Annotations:  openshift.io/generated-by: OpenShiftNewApp
      Containers:
       my-database:
        Image:      centos/postgresql-10-centos7@sha256:f826fcb2983eef2c49e9e9a9d9d61ab403254b50cff85a7caa949fd8474fd558
        Port:       5432/TCP
        Host Port:  0/TCP
        Liveness:   tcp-socket :5432 delay=30s timeout=3s period=10s #success=1 #failure=3
    （略）
    
    > oc describe deployment/nodejs-app
    Name:                   nodejs-app
    （略）
    Pod Template:
      Labels:       deployment=nodejs-app
      Annotations:  openshift.io/generated-by: OpenShiftNewApp
      Containers:
       nodejs-app:
        Image:         image-registry.openshift-image-registry.svc:5000/nishiooi-dev/nodejs-app@sha256:ffa6078bf399868860b83e40b8adcef9c80c3b1051a02c7f9b657ba3169b10e0
        Port:          8080/TCP
        Host Port:     0/TCP
        Liveness:      http-get http://:8080/ delay=30s timeout=3s period=10s #success=1 #failure=3
    （略）
    
    > oc status
    Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
    In project nishiooi-dev on server https://api.rm3.7wse.p1.openshiftapps.com:6443
    
    svc/modelmesh-serving (headless) ports 8033, 8008, 8443, 2112
    
    svc/my-database - 172.30.155.192:5432
      deployment/my-database deploys istag/my-database:latest
        deployment #3 running for 3 minutes - 1 pod
        deployment #2 deployed about an hour ago
        deployment #1 deployed about an hour ago
    
    svc/nodejs-app - 172.30.100.42:8080
      deployment/nodejs-app deploys istag/nodejs-app:latest <-
        bc/nodejs-app source builds https://github.com/openshift/nodejs-ex on openshift/nodejs:20-ubi9
        deployment #3 running for 3 minutes - 1 pod
        deployment #2 deployed about an hour ago
        deployment #1 deployed about an hour ago
    
    View details with 'oc describe <resource>/<name>' or list resources with 'oc get all'.
    ```
1. ルートを表示しましたが、存在しません。oc exposeをします。
    ```bash
    > oc get route
    No resources found in nishiooi-dev namespace.
    
    > oc get svc
    NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE
    modelmesh-serving   ClusterIP   None            <none>        8033/TCP,8008/TCP,8443/TCP,2112/TCP   98m
    my-database         ClusterIP   172.30.144.92   <none>        5432/TCP                              23m
    nodejs-app          ClusterIP   172.30.233.24   <none>        8080/TCP                              22m
    
    > oc expose svc/nodejs-app
    route.route.openshift.io/nodejs-app exposed
    ```
1. ルートをもう一度表示して、`HOST/PORT`に表示されているURLからWebアプリにアクセス。今回の例だと`nodejs-app-nishiooi-dev.apps.rm3.7wse.p1.openshiftapps.com`をブラウザのURLに貼り付ける。
    ```bash
    > oc get route
    NAME         HOST/PORT                                                    PATH   SERVICES     PORT       TERMINATION   WILDCARD
    nodejs-app   nodejs-app-nishiooi-dev.apps.rm3.7wse.p1.openshiftapps.com          nodejs-app   8080-tcp                 None
    ```
1. アプリでCRUD操作もできることを確認。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4085200/d83f3c14-820a-41de-884a-a794c2c96392.png)
1. 作成したリソースを削除し、`service/modelmesh-serving`以外全部消えていることを確認。（※本来なら`oc new-app`コマンドで作成されたアプリリソースは`odo app delete <application_name>`コマンドで削除することができます。Sandbox環境ではodoコマンドが使えないので、`oc delete`コマンドでそれぞれ削除しています。）
    ```bash
    > oc delete is/my-database deploy/my-database svc/my-database
    imagestream.image.openshift.io "my-database" deleted
    deployment.apps "my-database" deleted
    service "my-database" deleted
    
    > oc delete is/nodejs-app bc/nodejs-app deploy/nodejs-app svc/nodejs-app route/nodejs-app
    imagestream.image.openshift.io "nodejs-app" deleted
    buildconfig.build.openshift.io "nodejs-app" deleted
    deployment.apps "nodejs-app" deleted
    service "nodejs-app" deleted
    route.route.openshift.io "nodejs-app" deleted
    
    > oc get is,bc,deploy,svc,route,po
    NAME                        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                               AGE
    service/modelmesh-serving   ClusterIP   None         <none>        8033/TCP,8008/TCP,8443/TCP,2112/TCP   131m
    ```



# あとがき

今回はOpenshiftのSandbox環境を立ち上げ、`oc new-app <GitHubのURL>`コマンドを使って素早くアプリがデプロイできることを試しました。

下記に実際のocコマンドだけをまとめたので、細かいエラーなどは気にせずとにかくぱぱっと進めてみたいという方はこちらをご確認ください。


### ocコマンドだけまとめ
```bash
# ログイン
> oc login --token=sha256~XXX --server=https://api.rm3.7wse.p1.openshiftapps.com:6443

# デプロイと、必要な設定の追加
> oc new-app -e POSTGRESQL_USER=luke -e POSTGRESQL_PASSWORD=secret -e POSTGRESQL_DATABASE=my_data centos/postgresql-10-centos7 --name=my-database
> oc new-app nodejs https://github.com/openshift/nodejs-ex --name=nodejs-app
> oc set probe deployment/my-database --liveness --open-tcp=5432 --initial-delay-seconds=30 --timeout-seconds=3
> oc set probe deployment/nodejs-app --liveness --get-url=http://:8080/ --initial-delay-seconds=30 --timeout-seconds=3

# ルートの確認
> oc get route

# デプロイしたリソースを削除
> oc delete is/my-database deploy/my-database svc/my-database
> oc delete is/nodejs-app bc/nodejs-app deploy/nodejs-app svc/nodejs-app route/nodejs-app
> oc get is,bc,deploy,svc,route,po
```


### パイプラインについて

本当は今回、アプリに対してパイプラインを構築し、Gitリポジトリ内に変更があると自動でそれが反映される、、、というようなことも確認したかったのですが、Sandbox環境の制約でパイプラインがうまく構築できなかったので見送りとしました。

もし気になる方は以下▼を見ていただけると嬉しいです！

<details><summary>Pipelineの内容</summary>

今回構築したかったパイプラインは以下のようなTask構成を予定していました。

> `git-clone` → `s2i` or `buidah` → `openshift-client`

参考にしたページはこちらです。
[openshift/pipelines-tutorial: A step-by-step tutorial showing OpenShift Pipelines](https://github.com/openshift/pipelines-tutorial)

結論から言うと、`s2i`と`buidah`のタスクがどっちも、権限が足りずできませんでした。

1. まず`s2i`タスクを使ったパイプラインを実行しましたが、エラーが出て、buildタスクの途中で失敗していました。cloneタスクは無事に成功したようでした。
1. 調べているうちに`s2i`タスクはサービスアカウントに特権コンテナの実行を許可する必要があるらしいことがわかりました。
[s2i - Tekton Hub](https://hub.tekton.dev/tekton/Task/s2i/0.3) より
    > If you are running on OpenShift, you also need to allow the service account to run privileged containers because OpenShift does not allow containers run as privileged containers by default unless explicitly configured, due to security considerations.（OpenShift 上で実行している場合は、セキュリティ上の理由から、明示的に構成しない限り、OpenShift ではデフォルトでコンテナーを特権コンテナーとして実行できないため、サービスアカウントに特権コンテナーの実行を許可する必要があります。）
1. サービスアカウントを作成し、権限を付与しようとしましたが、「`Error from server (Forbidden): clusterrolebindings.rbac.authorization.k8s.io "system:openshift:scc:privileged" is forbidden: User "nishiooi" cannot get resource "clusterrolebindings" in API group "rbac.authorization.k8s.io" at the cluster scope`」というエラーが出て、Sandbox環境の権限上の制約がある以上、どうしても特権コンテナの実行許可は出せなさそうだとわかりました。
1. また調べていると、`buildah`タスクは特に特権コンテナの言及がなかったので、`buildah`に切り替えてpipelineを構築してみました。
[buildah - Tekton Hub](https://hub.tekton.dev/tekton/Task/buildah/0.9)
1. `buildah`タスクでも`s2i`タスクと同様のエラーが出てしまいうまく解決できず、今回は諦めることにしました。
</details>

またいつか挑戦してみたいと思います。
ここまでご覧いただきありがとうございました！