Kabaneroを使ったアプリケーションの開発フローを確認してみた。




#はじめに
勉強用にKabaneroを使ったアプリケーションの開発フロー(ローカル環境はDocker、本番環境はOpenShift)を作りながら動作確認した時の内容をまとめてみました。

#Kabaneroとは
Kabaneroは、マイクロサービスベースのフレームワークで、開発者、アーキテクト、および運用チームがより迅速に連携できるしくみを作るIBM発のOSSのプロジェクトです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/4f96753c-2d62-861d-0c3f-15e4d333c4a3.png)
Kabaneroは IBM Cloud Pak for ApplicationsにAccelerator for Teamsという名称で同梱され主要な機能になっています。
Kabanero がアップストリームプロジェクトで　Kabanero → Cloud Pak for Applications(Accelerator for Teams)の順番でリリースされます。

# Appsody

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/9f75dd2f-ead0-f10c-08bd-68a9d83885a1.png)

KabaneroのアンブレラプロジェクトであるappsodyがDockerの開発ライフサイクルを抽象化しています。
そのため、開発者はdockerのコマンドやDockerfileなど知らなくても開発することができます。

例えば、

- appsody cliコマンドを使ってDockerを使ったローカル環境での開発からKubernetes、OpenShiftへのデプロイまで制御します。
- stackというNode.js、Eclipse Microprofile、Quarkus、Spring Boot などのオープン・ソースのランタイムとフレームワークに対応する事前構成されたテンプレート(ベースコンテナイメージはRHEL8などのUBIイメージ)用意されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/a53738b2-d078-da6e-4a10-c3a472697657.png)

# Kabaneroを使った開発者のワークフロー

では、Kabaneroを使うと開発者のワークフローはどのように変わるのでしょうか
フロー図に沿って、手順を確認していきたいと思います。

- 前提
 - appsodyがインストールされていること
 - ローカル環境にDockerがインストールされていること
 - (本番環境のリリース用）OpenShiftに Kabaneroがインストールされていること

## Appsody Hubから　stackの一覧を取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/1497a97e-d1d8-5024-f806-751949e45a84.png)

開発者のJaneは　appsody listコマンドを使用して、利用できる stackの一覧を取得します。

```console
appsody list 

REPO    	ID                            	VERSION  	TEMPLATES               	DESCRIPTION
kabanero	java-microprofile [Deprecated]	0.2.27   	*default                	Eclipse MicroProfile on Open Liberty & OpenJ9 using Maven
kabanero	java-openliberty              	0.2.3    	*default                	Open Liberty & OpenJ9 using Maven
kabanero	java-spring-boot2             	0.3.29   	*default, kafka, kotlin 	Spring Boot using OpenJ9 and Maven
kabanero	nodejs                        	0.3.6    	*simple                 	Runtime for Node.js applications
kabanero	nodejs-express                	0.4.8    	kafka, scaffold, *simple	Express web framework for Node.js
```

REPO列がリポジトリ名、IDが stack名、TEMPLATESはアプリケーションのソースコードのテンプレート名です。

## appsodyのプロジェクトの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/8eda5b7f-9be6-566b-a73d-83dea8ea5a87.png)

appsody listコマンドで出力されたstackの中から、今回は java-openliberty stackを使って開発したいと思います。

まず、プロジェクトの保存先のディレクトリを作成します。

```console
mkdir sample-application
cd sample-application
```

そして、appsody init "stack名"を実行して、開発環境を作成します。

```console
# appsody init kabanero/java-openliberty
Checking stack requirements...
Docker requirements met
Appsody requirements met
Running appsody init...
Downloading java-openliberty template project from https://github.com/appsody/stacks/releases/download/java-openliberty-v0.2.12/incubator.java-openlibert                                                       y.v0.2.12.templates.default.tar.gz
Download complete. Extracting files from /root/sample-application/java-openliberty.tar.gz
Setting up the development environment
Your Appsody project name has been set to sample-application
Pulling docker image docker.io/appsody/java-openliberty:0.2
Running command: docker pull docker.io/appsody/java-openliberty:0.2
0.2: Pulling from appsody/java-openliberty
ee2244abc66f: Pulling fs layer
befb03b11956: Pulling fs layer
4d3fb84d4d60: Pulling fs layer
d0aba8033c85: Pull complete
e7e883ba65bb: Pull complete
Digest: sha256:4dff3ca3d27b910b8dacf84895f5763d96df9671b7bbd5694ae14b4624d47dbd
Status: Downloaded newer image for appsody/java-openliberty:0.2
docker.io/appsody/java-openliberty:0.2
[Warning] The stack image does not contain APPSODY_PROJECT_DIR. Using /project
Running command: docker run --rm --entrypoint /bin/bash docker.io/appsody/java-openliberty:0.2 -c "find /project -type f -name .appsody-init.sh"
Extracting project from development environment
[Warning] The stack image does not contain APPSODY_PROJECT_DIR. Using /project
Running command: docker create --name sample-application-extract -v /root/.m2/repository:/mvn/repository -v /root/sample-application/:/project/user-app docker.io/appsody/java-openliberty:0.2
Running command: docker cp sample-application-extract:/project /root/.appsody/extract/sample-application
Project extracted to /root/sample-application/.appsody_init
Running command: docker rm sample-application-extract -f
Running command: ./.appsody-init.sh
[InitScript] [INFO] Scanning for projects...
[InitScript] [INFO]
[InitScript] [INFO] --------------------< dev.appsody:java-openliberty >--------------------
[InitScript] [INFO] Building java-openliberty 0.2.14
[InitScript] [INFO] --------------------------------[ pom ]---------------------------------
[InitScript] [INFO]
[InitScript] [INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ java-openliberty ---
[InitScript] [INFO] Skipping Rule Enforcement.
[InitScript] [INFO]
[InitScript] [INFO] --- maven-install-plugin:2.4:install (default-install) @ java-openliberty ---
[InitScript] [INFO] Installing /root/sample-application/.appsody_init/pom.xml to /root/.m2/repository/dev/appsody/java-openliberty/0.2.14/java-openliberty-0.2.14.pom
[InitScript] [INFO] ------------------------------------------------------------------------
[InitScript] [INFO] BUILD SUCCESS
[InitScript] [INFO] ------------------------------------------------------------------------
[InitScript] [INFO] Total time:  1.354 s
[InitScript] [INFO] Finished at: 2020-07-01T03:24:37+09:00
[InitScript] [INFO] ------------------------------------------------------------------------
Successfully added your project to /root/.appsody/project.yaml
Your Appsody project ID has been set to 20200701032437.87801097
Successfully initialized Appsody project with the kabanero/java-openliberty stack and the default template.
```

initが終了した後、sample-applicationディレクトリ構成は以下の通りです。

```console
.
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── dev
    │   │       └── appsody
    │   │           └── starter
    │   │               ├── health
    │   │               │   ├── StarterLivenessCheck.java
    │   │               │   └── StarterReadinessCheck.java
    │   │               ├── StarterApplication.java
    │   │               └── StarterResource.java
    │   ├── liberty
    │   │   └── config
    │   │       ├── configDropins
    │   │       │   └── defaults
    │   │       │       └── quick-start-security.xml
    │   │       └── server.xml
    │   └── webapp
    │       ├── index.html
    │       └── WEB-INF
    │           └── beans.xml
    └── test
        └── java
            └── it
                └── dev
                    └── appsody
                        └── starter
                            ├── EndpointTest.java
                            └── HealthEndpointTest.java
```

開発者Janeは、この構成をベースに開発を進めます。

##  ローカル環境でのアプリケーションの動作確認

開発者Janeは、アプリケーションの開発の途中、任意のタイミングでアプリケーションを起動して動作確認するのには
appsody では run / test / debug コマンドを使用てJaneのアプリケーションを起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/d85d6916-5256-0d41-8636-dc5eff229a07.png)

では、 appsody run コマンドを実行して、アプリケーションを起動します。

```console
# appsody run
Running development environment...
Pulling docker image docker.io/appsody/java-openliberty:0.2
Running command: docker pull docker.io/appsody/java-openliberty:0.2
0.2: Pulling from appsody/java-openliberty
Digest: sha256:4dff3ca3d27b910b8dacf84895f5763d96df9671b7bbd5694ae14b4624d47dbd
Status: Image is up to date for appsody/java-openliberty:0.2
docker.io/appsody/java-openliberty:0.2
[Warning] The stack image does not contain APPSODY_DEPS
Running command: docker run --rm -p 7777:7777 -p 9080:9080 -p 9443:9443 --name sample-application -u 0:0 -e "APPSODY_USER=0" -e "APPSODY_GROUP=0" -v /root/.m2/repository:/mvn/repository -v /root/sample-application/:/project/user-app -v appsody-controller-0.3.5:/.appsody -t --entrypoint /.appsody/appsody-controller docker.io/appsody/java-openliberty:0.2 "--mode=run"
[Container] Running APPSODY_PREP command: /project/run-stack.sh prep
[Container] Installing parent dev.appsody:java-openliberty:0.2.14
[Container] [INFO] Scanning for projects...
[Container] [INFO]
[Container] [INFO] --------------------< dev.appsody:java-openliberty >--------------------
[Container] [INFO] Building java-openliberty 0.2.14
[Container] [INFO] --------------------------------[ pom ]---------------------------------
[Container] [INFO]
[Container] [INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ java-openliberty ---
[Container] [INFO] Skipping Rule Enforcement.
[Container] [INFO]
[Container] [INFO] --- maven-install-plugin:2.4:install (default-install) @ java-openliberty ---
[Container] [INFO] Installing /project/user-app/../pom.xml to /mvn/repository/dev/appsody/java-openliberty/0.2.14/java-openliberty-0.2.14.pom
[Container] [INFO] ------------------------------------------------------------------------
[Container] [INFO] BUILD SUCCESS
[Container] [INFO] ------------------------------------------------------------------------
[Container] [INFO] Total time:  0.932 s
(省略)
[Container] [INFO] [AUDIT   ] CWWKE0001I: The server defaultServer has been launched.
[Container] [INFO] [AUDIT   ] CWWKG0093A: Processing configuration drop-ins resource: /opt/ol/wlp/usr/servers/defaultServer/configDropins/defaults/quick-start-security.xml
[Container] [INFO] [AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.
[Container] [INFO] [AUDIT   ] CWPKI0820A: The default keystore has been created using the 'keystore_password' environment variable.
[Container] [INFO] [AUDIT   ] CWWKS4104A: LTPA keys created in 3.284 seconds. LTPA key file: /opt/ol/wlp/usr/servers/defaultServer/resources/security/ltpa.keys
[Container] [INFO] [AUDIT   ] CWPKI0803A: SSL certificate created in 4.596 seconds. SSL key file: /opt/ol/wlp/usr/servers/defaultServer/resources/security/key.p12
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/health/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/ibm/api/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/jwt/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/openapi/ui/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/metrics/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/openapi/
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/
[Container] [INFO] [AUDIT   ] CWWKZ0001I: Application starter-app started in 18.902 seconds.
[Container] [INFO] [AUDIT   ] CWWKF0012I: The server installed the following features: [appSecurity-2.0, cdi-2.0, concurrent-1.0, distributedMap-1.0, jaxrs-2.1, jaxrsClient-2.1, jndi-1.0, json-1.0, jsonb-1.0, jsonp-1.1, jwt-1.0, microProfile-3.2, mpConfig-1.3, mpFaultTolerance-2.0, mpHealth-2.1, mpJwt-1.1, mpMetrics-2.2, mpOpenAPI-1.1, mpOpenTracing-1.3, mpRestClient-1.3, opentracing-1.3, servlet-4.0, ssl-1.0].
[Container] [INFO] [AUDIT   ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 49.562 seconds.
[Container] [INFO] CWWKM2015I: Match number: 1 is [6/30/20 21:47:36:813 UTC] 0000002e com.ibm.ws.kernel.feature.internal.FeatureManager            A CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 49.562 seconds..
[Container] [INFO] Tests will run automatically when changes are detected.
[Container] [INFO] Source compilation was successful.
[Container] [INFO] Tests compilation was successful.
[Container] [INFO] [AUDIT   ] CWWKT0017I: Web application removed (default_host): http://023d8b3431cd:9080/
[Container] [INFO] [AUDIT   ] CWWKZ0009I: The application starter-app has stopped successfully.
[Container] [INFO] Running unit tests...
[Container] [INFO] Unit tests finished.
[Container] [INFO] Waiting up to 30 seconds to find the application start up or update message...
[Container] [INFO] CWWKM2010I: Searching for (CWWKZ0001I.*|CWWKZ0003I.*starter-app) in /opt/ol/wlp/usr/servers/defaultServer/logs/messages.log. This search will timeout after 30 seconds.
[Container] [INFO] CWWKM2015I: Match number: 1 is [6/30/20 21:47:36:038 UTC] 00000039 com.ibm.ws.app.manager.AppMessageHelper                      A CWWKZ0001I: Application starter-app started in 18.902 seconds..
[Container] [INFO] Running integration tests...
[Container] [INFO] [AUDIT   ] CWWKT0016I: Web application available (default_host): http://023d8b3431cd:9080/
[Container] [INFO] [AUDIT   ] CWWKZ0003I: The application starter-app updated in 2.628 seconds.
[Container] [INFO]
[Container] [INFO] -------------------------------------------------------
[Container] [INFO]  T E S T S
[Container] [INFO] -------------------------------------------------------
[Container] [INFO] Running it.dev.appsody.starter.HealthEndpointTest
[Container] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.048 s - in it.dev.appsody.starter.HealthEndpointTest
[Container] [INFO] Running it.dev.appsody.starter.EndpointTest
[Container] [INFO] [WARNING ] CWMOT0010W: OpenTracing cannot track JAX-RS requests because an OpentracingTracerFactory class was not provided or client libraries for tracing backend are not in the class path.
[Container] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.056 s - in it.dev.appsody.starter.EndpointTest
[Container] [INFO]
[Container] [INFO] Results:
[Container] [INFO]
[Container] [INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[Container] [INFO]
[Container] [INFO] Integration tests finished.
```

ログからは、docker pull、maven、OpenLibertyの起動、IntegrationTestの実行されているのがわかりますが、
OpenLibertyが起動したので、 起動確認として、healthチェックがupになっているのを確認します。

```console
# curl http://localhost:9080/health
{"checks":[{"data":{},"name":"StarterLivenessCheck","status":"UP"},{"data":{},"name":"StarterReadinessCheck","status":"UP"}],"status":"UP"}
```

これで、ローカル環境でのアプリケーションの起動を確認することができました。
Janeは開発が終了まで、ソースコードの作成とappsody runコマンドで動作確認を繰り返すことになります。

## OpenShiftへリリースするためのアプリケーションのビルド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/be703c14-32ab-434e-9ed9-e410de29981e.png)

Janeはアプリケーションの開発が終了したので、OpenShiftへデプロイします。
まずは、appsody buildコマンドを実行して、本番環境用のコンテナイメージをビルドします。
appsody runの時はローカル環境用のbuilderを使って、コンテナイメージを生成していましたが、appsody buildの場合は本番環境のbuilderを使ってコンテナイメージを生成します。

```console
# appsody build
Extracting project from development environment
Pulling docker image docker.io/appsody/java-openliberty:0.2
Running command: docker pull docker.io/appsody/java-openliberty:0.2
0.2: Pulling from appsody/java-openliberty
Digest: sha256:4dff3ca3d27b910b8dacf84895f5763d96df9671b7bbd5694ae14b4624d47dbd
Status: Image is up to date for appsody/java-openliberty:0.2
docker.io/appsody/java-openliberty:0.2
[Warning] The stack image does not contain APPSODY_PROJECT_DIR. Using /project
Running command: docker create --name sample-application-extract -v /root/.m2/repository:/mvn/repository -v /root/sample-application/:/project/user-app docker.io/appsody/java-openliberty:0.2
Running command: docker cp sample-application-extract:/project /root/.appsody/extract/sample-application
Project extracted to /root/.appsody/extract/sample-application
Running command: docker rm sample-application-extract -f
(省略）
[Docker] Sending build context to Docker daemon    706kB
[Docker] Step 1/62 : FROM kabanero/ubi8-maven:0.9.0 as compile
[Docker] 0.9.0: Pulling from kabanero/ubi8-maven
(省略）
[Docker] Removing intermediate container 587544680ab9
[Docker]  ---> 6cb69d5ff953
[Docker] Successfully built 6cb69d5ff953
[Docker] Successfully tagged dev.local/sample-application:latest
Built docker image dev.local/sample-application
Running command: docker create --name sample-application-extract docker.io/appsody/java-openliberty:0.2
Running command: docker cp sample-application-extract:/config/app-deploy.yaml /root/sample-application/app-deploy.yaml
Running command: docker rm sample-application-extract -f
Created deployment manifest: /root/sample-application/app-deploy.yaml
```

OpenShiftへのデプロイは OpenShiftにインストールされた Appsody Operatorがアプリケーションをデプロイします。
最後に作成されたapp-deploy.yamlは、Appsody Operatorに渡すためのmanifestです。

- app-deploy.yaml

```yaml
apiVersion: openliberty.io/v1beta1
kind: OpenLibertyApplication
metadata:
  annotations:
    architecture: x86_64
    authoritative-source-url: registry.access.redhat.com
    build-date: 2020-03-31T14:54:13.907559
    commit.stack.appsody.dev/contextDir: /incubator/java-openliberty
    commit.stack.appsody.dev/date: Thu Jun 4 13:29:00 2020 +0100
    commit.stack.appsody.dev/message: 'java-openliberty: define APPSODY_DEBUG_PORT
      (#818)'
    description: Eclipse MicroProfile & Jakarta EE on Open Liberty & OpenJ9 using
      Maven
    distribution-scope: public
    image.opencontainers.org/created: "2020-07-01T07:13:29+09:00"
    k8s.io/description: The Universal Base Image is designed and engineered to be
      the base layer for all of your containerized applications, middleware and utilities.
      This base image is freely redistributable, but Red Hat only supports Red Hat
      technologies through subscriptions for Red Hat products. This image is maintained
      by Red Hat and updated regularly.
    k8s.io/display-name: Red Hat Universal Base Image 8
    maintainer: Red Hat, Inc.
    name: java-openliberty
    openshift.io/expose-services: ""
    openshift.io/tags: base rhel8
    redhat.com/build-host: cpt-1007.osbs.prod.upshift.rdu2.redhat.com
    redhat.com/component: ubi8-container
    redhat.com/license_terms: https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI
    release: "408"
    stack.appsody.dev/authors: Mike Andrasak <uberskigeek>, Andy Mauer <ajm01>, Scott
      Kurz <scottkurz>, Adam Wisniewski <awisniew90>
    stack.appsody.dev/configured: docker.io/appsody/java-openliberty:0.2
    stack.appsody.dev/created: "2020-06-04T12:31:59Z"
    stack.appsody.dev/description: Eclipse MicroProfile & Jakarta EE on Open Liberty
      & OpenJ9 using Maven
    stack.appsody.dev/digest: sha256:4dff3ca3d27b910b8dacf84895f5763d96df9671b7bbd5694ae14b4624d47dbd
    stack.appsody.dev/documentation: https://github.com/appsody/stacks/tree/master/incubator/java-openliberty/README.md
    stack.appsody.dev/licenses: Apache-2.0
    stack.appsody.dev/revision: 1b105b4891a3edef718d668271da30086214dd84
    stack.appsody.dev/source: https://github.com/appsody/stacks/tree/master/incubator/java-openliberty/image
    stack.appsody.dev/tag: docker.io/appsody/java-openliberty:0.2.14
    stack.appsody.dev/title: Open Liberty
    stack.appsody.dev/url: https://github.com/appsody/stacks/tree/master/incubator/java-openliberty
    summary: Open Liberty
    url: https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.1-408
    vcs-ref: 26f36bfa3e3a04c8c866b250924c1aefc34f01c9
    vcs-type: git
    vendor: Open Liberty
    version: 0.2.14
  creationTimestamp: null
  labels:
    image.opencontainers.org/title: sample-application
    stack.appsody.dev/id: java-openliberty
    stack.appsody.dev/version: 0.2.14
  name: sample-application
  namespace: sampleapps1
spec:
  applicationImage: dev.local/sample-application
  createKnativeService: false
  expose: true
  livenessProbe:
    failureThreshold: 12
    httpGet:
      path: /health/live
      port: 9080
    initialDelaySeconds: 5
    periodSeconds: 2
  readinessProbe:
    failureThreshold: 12
    httpGet:
      path: /health/ready
      port: 9080
    initialDelaySeconds: 5
    periodSeconds: 2
    timeoutSeconds: 1
  service:
    annotations:
      prometheus.io/scrape: "true"
    port: 9080
    type: NodePort
  version: 1.0.0
```


## アプリケーションのOpenShiftへのデプロイ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/e5992008-4117-0641-7344-f9ae9c1bfd24.png)

buildが終了すると本番環境のコンテナイメージが生成されます。このイメージをOpenShiftにデプロイするためには appsody deployコマンドでデプロイします。

その前に、OpenShiftの環境を準備します。


### プロジェクト(namespace)の作成

アプリケーションをデプロイするためのプロジェクト( sampleapps )を作成します。

```console
# oc new-project sampleapps
Now using project "sampleapps" on server "https://api.lab.example.com:6443".

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

    oc new-app ruby~https://github.com/sclorg/ruby-ex.git

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

    kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

```

現時点では、 sampleappsプロジェクトには何もリソースはありません。

```console
# oc get all -n sampleapps
No resources found in sampleapps namespace.
```

次に"oc get csv"コマンドを実行すると、sampleappsプロジェクトでは以下のOperatorが使えるようになっていますが、
このOperatorは、KabaneroをInstallしたときに導入されたOperatorが、sampleappsプロジェクトにも展開されています。

```console
# oc get csv -n sampleapps
NAME                                         DISPLAY                          VERSION               REPLACES                                     PHASE
appsody-operator.v0.5.1                      Appsody Operator                 0.5.1                                                              Succeeded
elasticsearch-operator.4.3.26-202006160135   Elasticsearch Operator           4.3.26-202006160135   elasticsearch-operator.4.3.25-202006081335   Succeeded
jaeger-operator.v1.17.3                      Red Hat OpenShift Jaeger         1.17.3                jaeger-operator.v1.17.2                      Succeeded
kiali-operator.v1.12.13                      Kiali Operator                   1.12.13               kiali-operator.v1.12.12                      Succeeded
open-liberty-operator.v0.5.1                 Open Liberty Operator            0.5.1                                                              Succeeded
openshift-pipelines-operator.v0.11.2         OpenShift Pipelines Operator     0.11.2                                                             Succeeded
serverless-operator.v1.7.1                   OpenShift Serverless Operator    1.7.1                                                              Succeeded
servicemeshoperator.v1.1.3                   Red Hat OpenShift Service Mesh   1.1.3                 servicemeshoperator.v1.1.2.3                 Succeeded
```

次に、OpenShiftの内部レジストリに本番環境用のコンテナイメージpushするために、内部レジストリにログインします。

ログインするために必要な内部レジストリのURLを変数HOSTに格納します。

```console
HOST=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
# echo ${HOST}
default-route-openshift-image-registry.apps.lab.example.com
```

そして、内部レジストリにログインして、ローカル環境からOpenShiftにコンテナイメージをpushできるようにします。

```console
# docker login -u kubeadmin -p $(oc whoami -t) $HOST
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
```

最後に appsody deployコマンドを使用して、OpenShiftにデプロイします。

```console
# appsody deploy --tag sampleapps/sample-application:v1 --push-url $HOST --push --pull-url docker-registry.default.svc:5000 --namespace sampleapps
```

-- tag プロジェクト名/コンテナイメージ名:tag  
--push-url $HOST --push は ローカル環境からpushするためにアドレスを記述
--pull-url は OpenShift内部で、デプロイするのに pullするために必要なURLを記述


デプロイが終了して、"oc get all -n sampleapps" コマンドを実行すると podが起動しているのが確認できます。

```console
# oc get all -n sampleapps
NAME                                      READY   STATUS    RESTARTS   AGE
pod/sample-application-6d56c87cdf-fhrs2   0/1     Running   0          42s

NAME                         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/sample-application   NodePort   172.30.145.68   <none>        9080:30957/TCP   43s

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/sample-application   0/1     1            0           42s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/sample-application-6d56c87cdf   1         1         0       42s

NAME                                                IMAGE REPOSITORY                                                                          TAGS     UPDATED
imagestream.image.openshift.io/sample-application   default-route-openshift-image-registry.apps.lab.example.com/sampleapps/sample-application   latest   2 minutes ago

NAME                                          HOST/PORT                                          PATH   SERVICES             PORT       TERMINATION   WILDCARD
route.route.openshift.io/sample-application   sample-application-sampleapps.apps.lab.example.com          sample-application   9080-tcp                 None
```

外部からcurlでhealthチェックのURLにアクセスすると statusがupになってるのが確認できました。

```console
# curl http://sample-application-sampleapps.apps.lab.example.com/health
{"checks":[{"data":{},"name":"StarterLivenessCheck","status":"UP"},{"data":{},"name":"StarterReadinessCheck","status":"UP"}],"status":"UP"}
```

## Kabaneroを使った開発フローのまとめ

これまでのkabaneroを使ったアプリケーションの開発フローをまとめると下図の様ながれになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/5708ae11-8fc3-9d1b-3ef8-d40f6b0dd52b.png)

これまでの流れから、appsody cliのコマンドを使うとdockerコマンドが抽象化されているので、開発者はdockerの作法知らなくても、開発できそうです。
また、stackをカスタマイズすると、それぞれの組織にあったstackもできそうです。
そして、5. deployでは、appsody operatorがアプリケーションをOpenShiftにデプロイしているのは初見でした。
もう少し勉強をすすめていきたいと思います。