Minishift環境でWildFlyとMySQL構成のmaven-webappをデプロイする

これまで作成したMavenのwebappを、今度はMinishift上のOpenShiftコンテナオーケストレーション環境で動かしてみる、という内容です。

- アプリのソース: [zaki-lknr/javaee-memoapp2: JavaEE + MySQL習作](https://github.com/zaki-lknr/javaee-memoapp2)
    - 説明: [Eclipseを使ってTomcat+JSP+Servlet+MySQLでメモアプリ作成 - Qiita](https://qiita.com/zaki-lknr/items/32690b071abf202281d6)
    - Mavenで再構築: [[Eclipse/Tomcat] MavenのwebappプロジェクトでServlet+JSP - Qiita](https://qiita.com/zaki-lknr/items/8137ac40ebd8f5bdb3c5)
- Ubuntu 18.04 (非コンテナ環境)でのデプロイ例
    - [[Maven/Tomcat/MySQL] Ubuntu 18.04でwebappをビルド＆デプロイする](https://qiita.com/zaki-lknr/items/dc5578d0a8d78edad992)

Minishiftのインストール・構築についてはこちら
[Minishiftを使ってVirtualBox上にOpenShift環境をつくる - Qiita](https://qiita.com/zaki-lknr/items/9eafd71d5557575ff47d)

※「Minishiftってなに？」「OpenShiftってなに？？」「コンテナオーケストレーションっておいしいの？」「コンテナってなんや？」あたりの説明はすっ飛ばしています。

# プロジェクトの作成

まず作業用のプロジェクトを作る。
デフォルトで`myproject`が割り当てられているが、せっかくなので別途プロジェクト(ネームスペース)を作る。

OpenShiftでは基本的にシステム単位でネームスペースを分ける感じにするとよさそう。(ネームスペース横断してPod間通信を行うには工夫が必要)

`oc new-app`でプロジェクトを作成すると、自動でそのプロジェクトが選択された状態になる。

```
zaki@mascarpone% oc new-project samplepj
Now using project "samplepj" on server "https://192.168.99.100: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.
zaki@mascarpone% 
```

ネーミングセンスの無さよ…

# MySQL

MinishiftではMySQLは標準で使用できる状態で構築される。
標準で使用できるイメージについては、`openshift`というネームスペースに配置されている

```
zaki@mascarpone% oc get is -n openshift mysql
NAME      DOCKER REPO                       TAGS                         UPDATED
mysql     172.30.1.1:5000/openshift/mysql   latest,5.5,5.6 + 1 more...   3 weeks ago
```

また、アプリケーションによってはパラメタなどの指定やPVの設定などが簡単にできるようにTemplateも含まれている。MinishiftのMySQLでは`mysql-persistent`というPV設定を含むTemplateが最初から準備されている。

```
zaki@mascarpone% oc get template -n openshift mysql-persistent
NAME               DESCRIPTION                                                                        PARAMETERS        OBJECTS
mysql-persistent   MySQL database service, with persistent storage. For more information about u...   9 (3 generated)   4
zaki@mascarpone% 
```

パラメタ(と省略時のデフォルト値)については、`describe`コマンドで確認できる。

```
zaki@mascarpone% oc describe template -n openshift mysql-persistent

...snip...

Parameters:              
    Name:               MEMORY_LIMIT
    Display Name:       Memory Limit
    Description:        Maximum amount of memory the container can use.
    Required:           true
    Value:              512Mi

    Name:               NAMESPACE
    Display Name:       Namespace
    Description:        The OpenShift Namespace where the ImageStream resides.
    Required:           false
    Value:              openshift

    Name:               DATABASE_SERVICE_NAME
    Display Name:       Database Service Name
    Description:        The name of the OpenShift Service exposed for the database.
    Required:           true
    Value:              mysql

    Name:               MYSQL_USER
    Display Name:       MySQL Connection Username
    Description:        Username for MySQL user that will be used for accessing the database.
    Required:           true
    Generated:          expression
    From:               user[A-Z0-9]{3}

    Name:               MYSQL_PASSWORD
    Display Name:       MySQL Connection Password
    Description:        Password for the MySQL connection user.
    Required:           true
    Generated:          expression
    From:               [a-zA-Z0-9]{16}

    Name:               MYSQL_ROOT_PASSWORD
    Display Name:       MySQL root user Password
    Description:        Password for the MySQL root user.
    Required:           true
    Generated:          expression
    From:               [a-zA-Z0-9]{16}

    Name:               MYSQL_DATABASE
    Display Name:       MySQL Database Name
    Description:        Name of the MySQL database accessed.
    Required:           true
    Value:              sampledb

    Name:               VOLUME_CAPACITY
    Display Name:       Volume Capacity
    Description:        Volume space available for data, e.g. 512Mi, 2Gi.
    Required:           true
    Value:              1Gi

    Name:               MYSQL_VERSION
    Display Name:       Version of MySQL Image
    Description:        Version of MySQL image to be used (5.7, or latest).
    Required:           true
    Value:              5.7
```

とにかく動かすのであれば、

|項目|内容|
|---|---|
|DATABASE_SERVICE_NAME|クラスタ環境上でのサービス名|
|MYSQL_USER|デプロイ時に作成するDBユーザ|
|MYSQL_PASSWORD|作成するユーザのパスワード|
|MYSQL_DATABASE|デプロイ時に作成するDB|

を指定しておけば最低限動作する。
サービス名は、ほかのPodからの名前解決にも使用される。


## デプロイ

ユーザ名・パスワード・DB名を、作成済みアプリケーションに合わせて、以下の設定でMySQLをデプロイする。

|項目|値|
|---|---|
|DATABASE_SERVICE_NAME|memoapp-db|
|MYSQL_USER|memoapp|
|MYSQL_PASSWORD|memoapp|
|MYSQL_DATABASE|memoapp_db|


```
zaki@mascarpone% oc new-app mysql-persistent -p DATABASE_SERVICE_NAME=memoapp-db -p MYSQL_USER=memoapp -p MYSQL_PASSWORD=memoapp -p MYSQL_DATABASE=memoapp_db
--> Deploying template "openshift/mysql-persistent" to project samplepj

     MySQL
     ---------
     MySQL database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mysql-container/blob/master/5.7/root/usr/share/container-scripts/mysql/README.md.
     
     NOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.

     The following service(s) have been created in your project: memoapp-db.
     
            Username: memoapp
            Password: memoapp
       Database Name: memoapp_db
      Connection URL: mysql://memoapp-db:3306/
     
     For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mysql-container/blob/master/5.7/root/usr/share/container-scripts/mysql/README.md.

     * With parameters:
        * Memory Limit=512Mi
        * Namespace=openshift
        * Database Service Name=memoapp-db
        * MySQL Connection Username=memoapp
        * MySQL Connection Password=memoapp
        * MySQL root user Password=2f044g2TyeVyxt3o # generated
        * MySQL Database Name=memoapp_db
        * Volume Capacity=1Gi
        * Version of MySQL Image=5.7

--> Creating resources ...
    secret "memoapp-db" created
    service "memoapp-db" created
    persistentvolumeclaim "memoapp-db" created
    deploymentconfig.apps.openshift.io "memoapp-db" 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 svc/memoapp-db' 
    Run 'oc status' to view your app.
```

これでDBは動作する。簡単ですね。

`Connection URL: mysql://memoapp-db:3306/`と表示されている通り、 __このネームスペースのほかのPodからであれば__ このURLでDBアクセスができる。

MySQLのPodが起動できたかどうかは`oc get pod`で`READY`の状態が`1/1`で`STATUS`が`Running`になっていればOK

```
zaki@mascarpone% oc get pod
NAME                 READY     STATUS    RESTARTS   AGE
memoapp-db-1-2lsjj   1/1       Running   0          27s
```

まぁできれば、ほかには`oc logs`コマンドでPod内のログを確認もするとより良い。

# webapp

minishiftってTomcatはデフォルトで入ってないのかーっていろいろチェックしたら、[WildFly](http://www.wildfly.org/)というAPサーバが[標準で使用できる状態](https://hub.docker.com/r/openshift/wildfly-130-centos7)になっていた。

[わいるどふらい(WildFly)って何？から学ぶEJB - ponsuke_tarou’s blog](http://ponsuke-tarou.hatenablog.com/entry/2018/05/29/002359)

WildFlyという存在を知らなかった…(JavaEE方面は疎いので)

というわけで、このAPサーバを使用してみます。
(Tomcatを使えるようにしたり、DockerHubでなく[Red HatのコンテナレジストリからAPサーバのイメージを取得する](https://qiita.com/zaki-lknr/items/cb55d452f4dc0a9917dd)、という方法もある。が、今回はWildFlyを使用)

[Red Hat Container Catalog (RHCC) を使ってみよう！ | RED HAT OPENEYE -レッドハットの情報ポータル](https://jp-redhat.com/openeye_online/column/oss-note/5894/)

## Tomcat→WildFly対応

APサーバをTomcatからWildFly v13.0に変更するにあたり、そのままだと動かないので修正を行う。
※ これはコンテナ化による修正・変更でなく、APサーバの変更に伴う修正。

```
14:12:17,627 ERROR [stderr] (default task-2) javax.naming.NameNotFoundException: comp/env -- service jboss.naming.context.java.comp.env
14:12:17,632 ERROR [stderr] (default task-2)    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)
14:12:17,632 ERROR [stderr] (default task-2)    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
14:12:17,632 ERROR [stderr] (default task-2)    at org.jboss.as.naming.InitialContext$DefaultInitialContext.lookup(InitialContext.java:237)
```

変更点はJNDIデータソース周りの設定

- (XML)JDBCによるDBサーバの定義の仕方の変更
    - Tomcatでは`META-INF/context.xml`に記述していたデータソースの定義は、WildFlyだと`META-INF`か`WEB-INF`に`*-ds.xml`というファイル名で作成する
        - [Developer Guide / 3. Deployment Descriptors used In WildFly](http://docs.wildfly.org/13/Developer_Guide.html#Deployment_Descriptors_used_In_WildFly)
        - ただし、実行すると` WFLYJCA0091: -ds.xml file deployments are deprecated. Support may be removed in a future version.`とログが出力されるので、そのうち変更される模様…
    - 設定例についてはいい感じのサンプルが見つからなかったので寄せ集めで書いてみた
        - [WildFly Documentation / Getting Started Guide / Modifying the Example DataSource](http://docs.wildfly.org/13/Getting_Started_Guide.html#modifying-the-example-datasource)
        - [JBoss Enterprise Application Platform 6 6.7.3. Example MySQL Datasource - Red Hat Customer Portal](https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/6/html/administration_and_configuration_guide/example_mysql_datasource1)
        - [[Subsonic Airlines] WildFlyへデータソースを設定 – Subsonic Systems](http://subsonic.info/ja/2015/08/21/subsonic-airlines-wildfly%E3%81%B8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%92%E8%A8%AD%E5%AE%9A/)
    - [内容はこちら](https://github.com/zaki-lknr/javaee-memoapp2/blob/b84c3296921510b8ff00f512d7700dfe39e57a2f/src/main/webapp/META-INF/memoapp2-ds.xml)

        ```xml:memoapp2-ds.xml
        <?xml version="1.0" encoding="UTF-8"?>
        <datasources>
         <datasource
          jndi-name="jdbc/memoapp_db"
          pool-name="memoapp_db"
         >
          <connection-url>jdbc:mysql://memoapp-db:3306/memoapp_db?useUnicode=yes&amp;characterEncoding=utf8</connection-url>
          <driver>mysql</driver>
          <security>
           <user-name>memoapp</user-name>
           <password>memoapp</password>
          </security>
        
         </datasource>
         <drivers>
          <driver
           name="mysql"
           module="com.mysql"
          >
           <driver-class>com.mysql.cj.jdbc.Driver</driver-class>
          </driver>
         </drivers>
        </datasources>
        ```

- (Javaコード)名前空間の参照方法の変更
    - Tomcatだと例え&lt;GlobalNamingResources&gt;でグローバルな設定を行っても、グローバルな名前空間でJNDIアクセスするわけではなかった。
    - [Apache Tomcat 8 (8.5.37) - JNDI Resources HOW-TO / Using resources](https://tomcat.apache.org/tomcat-8.5-doc/jndi-resources-howto.html#Using_resources)

        > All configured entries and resources are placed in the java:comp/env portion of the JNDI namespace

        Tomcatでは全てのリソースは`java:com/env`でアクセスするようになっているが、ほかのAPサーバはそでもない。
    - [JNDIをさらっと振り返る - nekop's blog](https://nekop.hatenablog.com/entry/20111212/1323765941)
    - [変更点はこちら](https://github.com/zaki-lknr/javaee-memoapp2/commit/b462794346bf19d2925347ffcfa6a3f4b6d2af09)

        ```diff:src/main/java/jp/example/www/dao/MemoappDaoImpl.java
        --- a/src/main/java/jp/example/www/dao/MemoappDaoImpl.java
        +++ b/src/main/java/jp/example/www/dao/MemoappDaoImpl.java
        @@ -27,6 +27,5 @@ public class MemoappDaoImpl implements MemoappDao {
                    //con = DriverManager.getConnection(url, user, pass);
                    Context initContext = new InitialContext();
        -           Context envContext  = (Context)initContext.lookup("java:/comp/env");
        -           DataSource ds = (DataSource)envContext.lookup("jdbc/memoapp_db");
        +           DataSource ds = (DataSource)initContext.lookup("jdbc/memoapp_db");
                    con = ds.getConnection();
                    System.out.println("con: " + con);
        @@ -71,6 +70,5 @@ public class MemoappDaoImpl implements MemoappDao {
                    //con = DriverManager.getConnection(url, user, pass);
                    Context initContext = new InitialContext();
        -           Context envContext  = (Context)initContext.lookup("java:/comp/env");
        -           DataSource ds = (DataSource)envContext.lookup("jdbc/memoapp_db");
        +           DataSource ds = (DataSource)initContext.lookup("jdbc/memoapp_db");
                    con = ds.getConnection();
                    smt = con.createStatement();
        ```

## DBアクセスの日本語設定

前述のJNDI周りの変更を行うことで、APからDBへアクセス可能になるが、デフォルトのMySQL設定だとエンコード設定が日本語対応していないため、Java側から日本語アクセス可能な設定を行う。
※ これもコンテナ化による修正・変更でなく、DBサーバのエンコード設定をサーバ側で設定するのではなくクライアント側で対処する、という内容。

- [blog.k11i.biz: UTF-8 エンコードされた絵文字を MySQL / JDBC で取り扱うには？](http://blog.k11i.biz/2012/11/utf-8-mysql-jdbc.html)
- [自分用備忘録: OpenShiftのMySQLにUTF-8設定を追加する](http://yasutake32.blogspot.com/2012/06/openshiftmysqlutf-8.html)
- https://bugzilla.redhat.com/show_bug.cgi?id=1010582

`<connection-url>`に指定するJDBCのURIに、エンコーディング設定を付加する。
[こんな感じ](https://github.com/zaki-lknr/javaee-memoapp2/commit/17783d936437935804de3b2c64e9e3cc0cd46bd2)

```xml
<connection-url>jdbc:mysql://memoapp-db:3306/memoapp_db?useUnicode=yes&amp;characterEncoding=utf8</connection-url>
```

また、テーブル作成時に[エンコード情報を付与して`create table`する](https://github.com/zaki-lknr/javaee-memoapp2/commit/188442fc516098d4d1fe13994684e3d6301316d7)。

```diff:src/main/java/jp/example/www/dao/MemoappDaoImpl.java
--- a/src/main/java/jp/example/www/dao/MemoappDaoImpl.java
+++ b/src/main/java/jp/example/www/dao/MemoappDaoImpl.java
@@ -99,5 +99,6 @@ public class MemoappDaoImpl implements MemoappDao {
                     "create_date DATETIME comment '作成日'," +
                     "modified_date DATETIME comment '更新日'," +
-                    "primary key (memo_id)" + ")";
+                    "primary key (memo_id)" + ") " +
+                    "engine=InnoDB default charset=utf8";
             // create table
             smt.executeUpdate(create_table);
```

今回はMySQLは標準のものをそのまま使用しDBサーバ側の設定で日本語対応していないので、アプリケーション側で可能な日本語設定を行っている。
DBサーバ側で対応するには、日本語設定を含んだDBのイメージを作成すればよいはず。(未確認)
[対応の内容は基本的にVMの場合と同じ](https://qiita.com/zaki-lknr/items/dc5578d0a8d78edad992#%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E8%A8%AD%E5%AE%9A)はず。(未確認)

また、[DockerHubにあるMySQL公式イメージ](https://hub.docker.com/_/mysql)であれば、`--character-set-server`という起動パラメタがあるみたいなので、これでエンコード設定ができると思われ。(Minishiftで用意してあるイメージはこのパラメタがなさそう)

## S2Iを使ったビルドとデプロイ

コンテナ環境でアプリケーションをデプロイするには通常は

1. アプリケーションのビルド(コンパイルが必要な言語であれば)
2. コンテナイメージのビルド
    - VM環境であればこの手順がない
    - が、この手順があることで「構築済みの初期状態」のイメージを作ることでいつでも初期状態の環境を作り直すことができる
3. コンテナのデプロイ
    - 前段で作ったコンテナイメージを「実行」するだけ
    - VM環境であればwarを配置したりの手順に相当かな
    - コンテナ環境でも「(Tomcatとかの)ミドルウェアのコンテナをデプロイ」して、その中にあとからアプリを手動デプロイとかできなくもないけど、オーケストレーション環境でそれをするメリットはあまりないかも…(Podのスケールができないとか)

という手順になるけど、OpenShiftの機能であるS2I(source-to-image)を使うことで、コマンド一発で全部完了することができる。(ついでに言うと、GitのリポジトリURLを指定することで、ソースコードのcloneから全自動)

- [OpenShiftのsource-to-image (s2i)をすごく簡単に説明するよ - nekop's blog](https://nekop.hatenablog.com/entry/2015/12/18/114610)
- [OpenShift v3 と source-to-image (s2i) - Qiita](https://qiita.com/nak3/items/6407c01cc2d1f153c0f1)

JavaEEであれば、`pom.xml`が含まれていれば認識する模様 (つまりMavenプロジェクトとして作っていればOK)
[Creating New Applications - Application Life Cycle Management | Developer Guide | OKD Latest ](https://docs.okd.io/latest/dev_guide/application_lifecycle/new_app.html)

前置きが長くなったけど、以下のコマンドを実行

```
zaki@mascarpone% oc new-app openshift/wildfly~https://github.com/zaki-lknr/javaee-memoapp2.git
--> Found image 4dea579 (3 weeks old) in image stream "openshift/wildfly" under tag "13.0" for "openshift/wildfly"

    WildFly 13.0.0.Final 
    -------------------- 
    Platform for building and running JEE applications on WildFly 13.0.0.Final

    Tags: builder, wildfly, wildfly13

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

--> Creating resources ...
    imagestream.image.openshift.io "javaee-memoapp2" created
    buildconfig.build.openshift.io "javaee-memoapp2" created
    deploymentconfig.apps.openshift.io "javaee-memoapp2" created
    service "javaee-memoapp2" created
--> Success
    Build scheduled, use 'oc logs -f bc/javaee-memoapp2' 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/javaee-memoapp2' 
    Run 'oc status' to view your app.
```

`oc new-app`のコマンド自体はすぐに完了し、裏でbuilder podというリポジトリからソースをcloneしてソースのビルドからイメージのビルドまでを実行するPodが起動する

```
zaki@mascarpone% oc get all                                                 [~]
NAME                          READY     STATUS    RESTARTS   AGE
pod/javaee-memoapp2-1-build   1/1       Running   0          17s
pod/memoapp-db-1-2lsjj        1/1       Running   0          10m

NAME                                 DESIRED   CURRENT   READY     AGE
replicationcontroller/memoapp-db-1   1         1         1         10m

NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/javaee-memoapp2   ClusterIP   172.30.210.59   <none>        8080/TCP   18s
service/memoapp-db        ClusterIP   172.30.11.241   <none>        3306/TCP   10m

NAME                                                 REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/javaee-memoapp2   0          1         0         config,image(javaee-memoapp2:latest)
deploymentconfig.apps.openshift.io/memoapp-db        1          1         1         config,image(mysql:5.7)

NAME                                             TYPE      FROM      LATEST
buildconfig.build.openshift.io/javaee-memoapp2   Source    Git       1

NAME                                         TYPE      FROM          STATUS    STARTED          DURATION
build.build.openshift.io/javaee-memoapp2-1   Source    Git@188442f   Running   17 seconds ago   

NAME                                             DOCKER REPO                                TAGS      UPDATED
imagestream.image.openshift.io/javaee-memoapp2   172.30.1.1:5000/samplepj/javaee-memoapp2             
zaki@mascarpone% oc get pod                                                 [~]
ocNAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-build   1/1       Running   0          25s
memoapp-db-1-2lsjj        1/1       Running   0          10m
```

この場合は`oc logs -f javaee-memoapp2-1-build`でビルドログ(Mavenの実行状態)を確認できる。

```
zaki@mascarpone% oc logs -f javaee-memoapp2-1-build

...

Pushing image 172.30.1.1:5000/samplepj/javaee-memoapp2:latest ...
Pushed 0/13 layers, 0% complete
Pushed 1/13 layers, 10% complete
Pushed 2/13 layers, 18% complete
Pushed 3/13 layers, 25% complete
Pushed 4/13 layers, 32% complete
Pushed 5/13 layers, 40% complete
Pushed 6/13 layers, 47% complete
Pushed 7/13 layers, 55% complete
Pushed 8/13 layers, 63% complete
Pushed 9/13 layers, 75% complete
Pushed 9/13 layers, 82% complete
Pushed 10/13 layers, 89% complete
Pushed 10/13 layers, 94% complete
Pushed 11/13 layers, 97% complete
Pushed 12/13 layers, 97% complete
Pushed 13/13 layers, 100% complete
Push successful
zaki@mascarpone% 
```

ビルドが完了されると、内部で動作しているイメージレジストリへpushされ実行可能状態になり、
そのままPodが起動される。

```
zaki@mascarpone% oc get pod
NAME                      READY     STATUS      RESTARTS   AGE
javaee-memoapp2-1-build   0/1       Completed   0          4m
javaee-memoapp2-1-rgjqq   1/1       Running     0          11s
memoapp-db-1-2lsjj        1/1       Running     0          15m
zaki@mascarpone
```

APサーバ関連のPodは、`oc logs`で確認してエラーがなく`listening`とか`started`とか起動してる感じのログが出ていればOK

```
07:21:38,706 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://0.0.0.0:9990/management
07:21:38,707 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://0.0.0.0:9990
07:21:38,716 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 13.0.0.Final (WildFly Core 5.0.0.Final) started in 46464ms - Started 698 of 890 services (315 services are lazy, passive or on-demand)
```

これでDBとwebアプリケーションが動作している状態

```
zaki@mascarpone% oc get service
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
javaee-memoapp2   ClusterIP   172.30.210.59   <none>        8080/TCP   9m
memoapp-db        ClusterIP   172.30.11.241   <none>        3306/TCP   19m
```

## routerの作成

アプリをデプロイしただけだと、動作しているServiceに対してクラスターの外部からアクセスすることができないため、外部からのアクセス用のRouter Podを作成する。

```
zaki@mascarpone% oc expose service javaee-memoapp2
route.route.openshift.io/javaee-memoapp2 exposed
zaki@mascarpone%
zaki@mascarpone% oc get route
NAME              HOST/PORT                                        PATH      SERVICES          PORT       TERMINATION   WILDCARD
javaee-memoapp2   javaee-memoapp2-samplepj.192.168.99.100.nip.io             javaee-memoapp2   8080-tcp                 None
```

これで、`http://javaee-memoapp2-samplepj.192.168.99.100.nip.io`に対してアクセスすると、javaee-memoapp2のPodの8080/TCPへルーティングしてくれる、という状態になる。

ちなみに、`oc expose`で作成されるRouter Podのドメイン名は、デフォルトでは`<サービス名>-<ネームスペース名>.サブドメイン`となる。なのでワイルドカードDNSが使用できる環境が基本的には必要。
(`--hostname`オプションで任意のホスト名/FQDNを指定することも可能)

# ブラウザでwebアクセス

Minishift環境だとrouteで作成したドメイン名はpublicなワイルドカードDNSサービスを使って作られるので特に意識せずに利用できる。
[ワイルドカードDNSは nip.io が良い - 約束の地](https://obel.hatenablog.jp/entry/20170825/1503658628)

routeのドメインである`javaee-memoapp2-samplepj.192.168.99.100.nip.io`にブラウザでアクセスすると…

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/49988fab-bf8d-7364-aaf8-2fa2f70a12fb.png)

そういえばアプリの構成的にコンテキストルートでの動作ではなかった。
`/memoapp2`のパスを付け加えてアクセス。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/52cceda8-a989-421d-d976-07b47610f34b.png)

うごいたああ！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/255029b5-2a10-9d5e-e624-c43a1cdf10c9.png)

日本語入力も大丈夫でした。