IBMのソリューションやソフトウェアに対し、そのテクニカルコミュニティーにおいて高度な貢献をしたエンジニアを表彰する制度「IBM Champions」。今回はIBM Champion for Cloud 2019に選出された平岡大祐氏に、その知見・ノウハウを体感できる記事を執筆していただいた。昨今のDXトレンドなどについて聞いたショートインタビューとともに、3回にわたって「Red Hat OpenShift on IBM Cloud」の実践的な活用方法をお届けする。2回目はマイクロサービス化と運用監視について。
DX(デジタルトランスフォーメーション)トレンドが進展し、ビジネスが「ITを使った体験価値の競争」に変容して久しい。テクノロジーはビジネスのコアとなり、それを使いこなすエンジニアこそが、ビジネスの推進役となる時代が到来したといえるだろう。
そうした中、IBMが主催しているのが「IBM Champions」だ。IBMのソリューションやソフトウェアに対し、年間を通してテクニカルコミュニティーに優れた貢献をしたエンジニアを表彰する制度で2008年に創設。2018年までにグローバルで650人、うち日本人は51人が選出されている。開発者、ビジネスリーダー、経営層など、全世界のITに携わる人に向けたインフルエンサーとして認定され、「IBM Analytics Champions」「IBM Cloud Champions」「IBM Collaboration&Talent Champions」「IBM Power Systems Champions」「IBM Storage Champions」「IBM Z Champions」の6部門で表彰。IBMのグローバルイベント、公式サイト、ブログなどを通じた意見発信の機会が与えられる。
今回はIBM Champion for Cloud 2019に選出された平岡大祐氏に、その知見・ノウハウを体感できる記事を執筆していただいた。昨今のDXトレンドなどについて聞いたショートインタビューとともに、3回にわたって「Red Hat OpenShift on IBM Cloud」の実践的な活用方法をお届けする。手を動かして“最先端の視点”を体感してはいかがだろうか。
IBM Champion for Cloud 2019
2002年からエンジニアとして、業務系、基幹系システム、プロダクトの設計、開発、運用などさまざま業務に従事。2016年の夏に2カ月でIBM CloudのベアメタルサーバにOpenShift環境を構築し、2017年1月から本番環境で稼働させ、運用する業務を経験。以降、コンテナやOpenShiftの業務を多く経験するようになる。2018年3月刊行の『コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤』(翔泳社)に、OpenShiftに関する章の共著で参加。Red Hat認定資格「Red Hat Certified Specialist in OpenShift Administration」を取得している。
―― 今の経営環境で求められているアプリケーションのアーキテクチャとは?
マイクロサービスをコンテナにまとめてデプロイする仕組みにモダナイゼーションすることが求められていると思います。アプリケーション単位でもいいので、いったんクラウドにリフトして、コンテナやマイクロサービスのアーキテクチャにシフトする「リフト&シフト」という方法もあります。また、ヨーロッパのIBM Championから聞いた事例ですが、既存のメインフレームのようなSoR(Systems of Record)領域にAPI連携の仕組みを入れて、SoE(Systems of Engagement)領域は新規でコンテナやマイクロサービスの開発を行い、SoR領域と連携させるアーキテクチャもあります。
―― マイクロサービスアークテクチャの意義とは?
リリーススピードを速めるために、アプリケーション単位よりもビジネスに直結する“機能”単位という具合にリリースの粒度を小さくできることです。ビジネス要請に応えるマイクロサービスにするには、ドメイン駆動設計が求められると思います。モノリシックなサービスをマイクロサービスアークテクチャに変えるには、ドメイン駆動設計ができていないとデータの不整合が起こるので、うまく切り出せません。
―― コンテナアプリケーションの運用監視の課題とあるべき姿
コンテナアプリケーションが多用されるマイクロサービス化が進むと、サービス群がちゃんと連携して動いているか分かりにくくなります。これには、「IBM Cloud Kubernetes Service(IKS)」に搭載されている「Istio」のようなサービスメッシュの仕組みが求められます。「Red Hat OpenShift Service Mesh」が2019年9月にリリースされたことで、ベンダーのサポートがある、つまり商用運用にも耐え得るものが出てきたといえます。マイクロサービスの本番運用は加速すると考えます。
今回の記事では、モダナイゼーションと運用監視がいかに簡単に行えるかを見ていただきたいと思います。
※以下は日本アイ・ビー・エムから提供されたコンテンツを、許諾を得て転載したものです。このため、用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。
IBM Champion for Cloud 2019の平岡です。今回はアプリケーションについてです。前半はOpenShiftによるJava EEアプリケーションがどれだけ簡単にモダナイゼーションできるか、後半ではIBM Cloudの便利なモニタリング・ロギングサービスであるSysdigとLogDNAについてまとめてあります。
IBM Code Patternsに「Java EEとOpen Libertyを使用した架空の医療アプリ内にマイクロサービスをデプロイする」というコードパターンがあります。これから、このコードパターンを使ってJava EEアプリケーションのモダナイゼーションを体感したいと思います。モダナイゼーションしたJava EEアプリケーションは前回作成した「Red Hat OpenShift on IBM Cloud」にデプロイします。
この一連の流れはオンプレミスシステムからクラウドへの移行の手順に相当するとご想像いただくとイメージしやすいでしょうか。これからみなさんはソリューションアーキテクトになりきって、これからクラウドで広がるモダナイゼーションの旅を体感しましょう。
Example Healthは架空の医療会社です。この会社には歴史があり、数十万の患者記録があります。もともと、Example Healthはアプリケーションにモノリシックアプリケーション構造を使用していました。それらのアプリケーション構造は、メインフレーム上のDb2データベースに接続されたWebSphereで実行されるフルスタックのJavaアプリケーションでした。Example Healthの元のアーキテクチャは次の通りです。
最近、Example Healthはアプリケーションをモダナイズし、マイクロサービスに分割することを決定しました。彼らはビジネスロジック用のOpen Libertyで実行されているJava EEアプリケーションと患者UI用のNode.jsアプリケーションに接続されたSQLデータベースに移動することを決定したのです。さらに、Example Healthはこれらのアプリケーションを「Red Hat OpenShift on IBM Cloud」、SQLデータベースはIBM CloudのDaaSの一つである「Compose for MySQL」に導入することも決定しました。 Example Healthの新しいアーキテクチャは次の通りです。
「Red Hat OpenShift on IBM Cloud」に移行した結果、Example Healthは容易に機能拡張できるようになりました。間もなく、健康記録管理用アプリケーションと分析アプリケーションを含む新しいマイクロサービスが含まれるようになるのです。
1.作業端末に次の前提条件ツールをインストールします。
$ yum install maven
- IBM Cloud Toolのインストール $ curl -sL https://ibm.biz/idt-installer | bash - Dockerの自動起動設定と起動 $ systemctl enable --now docker $ systemctl status docker
docker-ce-stableリポジトリのDocker(バージョン19.03.2)がインストールされます。(2019年10月時点)後の手順で使用するDockerfileではDockerのバージョン17.09.0-ceで追加されたADD/COPY commandsコマンドの--chownフラグを使用します。CentOS 7のDockerのバージョンは1.13.1で--chownフラグがないため、Dockerビルドで失敗します。そのため、docker-ce-stableリポジトリのDockerをインストールしています。
2019年10月時点では「Red Hat OpenShift on IBM Cloud」のバージョンは3.11、同じバージョンのツールを入手してください。
- OpenShift oc Client Toolsダウンロード $ curl -LO https://github.com/openshift/origin/releases/download/v3.11.0/openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz - ocコマンドとkubectlコマンドを/usr/local/sbinに配置 $ tar xf openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz --strip=1 \ -C /usr/local/sbin openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit/oc \ openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit/kubectl
IBM CloudのCompose for MySQLのMySQLのバージョンは5.7です。(2019年10月時点)同じバージョンのClientを導入する場合はCentOS 7.7のmariadbのパッケージは削除してから導入を行います。
$ yum remove mariadb-libs $ yum localinstall \ http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm $ yum install mysql-community-client
2.「Compose for MySQL」データベースを作成します。
IBM Cloudポータルにログインし、ダッシュボード画面から「カタログ」「データベース」の順に遷移し「Compose for MySQL」をクリックします。
IBM CloudではDb2、PostgreSQLなど様々な高可用性、冗長性、自動バックアップ機能を備えているデータベースを使用することができます。
「Compose for MySQL」のサービスに関する説明が表示されます。
「Compose for MySQL」は高可用性、冗長性、自動バックアップ機能を備えていますが、残念ながら東京は現時点ではないため、今回はダラスを選択しています。
「Compose for MySQL」はCloud Foundryの役割(組織、スペース)を利用して、サービスへのアクセスを管理します。Cloud Foundryの役割を設定していない場合は「Compose for MySQL」を作成時に、役割の作成を促すメッセージが出力されます。メッセージに従って役割を作成後、再度、「Compose for MySQL」を作成してください。
入力が終了しましたら、「作成」ボタンを押します。
「Compose for MySQL」のプロビジョニングが始まります。
「Compose for MySQL」データベースのプロビジョニングが終了すると管理画面が表示されます。画面内の「Connection Setting」枠の「Command Line」ボタンを押して表示される「Compose for MySQL」のユーザー、URL、パスワード、ホスト名およびポート番号をメモして置いてください。
3.GitHubのプロジェクトをCloneします。Cloneするとexample-health-jee-openshiftフォルダが作成されます。
$ git clone https://github.com/IBM/example-health-jee-openshift.git $ cd example-health-jee-openshift
4.MySQLクライアントを使用してデータベースとテーブルを作成します。次のSQLファイルを使用して、患者の健康記録データのSQLスキーマをインポートします。
データベースを作成します。
$ mysql -u admin -pパスワード --host ホスト名 --port ポート番号 --ssl-mode=REQUIRED \ -e "CREATE DATABASE health;"
-pとパスワードは間に空白を入れるとエラーになります。「-pパスワード」のように区切りなしに入力する必要があります。
データベースの一覧を出力し、healthデータベースが作成されていることを確認します。
$ mysql -u admin -pパスワード --host ホスト名 --port ポート番号 --ssl-mode=REQUIRED \ -e "show databases;" +--------------------+ | Database | +--------------------+ | information_schema | | compose | | health | | mysql | | performance_schema | | sys | +--------------------+
患者の健康記録データのSQLスキーマをインポートします
$ mysql -u admin -pパスワード --host ホスト名 --port ポート番号 --ssl-mode=REQUIRED \ health < ./example-health-api/samples/health_schema.sql
healthデータベースのテーブル一覧を出力します。SQLスキーマのインポートが正常に終了していると出力結果のテーブルが表示されます。
$ mysql -u admin -pパスワード --host ホスト名 --port ポート番号 --ssl-mode=REQUIRED \ health -e "show tables;" +------------------+ | Tables_in_health | +------------------+ | Allergies | | Appointments | | MESSAGE | | Observations | | Organizations | | Patients | | Prescriptions | | Providers | | SEQUENCE | +------------------+
5.Java EEアプリケーションをビルドします。
$ cd example-health-api $ mvn package
6.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 Digest: sha256:d9413b43aa7612d8ef4bd99398853a9755721e37f7cfa13c4ab76d97cb324683 Status: Downloaded newer image for openliberty/open-liberty:javaee8-ubi-min ---> bb992680821b Step 2/10 : ENV INSTALL_DIR /opt/ol/wlp/ ---> Running in 3cc2402d1213 Removing intermediate container 3cc2402d1213 ---> ff4d2db2923b Step 3/10 : ENV CONFIG_DIR /opt/ol/wlp/usr/servers/defaultServer/ ---> Running in 022fa5a1f6c9 Removing intermediate container 022fa5a1f6c9 ---> 283fa266876c 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 ---> 322226abbe1f Step 5/10 : RUN chmod 644 ${INSTALL_DIR}lib/mysql-connector-java-8.0.16.jar ---> Running in 4dc77423bf85 Removing intermediate container 4dc77423bf85 ---> 201fdb123eb4 Step 6/10 : COPY liberty-mysql/mysql-driver.xml ${CONFIG_DIR}configDropins/defaults/ ---> b4cd2a1d4218 Step 7/10 : COPY liberty/server.xml $CONFIG_DIR ---> 520cd6bf6b1c Step 8/10 : COPY liberty/jvm.options $CONFIG_DIR ---> 868a5c2218ed Step 9/10 : COPY target/health-api.war /opt/ol/wlp/usr/servers/defaultServer/apps ---> 1b335c4fcb28 Step 10/10 : EXPOSE 9080 ---> Running in e6f81752ef6b Removing intermediate container e6f81752ef6b ---> 901666e26ca5 Successfully built 901666e26ca5 Successfully tagged ol-example-health:1
Dockerビルドが成功するとベースイメージのopenliberty/open-libertyと今回作成したol-example-healthイメージが出力されます。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ol-example-health 1 901666e26ca5 26 minutes ago 450MB openliberty/open-liberty javaee8-ubi-min bb992680821b 17 hours ago 445MB
DockerfileのFROM句で指定しているOpen LibertyのベースイメージにはRed Hat UBI(Red Hat Universal Base Image)のRHEL 7を使用しています。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を使ってみたらいかがでしょうか?
7.Docker Hubにリポジトリを作成し、そこにJava EEアプリケーションのDockerイメージをプッシュします。
$ docker tag ol-example-health:1 daihiraoka/ol-example-health:1 $ 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 login -u daihiraoka Login Succeeded $ docker push daihiraoka/ol-example-health:1
今回はCode Patternsの手順でDocker Hubを使いましたが、IBM CloudにはContainer Registryのサービスがあります。通常、商用利用ではIBM Cloud Container Registryを使ってコンテナイメージを管理します。
8.OpenShiftのCLIにログインします。まずはログインに必要なトークンを取得するためにOpenShiftのWebコンソールにログインし、右上のユーザー名をクリックすると表示される「Copy Login Command」をクリックしてください。ログインに必要なコマンドがクリップボードに保存されます。
続いてクリップボードに保存されたログインコマンドをターミナルで実行してOpenShiftにログインします。
$ oc login https://c100-e.jp-tok.containers.cloud.ibm.com:31135 --token=<<トークン>> Logged into "https://c100-e.jp-tok.containers.cloud.ibm.com:31135" as "IAM#<<ユーザー名>>" using the token provided.
9.Example Health用のプロジェクトを作成します。これにより、新しいプロジェクトが作成され、Pod(コンテナ)がデプロイされる作業プロジェクトとして設定されます。
$ oc new-project health
10.ファイル「example-health-api/kubernetes-openshift.yaml」を編集して、containersセクションのimageキーをDocker HubにpushしたJava EEアプリケーションのDockerイメージに変更します。
containers: - name: example-health-api image: ykoyfman/ol-example-health:latest
containers: - name: example-health-api image: daihiraoka/ol-example-health:1
11.example-health-api/create-secrets.shスクリプトを使って「Compose for MySQL」の接続情報を設定します。必要な値はすべて、IBM Cloudの「Compose for MySQL」サービスの管理画面にあります。
#!/bin/bash oc create secret generic db-secrets \ --from-literal=db_username=admin \ --from-literal=db_password=パスワード \ --from-literal=db_host="jdbc:mysql://ホスト名:ポート番号/DB名?sessionVariables=sql_mode=''"
2019年10月時点ではcreate-secrets.shには「DB名/?sessionVariables」と「DB名」と「?」の間に「/」が書かれています。JDBCで接続する時は「/」もDB名の文字列に含まれるため、接続エラーが発生します。そのため「/」を削除してください。
OpenShiftではパスワードなど認証情報はsecretsという機密情報を保持するメカニズムを持つオブジェクトに保持します。そして「Compose for MySQL」の接続情報はPod(コンテナ)の中で環境変数として利用します。環境変数として使うためには次の手順のkubernetes-openshift.yamlでPod(コンテナ)のデプロイを定義するDeploymentオブジェクトの中で、環境変数とsecretsの紐付けを行います。
env: - name: ENV_MYSQL_URL 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設定では、上記で定義した環境変数を使用してデータベース接続のパラメータを設定します。
<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
12.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(コンテナ)に接続できるようになります。
13.しばらく時間が経過すると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-gnlff 1/1 Running 0 2d
Open LibertyのPod(コンテナ)のログは「oc logs -f example-health-api-<任意の英数字>」コマンドを実行すると出力されます。下記のようにOpen Libertyの起動ログが出力されます。
$ oc logs -f example-health-api-7fcb786fb6-gnlff Launching defaultServer (Open Liberty 19.0.0.9/wlp-1.0.32.cl190920190905-0148) on IBM J9 VM, version 8.0.5.40 - pxa6480sr5fp40-20190807_01(SR5 FP40) (en_US) <<省略>> [AUDIT ] CWWKZ0001I: Application health-api started in 6.040 seconds. [AUDIT ] CWWKF0012I: The server installed the following features: [appClientSupport-1.0, appSecurity-2.0, appSecurity-3.0, batch-1.0, beanValidation-2.0, cdi-2.0, concurrent-1.0, distributedMap-1.0, ejb-3.2, ejbHome-3.2, ejbLite-3.2, ejbPersistentTimer-3.2, ejbRemote-3.2, el-3.0, j2eeManagement-1.1, jacc-1.5, jaspic-1.1, javaMail-1.6, javaee-8.0, jaxb-2.2, jaxrs-2.1, jaxrsClient-2.1, jaxws-2.2, jca-1.7, jcaInboundSecurity-1.0, jdbc-4.2, jms-2.0, jndi-1.0, jpa-2.2, jpaContainer-2.2, jsf-2.3, json-1.0, jsonb-1.0, jsonp-1.1, jsp-2.3, jwt-1.0, managedBeans-1.0, mdb-3.2, microProfile-2.1, monitor-1.0, mpConfig-1.3, mpFaultTolerance-1.1, mpHealth-1.0, mpJwt-1.1, mpMetrics-1.1, mpOpenAPI-1.0, mpOpenTracing-1.2, mpRestClient-1.1, opentracing-1.2, servlet-4.0, ssl-1.0, wasJmsClient-2.0, wasJmsSecurity-1.0, wasJmsServer-1.0, webProfile-8.0, websocket-1.1]. [AUDIT ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 22.422 seconds.
14.Java EE アプリケーションをインターネットに公開するためのOpenShiftのオブジェクトであるRouteを作成します。
$ oc expose svc example-health-api route.route.openshift.io/example-health-api exposed
15.Java EE アプリケーションが機能していることを確認します。まず、Routeに割り当てられたホスト名を取得します。
$ oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD example-health-api example-health-api-health.****.jp-tok.containers.appdomain.cloud example-health-api http None
この場合は最初のNAMEのexample-health-apiがRoute名で、次のHOST/PORTのFQDNが生成されたホスト名です。RouteにアクセスがあるとSERVICESのexample-health-apiを通って、Open LibertyのPod(コンテナ)のEndPointのIPアドレスにアクセスします。
Red Hat OpenShift on IBM Cloudで生成されるホスト名の命名規則は下記の通りです。
<ルート名>[ -<プロジェクト名> ].<クラスター名>[ -<任意の英数字> ].<リージョン>.containers.appdomain.cloud
example-health-api-health.jp-tokcluster-5a7e2b4ab65bac806c7e37b385575e75-0001.jp-tok.containers.appdomain.cloud
16.ブラウザウィンドウで、<ホスト名>/openapi/ui/に移動します。Java EEアプリケーションでサポートされるOpenAPIのエンドポイントと仕様が表示されます。
これで、ビジネスロジックがRed Hat OpenShift on IBM Cloud上で起動しました。現時点ではデータベースにはSQLのスキーマは作成されていますがデータがありません。次の手順で患者の健康記録テストデータをUSERが①の経路でREST APIを使って登録します。
17.患者の健康記録テストデータを作成するgenerate.shを実行してテストデータをREST APIでCompose for MySQLに登録します。generate.shの中では合成された現実的な(ただし実際ではない)患者データと関連する健康記録を様々な形式で出力することができる「synthea」と呼ばれるプログラムが使用されています。
18.generate.shを実行するのに必要なNode.jsのcsvtojsonをインストールします。
$ cd /<任意のフォルダ>/example-health-jee-openshift/generate $ yum install epel-release $ yum install npm $ npm install csvtojson - csvtojsonが使えるようにPATHを通します。 $ PATH=$PATH:/root/example-health-jee-openshift/generate/node_modules/csvtojson/bin
19.前の手順で作成した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 <route名>」コマンドで確認できます。
$ oc describe route example-health-api Name: example-health-api Namespace: health Created: 2 days ago Labels: app=example-health-api Annotations: haproxy.router.openshift.io/timeout=60m openshift.io/host.generated=true
それでは実行します。generate.shのオプション「-p」は患者の人数、「-u」はrouteで公開したホスト名です。今回は10人のデータを登録します。
$ ./generate.sh -p 10 -u http://example-health-api-health.jp-tokcluster-****.jp-tok.containers.appdomain.cloud Cloning into 'synthea'... remote: Enumerating objects: 120, done. remote: Counting objects: 100% (120/120), done. remote: Compressing objects: 100% (93/93), done. remote: Total 31035 (delta 30), reused 60 (delta 7), pack-reused 30915 Receiving objects: 100% (31035/31035), 509.89 MiB | 19.97 MiB/s, done. Resolving deltas: 100% (17840/17840), done. Population: 10 Seed: 1 Provider Seed:1570395844755 Location: Arizona Min Age: 0 Max Age: 140 7 -- Karri995 McDermott739 (8 y/o F) Flagstaff, Arizona 2 -- Stanley702 Kris249 (31 y/o M) Prescott, Arizona 1 -- Sofia418 Arteaga169 (23 y/o F) Avondale, Arizona 8 -- Tresa661 Littel644 (39 y/o F) Mesa, Arizona 3 -- Shayne60 Barton704 (58 y/o M) Fountain Hills, Arizona 6 -- Octavio643 Mante251 (68 y/o M) Phoenix, Arizona 5 -- Janise4 Jakubowski832 (56 y/o F) Yuma, Arizona 4 -- Clyde817 Ferry570 (70 y/o M) Phoenix, Arizona 10 -- Opal236 Reichel38 (40 y/o F) Parker, Arizona 9 -- Victoria535 Burgos636 (54 y/o F) Tucson, Arizona {alive=10, dead=0} BUILD SUCCESSFUL in 11s 4 actionable tasks: 4 executed
BUILD SUCCESSFULが表示された後から登録完了まで約20分程度かかりました。途中の状況を確認したい場合は、Open LibertyのPod(コンテナ)のログを「oc logs -f example-health-api-<任意の英数字>」コマンドを実行して確認してください。
20.患者の一覧を取得するAPI「/resources/v1/getInfo/patients」を使って、患者の健康記録データが登録されているか確認します。
curlでURLにホスト名/resources/v1/getInfo/patientsを指定して実行すると事前に登録した件数と同じ10人分の患者のデータが取得できます。
$ curl -X GET "http://example-health-api-health.jp-tokcluster-****.jp-tok.containers.appdomain.cloud/resources/v1/getInfo/patients" -H "accept: */*" {"ResultSet Output":[{"CA_DOB":"1949-03-19","CA_FIRST_NAME":"Clyde","CA_GENDER":"M","CA_LAST_NAME":"Ferry"},{"CA_DOB":"2003-10-18","CA_FIRST_NAME":"Lawerence","CA_GENDER":"M","CA_LAST_NAME":"Pollich"},{"CA_DOB":"1999-04-21","CA_FIRST_NAME":"Opal","CA_GENDER":"F","CA_LAST_NAME":"Larkin"},{"CA_DOB":"1980-08-30","CA_FIRST_NAME":"Tresa","CA_GENDER":"F","CA_LAST_NAME":"Green"},{"CA_DOB":"1987-11-06","CA_FIRST_NAME":"Stanley","CA_GENDER":"M","CA_LAST_NAME":"Kris"},{"CA_DOB":"2011-05-01","CA_FIRST_NAME":"Karri","CA_GENDER":"F","CA_LAST_NAME":"McDermott"},{"CA_DOB":"1963-09-16","CA_FIRST_NAME":"Janise","CA_GENDER":"F","CA_LAST_NAME":"Metz"},{"CA_DOB":"2009-04-15","CA_FIRST_NAME":"Alphonse","CA_GENDER":"M","CA_LAST_NAME":"Hand"},{"CA_DOB":"1993-09-13","CA_FIRST_NAME":"Pedro","CA_GENDER":"M","CA_LAST_NAME":"Perea"},{"CA_DOB":"1951-02-28","CA_FIRST_NAME":"Octavio","CA_GENDER":"M","CA_LAST_NAME":"Mante"}],"StatusCode":200,"StatusDescription":"Execution Successful"}
これでExample HealthはモノリシックなJava EE アプリケーション構造からビジネスロジック部分を分割し、「Red Hat OpenShift on IBM Cloud」上で動作するOpen Libertyで実行されているビジネスロジック用のJava EEアプリケーションとして稼働させることに成功しました。実際に患者の健康管理テストデータ生成プログラム(generater.sh)を使ってREST API を使用して「Compose for MySQL」データベースに患者の健康管理テストデータを取り込み、Java EEアプリケーションからそのデータにアクセスする方法も実行することができました。
ここまでのステップでモダナイゼーションの旅も一山越えた感じですが、このままでは、REST APIでしか呼応できないため、サービスとしては不十分です。次のステップからモノリシックなJava EEアプリケーションから分割したもう一つの患者用UIのNode.jsアプリケーションを「Red Hat OpenShift on IBM Cloud」にデプロイして、今回作成したビジネスロジック用のJava EEアプリケーションと結合したいと思います。
患者用UI(ユーザーインターフェイス)のモダナイゼーションは、「Node.js、Source-to-Imageツールキット、OpenShiftによるアプリケーションのモダナイズ―Kubernetesベースのマイクロサービスで従来型の患者記録アプリを変換する」というコードパターンを使います。UIは、オープン・スタンダードなJavaScriptと最新のユニバーサルCSS、およびレイアウト用のHTML5 Canvasでプログラムされています。
早速、患者用UIを作り始めましょう。コードパターンの手順はGUI操作で、1回目の記事で紹介したOpenShiftのWebコンソールを使ってコンテナをデプロイする方法です。ただ、今回私達はソリューションアーキテクトですので今回はCLI操作でGUIと同じ手順を再現してみましょう。
1.まず、コードパターンのGitHubのリポジトリ「IBM/node-s2i-openshift」で「Fork」ボタンをクリックして自分のGitHubのリポジトリにフォークします。GitHubのアカウントをお持ちでない方は事前に作成してください。
2.コードパターンでは新しいプロジェクトを作成していますが、ここでは前の手順で作成したExample Health用のプロジェクトを使います。healthプロジェクトに移動します。
$ oc project health
3.Red Hat UBI(RHEL 7)のNode.js 10コンテナイメージをOpenShiftプロジェクトにインポートします。コンテナイメージをプロジェクト間で共有するユースケースではOpenShiftプロジェクトにコンテナイメージをインポートします。
$ oc import-image ubi7/nodejs-10 --from=registry.access.redhat.com/ubi7/nodejs-10 \ -n openshift --confirm
デフォルトで用意されているカタログのベースイメージがCentOSのため、本番環境での使用を意識してRed Hat UBIを使用します。この記事の掲載後、何かしらの理由でインポートできない場合はこの手順はスキップしてください。この後の手順でCentOSを使用する場合の手順を用意しています。
4.インポートの結果を確認します。OpenShiftプロジェクトのImageStream(is)の一覧を出力します。
$ oc get is -n openshift NAME DOCKER REPO TAGS UPDATED dotnet docker-registry.default.svc:5000/openshift/dotnet latest,2.1,2.0 5 weeks ago dotnet-runtime docker-registry.default.svc:5000/openshift/dotnet-runtime latest,2.0,2.1 5 weeks ago httpd docker-registry.default.svc:5000/openshift/httpd 2.4,latest 5 weeks ago jenkins docker-registry.default.svc:5000/openshift/jenkins 1,2,latest 5 weeks ago mariadb docker-registry.default.svc:5000/openshift/mariadb 10.1,10.2,latest 5 weeks ago mongodb docker-registry.default.svc:5000/openshift/mongodb 2.4,2.6,3.2 + 3 more... 5 weeks ago mysql docker-registry.default.svc:5000/openshift/mysql 5.7,latest,5.5 + 1 more... 5 weeks ago nginx docker-registry.default.svc:5000/openshift/nginx 1.8,latest,1.10 + 1 more... 5 weeks ago nodejs docker-registry.default.svc:5000/openshift/nodejs 0.10,10,4 + 4 more... 5 weeks ago nodejs-10 docker-registry.default.svc:5000/openshift/nodejs-10 latest 2 hours ago perl docker-registry.default.svc:5000/openshift/perl 5.16,5.20,5.24 + 2 more... 5 weeks ago
nodejs-10が今回インポートしたコンテナイメージのImageStreamです。一覧で表示されるnodejsやdotnetは、下記画像のWebコンソールのカタログと同じです。OpenShiftはCLIでも簡単にアプリケーションをデプロイする仕組みを用意しています。
ImageStreamはKubernetesにはないOpenShiftにのみあるオブジェクトです。ImageStreamは、C言語でいうとポインタ、RDB(リレーショナルデータベース)でいうとViewみたいなもので、Dockerレジストリのコンテナイメージの内部メタデータを使って、コンテナイメージの情報を参照して、コンテナイメージを管理します。ImageStreamの中には、コンテナイメージの実体は保持しません。
ImageStreamの主な機能として、
があります。詳細はOpenShiftの公式ドキュメント「3.5.2 イメージストリーム」を確認ください。
5.OpenShiftのS2I(Source to Image)を使って患者UI用のアプリケーションをビルド・デプロイします。
$ oc new-app openshift/nodejs-10~https://github.com/daihiraoka/node-s2i-openshift.git --name='patientui' --context-dir='/site'
openshift/nodejs-10はベースとなるコンテナイメージのImageStream名(openshiftプロジェクトのnodejs-10)、~(チルダ)で挟んで右側が、ソースコードリポジトリ、--nameは生成するアプリケーションの名前、--context-dirはソースコードリポジトリのサブディレクトリを指定しています。S2I(Source to Image)はベースとなるコンテナイメージとソースコード使って新しいコンテナイメージを生成するRed Hat独自のビルド方式です。
Red Hat UBIがインポートできなかった場合は、openshift/nodejs-10をopenshift/nodejs:10に変更してCentOS 7のnodejsを使用してください。
実行結果は以下のように出力されます。
$ oc new-app openshift/nodejs-10~https://github.com/daihiraoka/node-s2i-openshift.git --name='patientui' --context-dir='/site' --> Found image fca7ff7 (3 weeks old) in image stream "openshift/nodejs-10" under tag "latest" for "openshift/nodejs-10" * A source build using source code from https://github.com/daihiraoka/node-s2i-openshift.git will be created * The resulting image will be pushed to image stream tag "patientui:latest" * Use 'start-build' to trigger a new build * This image will be deployed in deployment config "patientui" * Port 8080/tcp will be load balanced by service "patientui" * Other containers can access this service through the hostname "patientui" --> Creating resources ... imagestream.image.openshift.io "patientui" created buildconfig.build.openshift.io "patientui" created deploymentconfig.apps.openshift.io "patientui" created service "patientui" created --> Success Build scheduled, use 'oc logs -f bc/patientui' 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/patientui' Run 'oc status' to view your app.
oc new-appコマンドを実行すると、「patientui」という名称でこれから作成されるコンテナイメージを管理するためのImageStream、ビルドするためのBuildConfig、デプロイするためのDeploymentConfig、IPで通信するためのServiceが作成されます。そして、BuildConfigはBuildConfigの作成をトリガーにコンテナのビルドが自動で始まり、ビルドが完了(DockerレジストリにPush)するとpatientuiのImageStreamにバージョン履歴が追加されます。するとDeploymentConfigはImageStreamのバージョン履歴の変更を検出して、自動的にPod(コンテナ)のデプロイを開始し、アプリケーションが利用できるようになります。
このようにOpenShiftはS2I(Source-to-Image)、ImangeStreamを使って自動ビルド・デプロイを標準で利用できます。KubernetesではDeploymentを使ってコンテナをデプロイしますが、ImangeStreamのような概念はスコープ外です。Kubernetesに開発のスコープまでカバーするのがOpenShiftの特徴です。
しばらくするとpatientui-1-<英数字>のSTATUSがRunningに変わります。
$ oc get pod NAME READY STATUS RESTARTS AGE patientui-1-build 0/1 Completed 0 2m patientui-1-lpql7 1/1 Running 0 5m
6.患者用UIアプリケーションをインターネットに公開するためのRouteを作成します。
$ oc expose svc/patientui route.route.openshift.io/patientui exposed $ oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD patientui patientui-health.****.containers.appdomain.cloud patientui 8080-tcp None
7.ブラウザでホスト名をアクセスします。
デフォルトではモックモードで動作しています。nameとpassword共にtestを入力するとログインすることができます。 ここでは、患者UIとビジネスロジックを結合するために、「settings」をクリックして画面遷移します。
8.赤枠に、ビジネスロジック用のJava EEアプリケーションのAPIのURLを入力して、「java」をクリックします。
http://example-health-api-health.****.jp-tok.containers.appdomain.cloud/resources/v1/
9.ログイン情報を確認するために、healthデータベースのPatientsテーブルからuser_idとpasswordを取得します。
$ mysql -u admin -pOPBHZLO --host sl**.dblayer.com --port 26170 --ssl-mode=REQUIRED \ health -e "select first_name,last_name,birthdate,user_id,password from Patients;" +------------+-----------+------------+------------+------------+ | first_name | last_name | birthdate | user_id | password | +------------+-----------+------------+------------+------------+ | Clyde | Ferry | 1949-03-19 | clydef | clydef | | Lawerence | Pollich | 2003-10-18 | lawerencep | lawerencep | | Opal | Larkin | 1999-04-21 | opall | opall | | Tresa | Green | 1980-08-30 | tresag | tresag | | Stanley | Kris | 1987-11-06 | stanleyk | stanleyk | | Karri | McDermott | 2011-05-01 | karrim | karrim | | Janise | Metz | 1963-09-16 | janisem | janisem | | Alphonse | Hand | 2009-04-15 | alphonseh | alphonseh | | Pedro | Perea | 1993-09-13 | pedrop | pedrop | | Octavio | Mante | 1951-02-28 | octaviom | octaviom | +------------+-----------+------------+------------+------------+
10.Clydeさんの患者情報にログインするためにnameとpasswordに「clydef」を入力して「Sign In」ボタンをクリックします。
11.ログインするとClydeさんの個人情報、予約履歴、処方記録が表示されます。
これで患者用UIのNode.jsアプリケーションとビジネスロジック用のJava EEアプリケーションの結合ができました。
そろそろJava EEアプリケーションモダナイゼーションの旅も終わりです。
この旅では
について、2つのコードパターンを使ってモダナイゼーションを体感しました。次は、架空の会社ではなくみなさんの旅を始める時です。
自分のパソコンで今回の手順を試すことができるようにQiitaに「OpenShiftによるJava EEアプリケーションのモダナイゼーションをやってみた。」を投稿しました。是非お試しください。
Red Hat OpenShift on IBM Cloudをプロビジョニングした瞬間から、クラスター内部で何が起こっているか知りたいと思います。問題を先取り、問題に対処するためには、モニタリング、ロギングが必要です。
IBM Cloudには、IBM Log Analysis with LogDNAとIBM Cloud Monitoring with Sysdigがモニタリング・ロギングサービスとして用意されています。このサービスのいい所は3ステップでモニタリング・ロギングを開始できることです。
Sysdigに限って言えば下記のコマンドを実行するだけで、Sysdigエージェントのコンテナが起動し、モニタリング・ソースの転送が開始します。
curl -sL https://ibm.biz/install-sysdig-k8s-agent | bash -s -- -a <認証鍵> \ -c ingest.jp-tok.monitoring.cloud.ibm.com -ac 'sysdig_capture_enabled: false' (前提:ibmcloud loginコマンドでログイン済み、OpenShiftにLogin済み)
LogDNAも少ないステップでログの転送を開始してくれます。SysdigとLogDNAのセットアップの詳細はIBM Cloudのドキュメント「クラスターの正常性をモニターするためにLogDNAおよびSysdigアドオンをセットアップする」をご覧ください。
同じOpenShiftのワーカー・ノードで実行している他のコンテナおよびワーカー・ノード自体から、LogDNAはログを収集し、Sysdigはシステムコールから、必要なすべてのデータ(ホストメトリック、ネットワークメトリック、カスタムアプリケーションメトリック、セキュリティイベント)を抽出します。これらのデータはすべてエージェントからアクセス・キーを使って認証しIBM CloudのSysdig・LogDNAインスタンスに転送されます。そして、Web UIで確認することができる仕組みになっています。
それではSysdigとLogDNAの特徴について紹介したいと思います。
IBM Cloud内で動作しているIBM Kubernetes Service(IKS)、仮想サーバ(VSI)、物理サーバ(BMS)などのリソースにエージェントを導入してIBM Cloud内のリソース、アプリケーションを一括にモニタリングすることができます。
Sysdig MonitorというWeb UIを開くと表示されるExploreビューでは、OpenShiftクラスター内のすべてのプロジェクト(ネームスペース)を表示し、ワーカー・ノード、Pod、Serviceなどの健全性などの情報を様々なダッシュボードとメトリックを確認できます。
下の図は、Example Healthのビジネスロジックと患者用UIのネットワークトラフィックのトポロジー図です。リアルタイムでアプリケーション層の論理依存性が更新されます。この図では、ユーザーがアクセスすると初めに通過するOpenShiftのrouterから、患者用UIのPod(コンテナ)、ビジネスロジック用のOpen LibertyのPod(コンテナ)、Compose for MySQLの論理依存性が描画されています。なお、トポロジー図にはネットワークトラフィック以外にCPU使用率、応答時間のダッシュボードが用意されています。
コンテナ監視ではPod(コンテナ)は常に生き死にして状況が変わるため、ワーカー・ノードのリソース変動など監視の定義やしきい値の見直しは常に必要です。Sysdigでは、Sysdig Monitorでダッシュボードやメトリックの中で、監視したい項目を見つけると、監視対象をクリックして「Create Alert」をクリックするだけで、監視定義を作成することができます。
今回、Example Healthのhealthプロジェクトの患者用UIのPod(コンテナ) patientui-1-<英数字>の平均CPU使用率の監視を追加したいと思います。
監視の定義画面が表示されます。MetricとScopeはすでに選択しているので、Trigger(しきい値)とNotify(通知方法)を設定するだけです。今回は過去10分間、平均CPU使用率が50%を超えるとアラートをSlackに通知するように設定しました。
設定完了後、すでに平均CPU使用率は50%を超えていたため、Slackにアラートが飛んできます。
Sysdigには、コンテナの「CrashLoopBackOff」、「Failed to pull image」、OpenShiftのワーカー・ノードが正常でない時の「Node Not Ready」など監視定義が準備されています。監視定義の有効/無効は、Enabledボタンをクリックして有効/無効にするだけで簡単です。アラートの詳細についてはIBM Cloudのドキュメント「IBM Cloud Monitoring with Sysdig - アラート」を参照してください。
これまでのNagiosなどの監視システムでは監視設定はファイルベースで、比較的大きな組織では部署をまたいで監視設定しなければならなく、監視設定が反映されるまでリードタイムが長い傾向がありました。
Sysdigを使えば開発、運用関係なくいつでもワーカー・ノード、コンテナの状態が見ることができますし、監視の設定変更もすぐにすることができます。今回触れていませんが、イベント発生時のCaptureを有効にするとOpenShiftのワーカー・ノード全体のstrace、syscallなどの情報を取得してSysdig Inspectを使ってデバッグすることもできます。
Sysdigの導入は簡単で、IBM Cloud Monitoring with Sysdigは試用・無料版もあります。ドキュメントも充実しているので「IBM Cloud Monitoring with Sysdig 入門チュートリアル」を参考にまずはSysdigを始めてみてはいかがでしょうか。
LogDNAの主な機能として以下の4つがあります。
LogDNAのWeb UIを開くとログの一覧が出力されます。タグ、データソース、アプリケーション、ログレベルからログを絞り込んで目的のログを表示させることができます。
下記画像は、患者用UI(patientui)のアプリケーションで絞り込んで出力された、アプリケーション(Nodejs)のログです。どのPod(コンテナ)で動作して、その時のNodejsのアプリケーションログがわかります。
次に、ログの出力、アラート通知、グラフの描画を1回目の記事で作成した3つのデータセンター(Tok02、Tok04、Tok05)に展開したコンテナのIPアドレスとホスト名が出力されるhelloworldのPod(コンテナ)を使って試しました。
$ oc get pod -o wide -n phptest NAME READY STATUS RESTARTS AGE IP NODE helloworld-3-4srt7 1/1 Running 0 54s 172.30.121.230 10.192.17.136 helloworld-3-qmn4g 1/1 Running 0 54s 172.30.138.246 10.193.80.235 helloworld-3-tm6cw 1/1 Running 0 54s 172.30.199.28 10.212.36.4
helloworldのアプリケーションでログを絞り込んで、Apache Benchでアクセスすると赤枠のPod(コンテナ)で各データセンターに展開されたPod(コンテナ)に均等にアクセスしているのがわかります。
ログの検索条件は、ログ検索Viewとして保存して定型利用することができます。ログ検索ViewにはAlert機能を追加することができます。今回は試しにアプリケーション(Apps)が「helloworld」で「レスポンスが404」の場合はSlackに通知するというログ検索Viewを作成しました。
LogDNAで通知条件を検出するとSlackには下記のようにメッセージを受信します。
グラフ描画も検索条件の絞り込みを行なって、「Add Graph」ボタンを押すだけでグラフが描画されます。今回は、アプリケーション「app」が「helloworld」のグラフを設定しました。
下図はhelloworldアプリケーションのhttpアクセスログで、一度グラフを作成すると常に更新し続けます。さらに、時系列の絞り込みや、フリーワードによる絞り込みができます。例えば、今回の図のようなhttpのアクセスログではhttpの応答コードの404、200で絞り込んで調査することができます。
ここまでの説明でLogDNAもWeb UIのみでログの調査・管理・監視が完結して簡単に利用できることがわかっていただけと思います。IBM Log Analysis with LogDNAの試用・無料版では、最新のログのみ参照で、検索ができない制約がありますが、確認はできます。有償版にアップグレードしたとしてもログの容量料金が安いので気軽に試せます。ドキュメントも充実しているので「IBM Log Analysis with LogDNA - 入門チュートリアル」を参考にLogDNAを始めてみてはいかがでしょうか。
IBM Cloudでは、利用者はSysdigとLogDNAのインスタンスを作成して、ホストにエージェントを設置するだけでモニタリングできます。さらにWeb UIで完結するため、いつでも、どこでも、管理者、開発者問わず、監視、トラブルシューティング、アラートの定義を行うことができます。そのため、例えば監視設定では従来のファイルベースで設定していた監視手法に比べると、リードタイムが大幅に短縮することが期待できることでしょう。便利すぎます。
コンテナの監視は従来の監視と違うところがありますが、IBM CloudのSysdigとLogDNA試用・無料版がありすぐ試せます。みなさんのこれまでの経験とベストプラクティスに基づいてコンテナの監視を始めてみてはいかがでしょうか?
次回は、モダナイゼーションしたExample Healthのアプリケーションを使って、より実践的に開発、検証、本番環境へのリリースを想定したOpenShiftでDevOpsを取り上げます。
Copyright © ITmedia, Inc. All Rights Reserved.
提供:日本アイ・ビー・エム株式会社
アイティメディア営業企画/制作:@IT 編集部/掲載内容有効期限:2019年12月5日