はじめに
IBM CloudのOpenShiftのマネージドサービスである「 Red Hat OpenShift on IBM Cloud 」を使った「OpenShiftによるJava EEアプリケーションのモダナイゼーション」の記事を寄稿しました。
https://www.atmarkit.co.jp/ait/articles/1911/15/news002.html
その記事で使用している「 Red Hat OpenShift on IBM Cloud 」は有料サービスのため、たくさんの人に記事の手順を試してもらうのは難しいと思います。 そこで、無料で利用できるMiniShiftを使って、気軽にOpenShiftでJava EEアプリケーションのモダナイゼーションを体感してもらえるように、リライトしました。
今回はアプリケーション・データベース共に全てコンテナ化するケースを試したいと思います。記事を読んでいただいた方は、記事の内容に加えて複数コンテナの連携(アプリケーションとデーターベース接続)について学べるようになってます。 記事では、データベースはIBM Cloudのマネージドサービス「 Compose for MySQL 」を利用しました。
(1)から(5)までシリーズ化してます。
-
(この投稿)「OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた」- ビジネスロジック用のOpen Libertyで実行されているJava EEアプリケーションのモダナイゼーション
-
「OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた(2)」- 患者向けUI(ユーザーインターフェイス)のNode.jsアプリケーションのモダナイゼーション
-
「 OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた(3)」- 健康記録管理者用のPHPアプリケーション機能追加のモダナイゼーション
-
「 OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた(4)」- OpenShiftの標準的な機能のみを使ったDevOpsやCI/CD(継続的インテグレーション/継続的デリバリー)
-
「 OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた(5)」- Jenkinsを使ったDevOpsやCI/CD(継続的インテグレーション/継続的デリバリー)
OpenShiftによるJava EEアプリケーションのモダナイゼーション
IBM Code Patterns に「 Java EE と Open Liberty を使用した架空の医療アプリ内にマイクロサービスをデプロイする 」というコードパターンがあります。これからこのコードパターンを使って実際に手を動かしてJava EEアプリケーションのモダナイゼーションを体感したいと思います。この一連の流れはオンプレミスシステムからクラウドへの移行の手順に相当するとご想像いただくとイメージしやすいでしょうか。これから皆さんはソリューションアーキテクトになりきって、これからクラウドで広がるモダナイゼーションの旅を体感しましょう。
Example Healthのユースケース
Example Healthは架空の医療会社です。この会社には歴史があり、数十万の患者記録があります。もともと、Example Healthはアプリケーションにモノリシックアプリケーション構造を使用していました。それらのアプリケーション構造は、メインフレーム上のDb2データベースに接続されたWebSphereで実行されるフルスタックのJavaアプリケーションでした。Example Healthの元のアーキテクチャは次の通りです。
最近、Example Healthはアプリケーションをモダナイズし、マイクロサービスに分割することを決定しました。彼らはビジネスロジック用のOpen Libertyで実行されているJava EEアプリケーションと患者UI用のNode.jsアプリケーションに接続されたSQLデータベース(MySQL)に移動することを決定したのです。さらに、Example Healthはこれらのアプリケーション、SQLデータベースを全てコンテナ化し「 Red Hat OpenShift on IBM Cloud」上で動かすことを決定しました。 Example Healthの新しいアーキテクチャは次の通りです。
「 Red Hat OpenShift on IBM Cloud 」に移行した結果、Example Healthは容易に機能拡張できるようになりました。間もなく、健康記録管理用アプリケーションと分析アプリケーションを含む新しいマイクロサービスが含まれるようになるのです。
MiniShiftの準備
Qiitaの別投稿を参考に、MiniShiftを準備してください。
注:MiniShiftを起動するホストのDockerのバージョンは17.09以降をインストールしてください。 Docker CE(コミュニティエディション)の最新をインストールすると良いでしょう。後ほど使用するDockerfileの中にDocker 17.09からサポートするADD/COPY --chownフラグでファイルのオーナーを変える構文が使われているためです。 MiniShiftの仮想マシン(VM)で動作するDockerのバージョンが1.13なので、面倒なことになってます。ちなみにDockerfileを--chownフラグを使わないようにすれば、メンドくさいことから回避されますが、今回はコードパターンのリソースは変更せずにやっていきます。
手順の前半ではMiniShiftは使用しません。必要になる時までMiniShiftを停止してください。
# minishift stop
MiniShiftを起動した後に「 # eval $(minishift docker-env) 」コマンドを実行している場合は、
「 docker push 」する際に、MiniShiftの仮想マシン(VM)で動作するDockerにイメージを登録します。
今回は、作業ホストのMiniShiftを起動するホストのDockerにイメージを登録したいので、「 # env | grep DOCKER 」コマンドを実行してDOCKER_HOST、DOCKER_TLS_VERIFY、DOCKER_CERT_PATHに値が入っている場合は、下記コマンドで環境変数を空にしてください。
export DOCKER_TLS_VERIFY=""
export DOCKER_HOST=""
export DOCKER_CERT_PATH=""
手順
(筆者が試した環境)CentOS 7.7 最小構成
1. Maven (Mavenの依存関係でJDKもインストールされる)
# yum install maven
2. Dockerデーモンの起動確認
後ほどDockerビルドするのでDockerでデーモンが起動していることを確認
# systemctl status docker
Dockerfileの中に、Docker 17.09 からサポートするADD/COPY --chownでファイルのオーナーを変える構文が使われているため、 CentOSでサポートする Dockerでは、構文がわからないためエラーになります。 Dockerのバージョンを17.09以上にするか、Dockerfileを--chownの箇所を 別行(別レイヤー)でchownコマンドで処理するなど回避してください。
3. GitHubのプロジェクトをCloneします。Cloneするとexample-health-jee-openshiftフォルダが作成されます。
# git clone https://github.com/daihiraoka/example-health-jee-openshift.git
Cloning into 'example-health-jee-openshift'...
remote: Enumerating objects: 263, done.
remote: Counting objects: 100% (263/263), done.
remote: Compressing objects: 100% (175/175), done.
remote: Total 263 (delta 108), reused 204 (delta 53), pack-reused 0
Receiving objects: 100% (263/263), 17.82 MiB | 5.57 MiB/s, done.
Resolving deltas: 100% (108/108), done.
# cd example-health-jee-openshift
# ls
example-health-api generate LICENSE readme_images README.md screenshots
4. Java EEアプリケーションをビルドします。
# cd example-health-api/
# mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building health-api 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.5/maven-resources-plugin-2.5.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.5/maven-resources-plugin-2.5.pom (7 KB at 7.4 KB/sec)
<<------------------------------------省略------------------------------------>>
[INFO] Building war: /root/example-health-jee-openshift/example-health-api/target/health-api.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34.656s
[INFO] Finished at: Thu Oct 17 13:58:55 JST 2019
[INFO] Final Memory: 14M/143M
[INFO] ------------------------------------------------------------------------
5. Java EE アプリケーションのDockerイメージをビルドします。
# docker build -t ol-example-health:1 .
Sending build context to Docker daemon 13.48MB
Step 1/10 : FROM openliberty/open-liberty:javaee8-ubi-min
javaee8-ubi-min: Pulling from openliberty/open-liberty
bdb299bbb0dd: Pull complete
22b1a8fa1ec0: Pull complete
bccea9526f92: Pull complete
ca821998be76: Pull complete
7d738fac7181: Pull complete
2356e9fc5285: Pull complete
048ba391e9fe: Pull complete
347eb7134a38: Pull complete
94456b65cdbb: Pull complete
Digest: sha256:1f08f83c3076aaec7a7d3639864ca06998a779cecad6ad1452d501008c56f63b
Status: Downloaded newer image for openliberty/open-liberty:javaee8-ubi-min
---> fc55e2d66c27
Step 2/10 : ENV INSTALL_DIR /opt/ol/wlp/
---> Running in 45aaeaaa0c92
Removing intermediate container 45aaeaaa0c92
---> 27fe222d05be
Step 3/10 : ENV CONFIG_DIR /opt/ol/wlp/usr/servers/defaultServer/
---> Running in 395e839afb7f
Removing intermediate container 395e839afb7f
---> 8632cfb62026
Step 4/10 : ADD --chown=default:root https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar ${INSTALL_DIR}lib/mysql-connector-java-8.0.16.jar
Downloading [==================================================>] 2.293MB/2.293MB
---> 61898c26bdb1
Step 5/10 : RUN chmod 644 ${INSTALL_DIR}lib/mysql-connector-java-8.0.16.jar
---> Running in 8011b3b50bac
Removing intermediate container 8011b3b50bac
---> 5909218a689a
Step 6/10 : COPY liberty-mysql/mysql-driver.xml ${CONFIG_DIR}configDropins/defaults/
---> f42f5684e5b0
Step 7/10 : COPY liberty/server.xml $CONFIG_DIR
---> 67938badab11
Step 8/10 : COPY liberty/jvm.options $CONFIG_DIR
---> 60c3c494f5ef
Step 9/10 : COPY target/health-api.war /opt/ol/wlp/usr/servers/defaultServer/apps
---> 1bcb2f837df9
Step 10/10 : EXPOSE 9080
---> Running in eba84e894ddc
Removing intermediate container eba84e894ddc
---> aa91da14cf12
Successfully built aa91da14cf12
Successfully tagged ol-example-health:1
6. Dockerビルドが成功するとベースイメージのopenliberty/open-libertyと今回作成したol-example-healthイメージが出力されます。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ol-example-health 1 aa91da14cf12 48 seconds ago 348MB
openliberty/open-liberty javaee8-ubi-min fc55e2d66c27 16 hours ago 343MB
Note:
DockerfileのFROM句で指定しているOpen LibertyのベースイメージにはRed Hat UBI(Red Hat Universal Base Image)のRHEL7を使用しています。Red Hat UBIはRed Hatの品質管理を経て提供されるコンテナイメージで無償で、自由に再配布することができます。
Red Hat UBIベースで作成したコンテナイメージは、「 Red Hat OpenShift on IBM Cloud 」上で動作させる時は、サポートを受けることができます。OpenShiftを使用しない環境では、サポートを受けることはできませんが、無償でRHELのコンテナイメージが使えるメリットがあります。
企業の中でコンテナを運用していると、それぞれの部門からCentOS、Ubuntuなど出所のよく分からないコンテナを渡されてセキュリティ的に大丈夫なのか判断が必要な場合があります。でも様々な理由で使うしかなく不安を抱えて運用することもありました。Red Hat UBIだとRed Hatの品質管理を経て提供されるのでその不安は解消されます。もし、今CentOSやUbuntuのコンテナイメージを使っている方は、Red Hat UBIを使ってみたらいかがでしょうか?
Red Hat UBI(Red Hat Universal Base Image)
https://access.redhat.com/containers/#/search/ubi
7. Docker HubにJava EEアプリケーションのDockerイメージ「 ol-example-health 」を登録します。
- 事前にDocker Hubのアカウントを作成してください。
- daihiraokaの箇所をDocker Hubのアカウント名に置き換えて実行してください。
ol-example-healthイメージを 「 Docker Hubのアカウント名/イメージ名:タグ名 」の形式でタグ付けします。
# docker tag ol-example-health:1 daihiraoka/ol-example-health:1
Dockerイメージの一覧を出力するとdaihiraoka/ol-example-healthイメージが作成されているのが確認できます。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daihiraoka/ol-example-health 1 901666e26ca5 27 minutes ago 450MB
ol-example-health 1 901666e26ca5 27 minutes ago 450MB
openliberty/open-liberty javaee8-ubi-min bb992680821b 17 hours ago 445MB
Docker Hubにログインし、Docker Hubのリポジトリにdaihiraoka/ol-example-healthイメージを登録します。
# docker login -u daihiraoka
Login Succeeded
# docker push daihiraoka/ol-example-health:1
イメージの登録が完了するとDocker Hubのリポジトリにdaihiraoka/ol-example-healthが表示されます。
Note:
今回はCode Patternsの手順でDocker Hubを使いましたが、IBM CloudにはContainer Registryのサービスがあります。通常、商用利用ではIBM Cloud Container Registryを使ってコンテナイメージを管理します。
・IBM Cloud Container Registry の概要
https://cloud.ibm.com/docs/services/Registry?topic=registry-registry_overview&locale=ja
8. MiniShiftの起動
# minishift start
-- Starting profile 'minishift'
-- Check if deprecated options are used ... OK
-- Checking if https://github.com is reachable ... OK
-- Checking if requested OpenShift version 'v3.11.0' is valid ... OK
-- Checking if requested OpenShift version 'v3.11.0' is supported ... OK
-- Checking if requested hypervisor 'kvm' is supported on this platform ... OK
Server Information ...
OpenShift server started.
<img width="400" alt="dockerhub-01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209170/d24a8d74-9aca-898e-1066-86395168ba48.png">
The server is accessible via web console at:
https://192.168.42.138:8443/console
- MiniShiftの環境変数の適用
# eval $(minishift oc-env) <- ocコマンドのPATH定義
# eval $(minishift docker-env) <- MiniShiftのVMで動作するDockerへの接続設定
# source <(oc completion bash) <-コマンドとリソースのシェル補完
minishift oc-envを実行してみると ocコマンドのPATHを通すためコマンドが出力される。
# minishift oc-env
export PATH="/root/.minishift/cache/oc/v3.11.0/linux:$PATH"
# Run this command to configure your shell:
# eval $(minishift oc-env)
# ls -1 /root/.minishift/cache/oc/v3.11.0/linux
oc
minishift docker-envを実行すると、下記のように KVM上で動作しているMiniShiftのVMで動作しているDockerへの接続情報が出力されます。 この環境変数を定義することでローカルのDockerレジストリではなくMiniShiftのVMのDockerレジストリでコンテナイメージを取り扱います。
# minishift docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.42.138:2376"
export DOCKER_CERT_PATH="/root/.minishift/certs"
9. OpenShiftのCLIにユーザー名をdeveloperでログインします。
(MiniShiftではパスワードは何でも通るので任意の文字列を使用してください。)
# oc login -u developer
Logged into "https://192.168.42.138:8443" as "developer" using existing credentials.
You have one project on this server: "myproject"
Using project "myproject".
10. Example Health用のプロジェクトを作成します。
これにより、新しいプロジェクトが作成され、Pod(コンテナ)がデプロイされる作業プロジェクトとして設定されます。
# oc new-project health
Now using project "health" on server "https://192.168.42.138:8443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git
to build a new example application in Ruby.
11. MySQLのカタログを探すためにOpenShiftプロジェクトのImageStream(is)の一覧を出力します。
# oc get is -n openshift
NAME DOCKER REPO TAGS UPDATED
dotnet 172.30.1.1:5000/openshift/dotnet 2.0,latest 16 hours ago
httpd 172.30.1.1:5000/openshift/httpd 2.4,latest 16 hours ago
jenkins 172.30.1.1:5000/openshift/jenkins 2,latest,1 16 hours ago
mariadb 172.30.1.1:5000/openshift/mariadb 10.1,10.2,latest 16 hours ago
mongodb 172.30.1.1:5000/openshift/mongodb 2.6,3.2,3.4 + 3 more... 16 hours ago
mysql 172.30.1.1:5000/openshift/mysql latest,5.5,5.6 + 1 more... 16 hours ago
nginx 172.30.1.1:5000/openshift/nginx 1.10,1.12,1.8 + 1 more... 16 hours ago
nodejs 172.30.1.1:5000/openshift/nodejs 4,6,8 + 4 more... 16 hours ago
perl 172.30.1.1:5000/openshift/perl 5.20,5.24,5.26 + 2 more... 16 hours ago
php 172.30.1.1:5000/openshift/php 7.1,latest,5.5 + 2 more... 16 hours ago
postgresql 172.30.1.1:5000/openshift/postgresql 9.4,9.5,9.6 + 3 more... 16 hours ago
python 172.30.1.1:5000/openshift/python 3.5,3.6,latest + 3 more... 16 hours ago
redis 172.30.1.1:5000/openshift/redis 3.2,latest 16 hours ago
ruby 172.30.1.1:5000/openshift/ruby 2.2,2.3,2.4 + 3 more... 16 hours ago
wildfly 172.30.1.1:5000/openshift/wildfly 11.0,12.0,13.0 + 5 more... 16 hours ago
mysqlが今回使用するコンテナイメージのImageStreamです。一覧で表示されるnodejsやdotnetは、下記画像のWebコンソールのカタログと同じです。OpenShiftはCLIでも簡単にアプリケーションをデプロイする仕組みを用意しています。
12. OpenShiftのS2I(Source to Image)を使ってMySQLデータベースのコンテナを作成します。
# oc new-app \
-e MYSQL_USER=admin \
-e MYSQL_PASSWORD=password \
-e MYSQL_DATABASE=health \
--name=mysql \
openshift/mysql:5.7~https://github.com/daihiraoka/example-health-jee-openshift.git
「 -e 」で環境変数を定義します。
パラメーター | 概要 |
---|---|
-e MYSQL_USER | MySQLのユーザー名 |
-e MYSQL_PASSWORD | MySQLのパスワード |
-e MYSQL_DATABASE | データベース名 |
--name | コンテナ名 |
openshift/mysql:5.7 | openshift/mysql:5.7はベースとなるコンテナイメージのImageStream名(openshiftプロジェクトのmysql:5.7) |
~https://github.com(省略) | ~(チルダ)で挟んで右側が、ソースコードリポジトリを指定 |
今回は、データベースのデータを保存する永続ストレージについては省略しています。Pod(コンテナ)に永続ストレージの設定をしていない場合は、 Pod(コンテナ)が停止すると登録したデーターは全て消えてしまいます。
今回の場合は、新たにPod(コンテナ)が起動すると、空っぽで、SQLスキーマのインポートから再開しないといけません。
実行結果
--> Found image f83a293 (6 days old) in image stream "openshift/mysql" under tag "5.7" for "openshift/mysql:5.7"
MySQL 5.7
---------
MySQL is a multi-user, multi-threaded SQL database server. The container image provides a containerized packaging of the MySQL mysqld daemon and client application. The mysqld server daemon accepts connections from clients and provides access to content from MySQL databases on behalf of the clients.
Tags: database, mysql, mysql57, rh-mysql57
* A source build using source code from https://github.com/daihiraoka/example-health-jee-openshift.git will be created
* The resulting image will be pushed to image stream tag "mysql:latest"
* Use 'start-build' to trigger a new build
* This image will be deployed in deployment config "mysql"
* Port 3306/tcp will be load balanced by service "mysql"
* Other containers can access this service through the hostname "mysql"
--> Creating resources ...
imagestream.image.openshift.io "mysql" created
buildconfig.build.openshift.io "mysql" created
deploymentconfig.apps.openshift.io "mysql" created
service "mysql" created
--> Success
Build scheduled, use 'oc logs -f bc/mysql' 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 svc/mysql'
Run 'oc status' to view your app.
しばらくすると mysqlのPod [ mysql-1-hktv2 ] が起動します。
# oc get pod
NAME READY STATUS RESTARTS AGE
mysql-1-build 0/1 Completed 0 3m
mysql-1-hktv2 1/1 Running 0 2m
13. MySQLコンテナにデーターベーススキーマーを作成
MySQLにデーターベースのスキーマーを作成するために、 oc rshコマンドでコンテナにログインします。
# oc rsh mysql-1-hktv2
rshでログインするとgithubでディレクトリ構造がコンテナの中にあることがわかります。
sh-4.2$ ls
LICENSE README.md example-health-api generate readme_images screenshots
患者の健康記録データのSQLスキーマをインポートします ファイル名: example-health-api/samples/health_schema.sql
sh-4.2$ mysql -u admin -ppassword health < ./example-health-api/samples/health_schema.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
healthデータベースのテーブル一覧を出力します。SQLスキーマのインポートが正常に終了していると出力結果のテーブルが表示されます。
sh-4.2$ mysql -u admin -ppassword health -e "show tables;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------+
| Tables_in_health |
+------------------+
| Allergies |
| Appointments |
| MESSAGE |
| Observations |
| Organizations |
| Patients |
| Prescriptions |
| Providers |
| SEQUENCE |
+------------------+
データベースの作成が終わったのでコンテナから「 exit 」コマンドで抜けます。
sh-4.2$ exit
exit
14. ビジネスロジック用のJava EE アプリケーションとMySQLのコンテナ間通信設定
作業ホストに戻って「 pwd 」を打つと「 example-health-jee-openshift/example-health-api 」フォルダにいるはずです。
# pwd
/root/example-health-jee-openshift/example-health-api
# ls
create-secrets.sh Dockerfile kubernetes-openshift.yaml liberty liberty-mysql pom.xml samples src target
ビジネスロジック用のJava EE アプリケーションとMySQLを接続するために、まずは MySQLのサービス名を調べます。
# oc get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 172.30.88.187 <none> 3306/TCP 9m
Pod間の通信は、サービス名で行います。 サービス名は次の手順で使うので覚えておいてください。
example-health-api/create-secrets.shスクリプトを使ってMySQLの接続情報を設定します。
cat create-secrets.sh
#!/bin/bash
oc create secret generic db-secrets \
--from-literal=db_username=admin \
--from-literal=db_password=password \
# --from-literal=db_host="jdbc:mysql://サービス名:ポート番号/データベース名?sessionVariables=sql_mode=''"
--from-literal=db_host="jdbc:mysql://mysql:3306/health?sessionVariables=sql_mode=''"
注: 2019年10月時点ではcreate-secrets.shには「 DB名/?sessionVariables 」と「 DB名 」と「 ? 」の間に「 / 」が書かれています。JDBCで接続する時は「 / 」もDB名の文字列に含まれるため、接続エラーが発生します。そのため「 / 」を削除してください。
OpenShiftではパスワードなど認証情報はsecretsという機密情報を保持するメカニズムをもつオブジェクトに保持します。
そしてMySQの接続情報はPod(コンテナ)の中で環境変数として利用します。環境変数として使うためには次の手順のkubernetes-openshift.yamlでPod(コンテナ)のデプロイを定義するDeploymentオブジェクトの中で、環境変数とsecretsの紐付けを行います。
- kubernetes-openshift.yamlのenv(環境変数)を定義する箇所を抜粋
env:
- name: ENV_MYSQL_UR
valueFrom:
secretKeyRef:
name: db-secrets
key: db_host
- name: ENV_MYSQL_USER
valueFrom:
secretKeyRef:
name: db-secrets
key: db_username
- name: ENV_MYSQL_PWD
valueFrom:
secretKeyRef:
name: db-secrets
key: db_password
そしてOpen LibertyのDataSource設定では、上記で定義した環境変数を使用してデータベース接続のパラメータを設定します。
- example-health-api/liberty/server.xmlのDataSourceを定義する箇所を抜粋
<dataSource id="DefaultDataSource" jndiName="jdbc/health-api" jdbcDriverRef="mysql-driver"
type="javax.sql.ConnectionPoolDataSource" transactional="true">
<properties url="${ENV_MYSQL_URL}"
databaseName="${ENV_MYSQL_DB_NAME}"
user="${ENV_MYSQL_USER}"
password="${ENV_MYSQL_PWD}"/>
注: 上記には未定義の環境変数:ENV_MYSQL_DB_NAMEがありますが、環境変数:ENV_MYSQL_URLの中でデータベース名が定義しているためです。ここでは元のCode Patternsのコードをそのまま表示しています。
スクリプトを実行してsecretsをOpenShiftに作成します。作成後「 oc get secrets 」コマンドでsecretsの一覧を出力すると「 db-secrets 」という名前で作成されているのが確認できます。
# ./create-secrets.sh
secret/db-secrets created
# oc get secrets
NAME TYPE DATA AGE
db-secrets Opaque 3 2d
15. Java EE アプリケーションのデプロイ
ファイル: example-health-api/kubernetes-openshift.yamlを編集して、containersセクションのimageキーをDocker HubにpushしたJava EE アプリケーションのDockerイメージに変更します。
- daihiraokaの箇所をDockerHubのアカウント名に置き換えてください。
- ol-example-healthのタグをlatestから1に置き換えてください。
(変更前)
containers:
- name: example-health-api
image: ykoyfman/ol-example-health:latest
(変更後)
containers:
- name: example-health-api
image: daihiraoka/ol-example-health:1
Java EE アプリケーションをクラスターにデプロイします。
# oc create -f kubernetes-openshift.yaml
service/example-health-api created
deployment.apps/example-health-api created
example-health-api/kubernetes-openshift.yamlの中には、Open LibertyのPod(コンテナ)をデプロイするための定義が記述されているDeployment、Open LibertyのPod(コンテナ)のEndPoint(IP)にアクセスするためのServiceが記述されています。このyamlを実行することによって、OpenShiftにOpen LibertyのPod(コンテナ)が起動し、Serviceを使ってOpen LibertyのPod(コンテナ)に接続できるようになります。
しばらく時間が経過するとOpen LibertyのPod(コンテナ)が起動します。「 oc get pod 」コマンドを実行してPod(コンテナ)の一覧を出力すると「 example-health-api-<任意の英数字> 」のPod(コンテナ)のSTATUSが 「 Running 」になります。
# oc get pod
NAME READY STATUS RESTARTS AGE
example-health-api-7fcb786fb6-l5kx9 1/1 Running 0 1m
mysql-1-build 0/1 Completed 0 22m
mysql-1-hktv2 1/1 Running 0 21m
16. Java EE アプリケーションをインターネットに公開するためのOpenShiftのオブジェクトであるRouteを作成します。
# oc expose svc example-health-api
route.route.openshift.io/example-health-api exposed
Java EE アプリケーションが機能していることを確認します。まず、Routeに割り当てられたホスト名を取得します。
# oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
example-health-api example-health-api-health.192.168.42.138.nip.io example-health-api http None
この場合は最初のNAMEのexample-health-apiがRoute名で、次のHOST/PORTのFQDNが生成されたホスト名です。RouteにアクセスがあるとSERVICESのexample-health-apiを通って、Open LibertyのPod(コンテナ)のEndPointのIPアドレスにアクセスします。
17. ブラウザでJava EEアプリケーションの動作確認
ブラウザウィンドウで、/openapi/ui/に移動します。Java EEアプリケーションでサポートされるOpenAPIのエンドポイントと仕様が表示されます。 例) http://example-health-api-health.192.168.42.138.nip.io/openapi/ui/
これで、ビジネスロジックがRed Hat OpenShift on IBM Cloud上で起動しました。現時点ではデータベースにはSQLのスキーマーは作成されていますがデータがありません。次の手順で患者の健康記録テストデータをUSERが①の経路でREST APIを使って登録します。
18. 患者の健康記録テストデータ生成プログラムの準備
-
患者の健康記録テストデータを作成するgenerate.shを実行してテストデータをREST APIでMySQLに登録します。generate.shの中では合成された現実的な(ただし実際ではない)患者データと関連する健康記録をさまざまな形式で出力することができる synthea と呼ばれるプログラムが使用されています。
- スクリプト名: example-health-jee-openshift/generate/generate.sh
-
generate.shを実行するのに必要なNode.jsのcsvtojsonをインストールします。
# ls
example-health-api generate LICENSE readme_images README.md screenshots
# cd generate/
# ls
generate.sh package.json README.md
# pwd
/root/example-health-jee-openshift/generate
# yum install npm
Installing:
npm x86_64 1:3.10.10-1.6.17.1.1.el7 epel 2.5 M
Installing for dependencies:
libuv x86_64 1:1.30.1-1.el7 epel 138 k
nodejs x86_64 1:6.17.1-1.el7 epel 4.7 M
# npm install csvtojson
synthea-generate@1.0.0 /root/example-health-jee-openshift/generate
└─┬ csvtojson@2.0.10
├── bluebird@3.7.1
├── lodash@4.17.15
└─┬ strip-bom@2.0.0
└── is-utf8@0.2.1
# pwd
/root/example-health-jee-openshift/generate
- csvtojsonが使える様にPATHを通します。
# PATH=$PATH:/root/example-health-jee-openshift/generate/node_modules/csvtojson/bin
19. Routeのデフォルトタイムアウト値変更
前の手順で作成したRoute名: example-health-api のデフォルトタイムアウト値を60分に変更します。USERがgenerate.shを実行するとOpenShiftのアプリケーションロードバランサー(ALB)のrouterを通ってOpen LibertyのPod(コンテナ)をREST APIで呼出します。OpenShiftのrouterのデフォルトのタイムアウトは30秒のため、デフォルト値ではテストデータを投入する様な長時間実行されるREST API呼出しには短すぎるためタイムアウト値を長く設定する必要があります。
# oc annotate route example-health-api --overwrite haproxy.router.openshift.io/timeout=60m
route.route.openshift.io/example-api annotated
変更した結果は「 oc describe route 」コマンドで確認できます。
# oc describe route example-health-api
Name: example-health-api
Namespace: health
Created: 13 minutes ago
Labels: app=example-health-api
Annotations: haproxy.router.openshift.io/timeout=60m
openshift.io/host.generated=true
Requested Host: example-health-api-health.192.168.42.138.nip.io
exposed on router router 13 minutes ago
Path: <none>
TLS Termination: <none>
Insecure Policy: <none>
Endpoint Port: http
Service: example-health-api
Weight: 100 (100%)
Endpoints: 172.17.0.10:9080
20. 患者の健康記録テストデータプログラムの実行
それでは実行します。generate.shのオプションは -p は人口、-u は routeで公開したホスト名です。今回は150人のデータを登録します。
# ./generate.sh -p 150 -u http://example-health-api-health.192.168.42.138.nip.io
Cloning into 'synthea'...
remote: Enumerating objects: 38, done.
remote: Counting objects: 100% (38/38), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 31698 (delta 7), reused 21 (delta 2), pack-reused 31660
Receiving objects: 100% (31698/31698), 605.79 MiB | 9.81 MiB/s, done.
Resolving deltas: 100% (18183/18183), done.
Checking out files: 100% (663/663), done.
BUILD SUCCESSFUL in 30s
4 actionable tasks: 2 executed, 2 up-to-date
BUILD SUCCESSFULが表示された後から登録完了まで数分で終わりました。途中の状況を確認したい場合は、Open LibertyのPod(コンテナ)のログを「 oc logs -f example-health-api-<任意の英数字> 」コマンドを実行して確認してください。
21. 登録した患者の健康記録データの確認
患者の一覧を取得するAPI「 /resources/v1/getInfo/patients 」を使って、患者の健康記録データが登録されているか確認します。curlでURLにホスト名/resources/v1/getInfo/patientsを指定して実行すると事前に登録した件数と同じ150人分の患者のデータが取得できます。
# curl -X GET "http://example-health-api-health.192.168.42.138.nip.io/resources/v1/getInfo/patients" -H "accept: */*"
{"ResultSet Output":[{"CA_DOB":"1962-10-
<<<省略>>>
09","CA_FIRST_NAME":"Sergio","CA_GENDER":"M","CA_LAST_NAME":"Castellanos"},{"CA_DOB":"1988-06-06","CA_FIRST_NAME":"Lorraine","CA_GENDER":"F","CA_LAST_NAME":"Ledner"},{"CA_DOB":"2018-01-29","CA_FIRST_NAME":"Shemika","CA_GENDER":"F","CA_LAST_NAME":"Terry"},{"CA_DOB":"1954-03-26","CA_FIRST_NAME":"Clyde","CA_GENDER":"M","CA_LAST_NAME":"Ferry"},{"CA_DOB":"1946-03-25","CA_FIRST_NAME":"Bobby","CA_GENDER":"M","CA_LAST_NAME":"Krajcik"}],"StatusCode":200,"StatusDescription":"Execution Successful"}
22. まとめ
これでExample HealthはモノリシックなJava EE アプリケーション構造からビジネスロジック部分を分割し、MiniShiftのOpenShift上で動作するOpen Libertyで実行されているビジネスロジック用のJava EE アプリケーションとして稼働させることに成功しました。実際に患者の健康管理テストデータ生成プログラム(generater.sh)を使ってREST API を使用してMySQLデータベースに患者の健康管理テストデータを取り込み、Java EE アプリケーションからそのデータにアクセスする方法も実行することができました。
ここまでのステップでモダナイゼーションの旅も一山越えた感じですが、このままでは、REST APIでしか呼応できないため、サービスとしては不十分です。次のステップからモノリシックなJava EEアプリケーションから分割したもう一つの患者用UIのNode.jsアプリケーションをOpenShiftにデプロイして、今回作成したビジネスロジック用のJava EEアプリケーションと結合したいと思います。
続きは、「 OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた(2)」 の投稿に続きます。