Microservice Builderで新規にアプリを作って，IBM Cloud Private (Kubernetes) に自動デプロイしてみる

みなさんはKubernetesはどうやって使っていますか？

仕事とは関係なく趣味レベルですが，
私のチームでは以前からGKEやIBM Cloudをメインとしてパブリック環境のKubernetesを使っていました。(OpenShift Onlineもほんの少し)

k8sの選択肢は，クラウドのホスティングサービス，ターンキーでIaaSに入れるパターン，ソフトとして自身で導入・構築するパターン，色々あると思います。さらに，開発での利用，また運用，チームによって使い方も違いますよね。

俺達はこうやってるぜ！みたいな情報を積極的に出せる場があると良いですね。きっと需要もあるし，互いに共有する価値もあると思っています。ぜひぜひ教えてくださいませ。

# はじめに
本日は，[Kubernetes2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/kubernetes2) 17日目になります。

今回は，プライベート環境で開発用途なら無償で利用できる
 **IBM Cloud Private CE (Community Edition)** を使ってみたいと思います。

IBM Cloud Private CE のインストールがまだの場合でも誰でも導入できるので，[こちら](https://qiita.com/capsmalt/items/d15055ab3cb423d2d7ae) を参考にしてください。

この記事では **"アプリを作って，IBM Cloud Privateにデプロイ"** という基本的な部分を実施したいと思います。

この後説明する，Microservice Builderというツールを使ってアプリを開発します。

参考: ["Microservice Builder"](https://developer.ibm.com/microservice-builder/)

# Microservice Builder とは
様々なオープンテクノロジーを活用し，マイクロサービスアプリをスピード開発・デプロイするためのツールです。

一度アプリを作った後は，ソースコードをリポジトリにpushするだけで自動的にビルド・テストが行われ，IBM Cloud Privateにデプロイされるようになります。

ぱっとイメージが湧く方向けに結論を先に伝えると，
"Webhook + Jenkins Pipeline" を使って，Docker Imageをprivate registryに登録してバージョン管理し，諸々のステージを経て，Kubernetes環境にhelm releaseするイメージです。

そのために，アプリを作った瞬間からCI/CDの初期構成が組まれます。
※CI: Continuous Integration (継続的インテグレーション)
※CD: Continuous Delivery (継続的デリバリー)

|雛形プロジェクトの初期構成 (抜粋)|用途|
|:---|:----|
|Example.java|JAX-RSのリソースクラス1つ|
|pom.xml|Mavenビルド|
|jenkinsfile|Jenkins Pipeline|
|Dockerfile|Dockerイメージビルド|
|kube.deploy.yml|Kubernetesへのデプロイ|
|chartディレクトリ|helm chart|
|その他|-|

# 環境 と 進め方
以下の2段構成で紹介します。

- (前半戦) Microservice Builderでアプリを作ってローカル環境でコンテナ稼働させる
- (後半戦) IBM Cloud Private上(k8s)に自動デプロイされるように構成する

環境については，開発環境はMac，デプロイ先はUbuntu上に構築したIBM Cloud Privateとします。

## 開発環境
macOS 10.13.1
Docker for Mac V17.09.1
iTerm V3.0.15

 (なんとなく今日はMacbook Air 11使ってます)

## デプロイ先となる環境
IBM Cloud Private CE (Community Edition) V2.1.0
(※以降，IBM Cloud privateをICPと表現する場合があります)

注意:
ICP未インストールの場合は先にインストールしてください。
時間課金のAWSやIBM CloudなどのIaaSを使うのもありだと思います。

参考: ["IBM Cloud Private: Kubernetesをオンプレミス(IaaS)に導入してみる"](https://qiita.com/capsmalt/items/d15055ab3cb423d2d7ae)

# (前半戦) Microservice Builderでアプリを作ってローカル環境でコンテナ稼働させる
## コマンドの事前準備
###  bxコマンド (IBM Cloud CLI) を導入する

[IBM Cloud CLI Installer](https://console.bluemix.net/docs/cli/reference/bluemix_cli/all_versions.html#ibm-cloud-cli-installer-all-versions) からお使いのPCにあったものをインストールすればOKです。
インストール後にバージョン確認した結果は以下です。

```text
$ bx --version

bx version 0.6.2+040af8db-2017-11-17T08:37:05+00:00
```

[こちら](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6#2-1-ibm-cloud-cli-のインストール) に画面イメージ付きで導入手順がありますので，必要に応じて参照ください。



### bx devプラグインを導入する
bxコマンドでdevプラグインを導入します。

```text
$ bx plugin install dev
```

ヘルプを確認します。

```text
$ bx plugin show dev   // bx dev helpでも確認できます

Plugin                         dev
Version                        1.1.0
Minimal CLI version required   0.4.2

Commands:
dev build             Build the project in a local container
dev code              Download the code from a project
dev console           Opens the IBM Cloud console for a project
dev create            Creates a new project and gives you the option to add services
dev debug             Debug your application in a local container
dev delete            Deletes a project from your space
dev deploy            Deploy an application to IBM Cloud
dev enable            Add IBM Cloud files to an existing project.
dev get-credentials   Gets credentials required by the project to enable use of bound services.
dev list              List all IBM Cloud projects in a space
dev run               Run your application in a local container
dev shell             Open a shell into a local container
dev status            Check the status of the containers used by the CLI
dev stop              Stop a container
dev test              Test your application in a local container
dev view              View the URL of your project
dev help              Show help
```

## 新規アプリを作る (bx dev create/build/run)
さきほど導入した，bxコマンドおよびdevプラグインで，以下の操作が行えます。

|コマンド|用途|
|:--|:--|
|bx dev create|雛形プロジェクトの生成|
|bx dev build|アプリのビルド|
|bx dev run|Dockerコンテナでアプリ動作|

### 雛形プロジェクトの生成 (bx dev create)
`bx dev create` でインタラクティブに選択することで，目的の雛形プロジェクトを生成できます。
以下に従って，同じようにプロジェクトを作成します。

参考までに私が選択した項目(数字など)を示します。
`[bx dev create実行] > 1 > 1 > 2 > capsmaltapp > capsmaltapp > 3 > n`

※バージョン差異等によって，項目や順番などが変わっているかもしれないので，実際にはきちんと表記を確認しながら進めた方が良いです

コマンド実行例は以下です。

```text
$ bx dev create

? Select a resource type:
1. Backend Service / Web App
2. Mobile Client
Enter a number> 1     // 1. を選択

? Select a language:
1. Java - MicroProfile / Java EE
2. Java - Spring Framework
3. Node
4. Python
5. Swift
Enter a number> 1     // Java EEを選択

? Select a Starter Kit or select the last option for more information:
1. Backend for Frontend: Java MicroProfile / Java EE Backend
2. Microservice: Java MicroProfile / Java EE Microservice
3. Web App: Java MicroProfile / Java EE Basic
4. Show more details
Enter a number> 2     // マイクロサービスを選択


? Enter a name for your project> capsmaltapp     // アプリプロジェクト名を指定

? Enter a hostname for your project> capsmaltapp // ホスト名を指定(上記と同じでOK)
? Select from the following DevOps Toolchain and target runtime environment options:
Note: If you choose to create a DevOps Toolchain, then this machine must be
configured for SSH access to your IBM Cloud Git Lab account at
https://git.ng.bluemix.net/profile/keys in order to download the project code.
1. IBM DevOps, using Cloud Foundry buildpacks
2. IBM DevOps, using Kubernetes containers
3. No DevOps, with manual deployment
Enter a number> 3     // 今回はIBM Cloud(パブリッククラウド)を使わないので，3.を選択

? Do you want to add services to your project? [y/n]> n   // IBM Cloudのサービスも使わないので，n を選択

The project, capsmaltapp, has been successfully saved into the current directory.
```

### ビルド (bx dev build)
生成された雛形プロジェクトのディレクトリに移動してから，ビルドコマンド `bx dev build` を実行します。

```text
$ cd capsmaltapp  // 雛形プロジェクトのディレクトリに移動
$ bx dev build   // --traceオプションで標準出力で確認しながらすすめるのもOK

Creating image bx-dev-java-maven-tools based on Dockerfile-tools...
Image will have user capsair added
OK
Creating a container named 'bx-dev-capsmaltapp-tools' from that image...
OK
Starting the 'bx-dev-capsmaltapp-tools' container...
OK
Building the project in the current directory started at Sun Dec 17 01:16:34 2017
OK
Stopping the 'bx-dev-capsmaltapp-tools' container...
OK
```

### ローカルコンテナで動作確認 (bx dev run)
`bx dev run` で，ローカル環境のDockerコンテナ上でアプリの動作確認をします。

```text
$ bx dev run

The run-cmd option was not specified
Stopping the 'capsmaltapp' container...
The 'capsmaltapp' container was not found
Creating image capsmaltapp based on Dockerfile...
OK
Creating a container named 'capsmaltapp' from that image...
OK
Starting the 'capsmaltapp' container...
OK
Logs for the capsmaltapp container:
## PropertyMgr::initialize() A RuntimeBuilder helper class has changed the runtime directory name
## PropertyMgr::initialize() originally specified parameter=defaultServer, new value used=/opt/ibm/wlp/usr/extension/liberty_dc/runtime/was90.wlp17.defaultCellName.opt.ibm.wlp.defaultServer
## PropertyMgr::initialize() Calling  defineEnvMethodId.......
Trying to load environment variables from - /opt/ibm/wlp/usr/extension/liberty_dc/runtime/was90.wlp17.defaultCellName.opt.ibm.wlp.defaultServer/dc.env.properties
## PropertyMgr::initialize() loaded Environment Variables
LIBRARY_NAME=am_ibm_16
Calculated native library name as: am_ibm_16
Launching defaultServer (WebSphere Application Server 17.0.0.3/wlp-1.0.18.cl170320170927-1854) on IBM J9 VM, version 8.0.5.6 - pxa6480sr5fp6-20171124_02(SR5 FP6) (en_US)
[AUDIT   ] CWWKE0001I: The server defaultServer has been launched.
[AUDIT   ] CWWKE0100I: This product is licensed for development, and limited production use. The full license terms can be viewed here: https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/license/base_ilan/ilan/17.0.0.3/lafiles/en.html
[AUDIT   ] CWWKG0093A: Processing configuration drop-ins resource: /opt/ibm/wlp/usr/servers/defaultServer/configDropins/defaults/keystore.xml
[AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.
[AUDIT   ] CWPKI0803A: SSL certificate created in 2.811 seconds. SSL key file: /opt/ibm/wlp/output/defaultServer/resources/security/key.jks
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://148a4a7f545a:9080/ibm/api/
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://148a4a7f545a:9080/metrics/
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://148a4a7f545a:9080/health/
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://148a4a7f545a:9080/jwt/
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://148a4a7f545a:9080/capsmaltapp/
[AUDIT   ] CWWKZ0001I: Application capsmaltapp-1.0-SNAPSHOT started in 3.374 seconds.
[AUDIT   ] CWWKF0012I: The server installed the following features: [microProfile-1.2, usr:apmDataCollector-7.4, mpFaultTolerance-1.0, servlet-3.1, ssl-1.0, jndi-1.0, mpHealth-1.0, appSecurity-2.0, jsonp-1.0, mpConfig-1.1, jaxrs-2.0, jaxrsClient-2.0, concurrent-1.0, jwt-1.0, mpMetrics-1.0, monitor-1.0, mpJwt-1.0, json-1.0, cdi-1.2, distributedMap-1.0].
[AUDIT   ] CWWKF0011I: The server defaultServer is ready to run a smarter planet.
```

このコンテナプロセスは，`Ctrl + c` でkillできます。
まだkillせずに，少し動きを確認しましょう。

ブラウザで以下を入力して開きます。(アプリ名が異なる場合は読み替えてください。今回はcapsmaltappで作成しています)
`http://localhost:9080/capsmaltapp` を開きます。

以下のように表示されます。
![Screen Shot 2017-12-17 at 2.07.26.png](https://qiita-image-store.s3.amazonaws.com/0/69447/d7762da0-7c37-be9f-f714-c0e6d0683222.png)

上手で表示された2つのURLもコピーしてアクセスしてみましょう。
"health" の方は，名前の通りヘルスチェックです。
"example" の方は，RESTのGETで呼べるURIです。

Example.javaは，プロジェクト内のJavaコード(src > main > java > application > rest > v1 > Example.java)を見ると，JAX-RS(Java EE)に従って記載されたリソースクラスであることが分かります。
シンプルに，文字列を返すだけのGETが一つ用意されています。

また，[http://localhost:9080](http://localhost:9080) を開くと，WebSphere Liberty (Java EE アプリケーション・サーバー)のWelcomeページが開くことを確認できます。

※WebSphere Libertyとは，マイクロサービス向けに作られた機能備えた超軽量なランタイムです。

![Screen Shot 2017-12-17 at 2.30.15.png](https://qiita-image-store.s3.amazonaws.com/0/69447/fd908318-5a10-53a4-ee4c-b14fdf25008d.png)

次の項でこれまでの流れを簡単に解説します。

### bx dev create/build/run のまとめ (ここでは作業しません)
さて，行った手順は，**3つのコマンドを順に叩いただけ**ですが，実際は何が行われたのでしょうか。

実は，bx dev createで雛形を作った時点で，Dockerfileが含まれており，その中でWebSphere Libertyのコンテナイメージを取得し，プロジェクトをビルドして新たにDockerイメージを作成するように記載されていたわけです。

細かくは説明しませんが，以下の1行目にpullしてくるイメージ名が指定されています。

```text:Dockerfile
FROM websphere-liberty:webProfile7
MAINTAINER IBM Java engineering at IBM Cloud
COPY /target/liberty/wlp/usr/servers/defaultServer /config/
# Install required features if not present, install APM Data Collector
RUN installUtility install --acceptLicense defaultServer && installUtility install --acceptLicense apmDataCollector-7.4
RUN /opt/ibm/wlp/usr/extension/liberty_dc/bin/config_liberty_dc.sh -silent /opt/ibm/wlp/usr/extension/liberty_dc/bin/silent_config_liberty_dc.txt
# Upgrade to production license if URL to JAR provided
ARG LICENSE_JAR_URL
RUN \ 
  if [ $LICENSE_JAR_URL ]; then \
    wget $LICENSE_JAR_URL -O /tmp/license.jar \
    && java -jar /tmp/license.jar -acceptLicense /opt/ibm \
    && rm /tmp/license.jar; \
  fi
```

そして，ビルドを経て，bx dev runでは以下が行われました (抜粋)

- docker pullで，DockerHubからイメージ(websphere-liberty/webProfile7)を取得
- docker buildで，capsmaltappという名前でDockerイメージを生成する
- docker runで，capsmaltappのコンテナを稼働

コンテナの中では，WebSphere LibertyというJava EEランタイムが動き，その上にアプリケーションをインストールし，REST APIとして動作していたことになります。

つまり，**Microservice Builderのコマンド (bx dev create/build/run)** を使うことで，
**新規にアプリを作って，ビルドして，ローカル環境のコンテナでの動作確認まではすぐにできていた** わけです。

(実際にアプリを作る場合は，RESTリソースを弄ったり，他APIを呼ぶように構成したり，色々な進め方があります)


もう一度，プロジェクト内のファイル群を確認してみると，他にも色々含まれていますね。
これらのファイル群は，手元での開発から，リポジトリへの更新，その後IBM Cloud Private(k8s環境)のコンテナに対する自動デプロイするための初期構成として用意されています。

余裕があればご自身で中身を見てみてください。

```text
$ cd capsmaltapp/
$ ls
Dockerfile		LICENSE			cli-config.yml		pom.xml
Dockerfile-tools	README.md		manifest.yml		src
Jenkinsfile		chart			manifests
```

だんだん触っていくにつれて，プロジェクトに最初からこういったものが含まれていて，アプリ名が埋め込まれた雛形が用意されることの便利さを感じられると思います。

# (後半戦) IBM Cloud Private上(k8s)に自動デプロイされるように構成する
仕組みの説明を最初にします。

- 前半戦で作ったソースコード(アプリ)をリポジトリにpush
- GitHubリポジトリがコードの更新(e.g. git push)を検知してWebhookをJenkinsマスターに送る
- Jenkinsマスターは，Jenkinsスレーブに，一連のビルドからデプロイまでの操作を命令する


**後半戦は以下の3つの作業を行います。**

- GitHubにリポジトリを作成して，Webhookの設定をする
- IBM Cloud Privateに必要なコンポーネントを導入する
- IBM Cloud Privateのコンソール画面を操作して，Jenkinsマスターを構成する

## リポジトリ作成とWebhook設定
### リポジトリ作成と初期コードをpush
まずは，GitHubの組織とリポジトリを作成します。

ブラウザで，[GitHub](https://github.com/)にアクセスします。
※GitHubに組織を作成していなければ，一つ作ります。

- 組織の作成
 - [GitHubトップページ] > [+アイコン] > [New organization]
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/4ba11fda-5c0e-8de3-11df-55bb7fb8ddb3.png)
 - 組織名やメールアドレス，プラン(Free 無料)などを入力して，ウィザードをすすめる
 - (私の場合は，組織名に msbtechorg を指定)
- 組織内に新規リポジトリを作成する
 - 組織のページで，[Create New Repository]で **前半戦で作成したプロジェクト名で**，新規にリポジトリ作成 (私の場合，capsmaltapp)
 - 組織名/リポジトリ名 のようになる (下図)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/8c02515a-c5f5-f297-efdd-da7e5c487eaa.png)


次に，前半戦で作成したプロジェクト内で，`git init` コマンドを実行して初期化します。

```text
$ git init
```

その後，先程GitHubで作成したリポジトリにプロジェクトをpushしてください。
以下のように実行することになります。(リポジトリのURLは適宜読み替えてください)

```text
$ git add ./
$ git commit -m "Initial commit"
$ git remote add origin https://github.com/msbtechorg/capsmaltapp.git   // 自身のリポジトリを指定
$ git push -u origin master
```

GitHubの対象リポジトリページにアクセスすると，プロジェクト内のコード群が登録されていることが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/0157463b-8d75-68c2-400e-fc5e6ac958d9.png)

### Webhookの設定
ここでは，GitHubのリポジトリ内の更新(e.g. 開発者ソースコードを変更して，pushしたというイベント)をトリガーに，その事実(コードが更新されたこと)を通知する Webhook を設定します。

- GitHubでPersonal Access Tokenを発行する
 - [GitHubログイン] > [Setting] > [Developer settings] > [Personal access tokens] > [Generate new token]
 - Personal Access Tokenでの認可スコープを設定 (下図参照)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/5d8e6585-c2e2-e5ff-cab9-4562694949dd.png)
 - 下にスクロールして，[Generate token]をクリックしてトークンを生成
 - 表示されるトークンをメモ **※一度しか表示されないので注意**(忘れたら取り直し)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/7819a275-e76e-bd7b-c6e5-89836ce1f041.png)
 - (説明のためにSSを載せていますが，通常はセキュアに管理すべきものです。ちなみに今はRevoke済。)

- OAuthを設定します (GitHubのアカウントを使用して，後続の手順で作成するJenkinsにログインできるように，ID/Secretを生成します)
 - [msbtechorg(組織)] > [Settings] > [Developer settings] > [OAuth Apps]
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/58ebff29-4d6c-5fca-6251-2507ebcb090a.png)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/f2820867-3592-8d15-a145-0cc98e337733.png)
 - [New OAuth App] をクリック
 - 次の3項目に対して，値を入力
 - Application name / Homepage URL / Authorization callback URL
 - (10.132.75.83と記載している部分は，自身の環境のものに読み替えてください)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/3eeeb54e-5852-18f3-b077-339387a4a4b3.png)

上記で入力した3項目の解説

|項目|入力値|説明
|:--|:---|:---|
|Application name|MSB_OAuth(なんでもOK)|OAuthのID/Secretの組み合わせを識別するための名前|
|Homepage URL|http://xxx.xxx.xxx.xxx:31000|IBM Cloud Private上のJenkinsマスターのURL (ICPシングルノード構成の場合，ホストIPでOK)|
|Authorization callback URL|http://xxx.xxx.xxx.xxx:31000/securityRealm/finishLogin|Jenkinsマスターに接続したときに，GitHubアカウントを使った認証・認可を呼び出すためのURL|

 - 入力が終われば，[Register application]をクリックして進む
 - 次のページが表示されるので，**Client ID** / **Client Secret** をメモ (※ID/Secretは，いつでも確認できます。)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/a8495b89-a142-fd9f-2523-02b5b64e5ac3.png)

**ここまでで，以下をメモしているはずです。**
**あとでJenkinsマスターを構成する手順で使用します。**

|項目|値|
|:--|:--|
|Personal Access Token|c4b371b33290940e5167f67ad5effa4f1f033118|
|Client ID|45c465713684b148fdb5|
|Client Secret|c74034c9aeb791984a67104ff915be1a9018cf52|

- Webhookの設定
 - [msbtechorg(組織)] > [Settings] > [Webhooks] > [Add webhook]
 - Payload URLを設定
 - (私の場合は，`Payload URL = http://10.132.75.83:31000/github-webhook/`)
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/15716ca6-4dbb-d7ff-6739-af246ee55727.png)


 - **"Let me select individual events"** のラジオボタンを選択し，次の項目にチェックを入れます。
 - Pull request / Push / Repository
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/fb014649-f3a7-d3a7-1315-367fd0c86111.png)
 - [Add webhook] をクリックして登録



## Jenkinsマスターの構成 (IBM Cloud Private上でやること)
いよいよ，最後の手順です。
IBM Cloud Private上のコンテナでJenkinsマスターを稼働させます。

Jenkinsマスターは，前の手順で用意したWebhookを受け取り，Jenkinsスレーブの各コンテナでビルド・イメージ作成・テスト・デプロイをキックします。

これを一言で表すと，"Jenkins Pipelineを動作させる" 
と言えるかと思います。

では，以下の作業を実施します。

- Microservice Builder Fabricの導入
- Microservice Builder Pipelineの導入・構成

### Microservice Builder Fabricの導入
IBM Cloud Privateコンソールから操作します。
(私の場合は，`https://10.132.75.83:8443` がコンソールUI) 

- [IBM Cloud Privateコンソールにログイン] > [メニューからCatalog]
- [ibm-microservicebuilder-fabric] を選択

- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/32cdc317-f014-5a18-3e97-76800f68e92b.png)
- 右下にある [Configure] をクリック
- [Release name]に任意の名前を入力 (小文字英数字)
- [I have read and agreed to the license agreements]にチェックを入れる
- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/7065dbbc-8d01-51e1-445a-f487305c54ef.png)
- 末尾右下にある [Install] をクリック

以上の手順で，IBM Cloud PrivateにMicroservice Builder fabricをコンテナとしてリリースできました。
簡単に中身を説明します。

Microservice Builder fabricは，Zipkinによる分散トレースを行う際に使用します。実はそれだけではなく，Microservice Builderで使用するキーストアをsecretとして登録してくれます。
このsecretが欲しかったので，最初にfabricの導入を行いました。

secretは以下kubectlコマンドで確認できます。

ローカルPCに [こちらの手順](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6#1-1-kubectl-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) でkubectlコマンドをインストール済であれば，以下を実行することでsecretを確認できます。

`$ kubectl get secrets`

もし，IBM Cloud Privateのk8sクラスターに接続していない場合は，[こちら](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6#1-2-ibm-cloud-private%E3%81%B8%E3%81%AE%E6%8E%A5%E7%B6%9A%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C) を実施してから，コマンド実行します。

<実行結果>

```text
$ kubectl get secrets

NAME                     TYPE                                  DATA      AGE
calico-etcd-secrets      Opaque                                3         7d
default-token-2fcm6      kubernetes.io/service-account-token   3         7d
mb-keystore              Opaque                                1         1m
mb-keystore-password     Opaque                                1         1m
mb-truststore            Opaque                                1         1m
mb-truststore-password   Opaque                                1         1m
```



### Microservice Builder Pipelineの導入・構成
いよいよ終盤です。2つの操作をします。

1) IBM Cloud PrivateのノードにSSHでログインして，事前設定
2) IBM Cloud Privateのコンソールから，Microservice Builder Pipelineをコンテナにリリースします

#### 1) IBM Cloud PrivateのノードにSSHでログインして，事前設定
1)の操作はすべてIBM Cloud Privateのノード内で行います。
SSHでIBM Cloud Privateのノードにログインします。

```text
$ ssh capsmalt@10.132.75.83
$ sudo -i
# // rootに昇格。今回はk8s環境内の操作はrootで操作していますが，外部公開する場合は適切なユーザー設定をしてください。
```

1-1) jqのインストール
JSONの制御をしやすくするツールです。
すぐ後のステップの中で使用しますのでインストールします。

```text
# apt install -y jq
```

1-2) admin.registrykeyの作成
Jenkins PipelineがICP内のDocker registryに接続するためのSecretを作成します。

ローカルPCにはKubectlは導入済みかと思いますが，
IBM Cloud Privateのノード上に未導入の場合は，[Kubectl導入手順](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6#1-1-kubectl-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)を参考に，Linux用のKubectlを導入しておきましょう。今回に限らず，使いたいケースは出てくると思います。

また，IBM Cloud Privateのk8sクラスターに接続するために，[Kubectlの接続先の設定](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6#1-2-ibm-cloud-private%E3%81%B8%E3%81%AE%E6%8E%A5%E7%B6%9A%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C)をしておきましょう。

Kubectlの準備ができたら，以下のコマンドを実行します。

```test
# kubectl create secret docker-registry admin.registrykey --docker-server=https://mycluster.icp:8500 --docker-username=admin --docker-password=admin --docker-email=null
```

上記コマンドのオプションは，ICPインストールをデフォルト値で行った場合の例です。
もし，パスワードを `p@ssw0rD` のように変更している場合は，
`--docker=password=p@ssw0rD` のように適宜変更してください。

1-3) service accountにsecret設定を反映
前の手順で作成したadmin.registrykeyを使用するようにservice accountに反映させます

```text
# kubectl get serviceaccounts default -o json | jq 'del(.metadata.resourceVersion)' | jq 'setpath(["imagePullSecrets"];[{"name":"admin.registrykey"}])' | kubectl replace serviceaccount default -f -

serviceaccount "default" replaced
```

#### 2) IBM Cloud Privateのコンソールから，Microservice Builder Pipelineをコンテナにリリース
2)の作業は，IBM Cloud Privateコンソールから行います。

- ブラウザでコンソールにログイン (e.g. `https://10.132.75.83:8443`)
- [メニュー] > [Catalog] > [ibm-microservicebuilder-pipeline] をクリック
 - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/64360ca0-5ffb-1625-5d54-026bd273cd00.png)
- [Configure] をクリックして，以下の項目を設定

(ご自身のGitHubアカウントで用意したものに置き換えてください)

|入力項目|値|説明|
|:-----|:-----|:-----------|
|Release name|capsmalt-pipeline|(入力チェックをパスできれば何でもOK)|
|[ ] I have read ...|チェック入れる|ライセンス確認チェックボックス|
|Orgs|msbtechorg|GitHubで作成した組織名|
|RepoPattern|.*|.*の設定で組織内のすべてのリポジトリがPipeline対象になる|
|OAuth.Token|c4b371b33290940e5167f67ad5effa4f1f033118|GitHubで設定したPersonal Access Token|
|OAuth.User|capsmalt|GitHubアカウントのユーザー名|
|App.Id|45c465713684b148fdb5|GitHubで設定したOAuthAppのClient ID|
|App.Secret|c74034c9aeb791984a67104ff915be1a9018cf52|GitHubで設定したOAuthAppのClient Secret|
|Admins|capsmalt|GitHubアカウントの管理者権限のあるユーザー名|
|その他の項目|デフォルト値(or ブランク)|-|

入力後のイメージ図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/10114a78-d2f2-7d16-b771-5400cfd39b05.png)

- 最後に，入力画面の右下にある [Install] をクリックし，インストールを完了する
- [ICPコンソールメニュー] > [Workloads] > [Helm releases] でリリースしたもの(capsmalt-pipeline，capsmalt-fabric)を確認できます。


## Jenkins Pipelineによる自動デプロイの動作確認 
IBM Cloud Privateのコンテナ上で動作するJenkinsマスターに接続します。
ブラウザで，`http://10.132.75.83:31000/` を開きます。

OAuthの認可確認画面がでてくるので，GitHubアカウントのパスワードなどを入力し，Jenkinsのコンソールにログインします。 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/be47661b-c1ed-288d-4157-0436d64c7b41.png)

自身の組織を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/822b4822-37a7-81d8-df09-c75d7e2c18ef.png)

組織内に含まれるリポジトリを選択します。(今回は，capsmaltapp)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/b658690f-0fd6-522e-881f-7505ce30be8a.png)

ブランチを選択します。(今回は，masterブランチのみ)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/35a74f30-f51f-7d5f-3589-a73f822fb538.png)

Jenkinsマスターの構成や，GitHubのWebhook構成がちゃんとできていれば，以下図のようなパイプライン画面が確認できます。
ソースコードの更新をトリガーに，自動的にビルドやテスト，デプロイが行われるパイプラインです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/a4ed6ca8-c50f-cc69-0b2c-1222739bf648.png)

ローカルPCで，ソースコードを少し変更してみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/a088e718-e684-e2d7-84b1-db2363c10f22.png)

なんの面白みもないですが，文字列を変えてみました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/971561b5-1522-c335-34b7-c4197b3b6dac.png)

GitHubにpushします。

```text
$ git add ./
$ git commit -m "Change msg."
$ git push
```

ブラウザで，確認します。
1行だったものが2行に増えていませんか？
リポジトリの更新(Webhook)をJenkinsマスターが受け取って，ICP上でパイプラインを動作させていることが分かります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/3a83289b-d3da-55ff-84a2-4e8fad7ad4eb.png)

アプリの動作を確認してみます。

ブラウザで，ICPコンソールにアクセスします。(`https://10.132.75.83:8443`)
Helm release一覧から，対象アプリを選択
[ICPのメニュー] > [Helm releases] > [capsmaltapp]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/68601b5c-e8b5-1e95-7610-731854e6156a.png)

SERVICE欄にある [capsmaltapp-service] を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/3b03c7fc-7634-d787-11ff-1f376f9dfc9f.png)

NodePort欄の `http 31110/TCP` をクリック (ポート番号は異なります)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/3b03e3a1-9d70-cf58-5ee0-f9336323e754.png)

コンテナ上のWebSphere Libertyが動作していることが分かります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/ceeb9ee8-d363-cebe-4112-7e85923aacf7.png)

URLで，REST(GET)のリソースパスを指定しましょう。
(私の場合，`http://10.132.75.83:31110/capsmaltapp/v1/example`)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69447/c3c605c8-4011-e39c-b450-5a2824814adc.png)

さきほどローカルPCで変更して，GitHubにpushしたコードが反映されていることが分かります。


# まとめ
## 本稿で行った初期設定
IBM Cloud Privateのノード，ICPコンソール，開発端末，GitHub，などいろんな場所で作業をしたので，結構大変だなーと感じた方もいらっしゃるかと思います。

しかし，ざっくり整理すると，実際は下記程度の作業しかしてません。

- Microservice Builderコマンド(bx dev create/build/run)
 - 雛形作成，ビルド，ローカルPCでコンテナ稼働確認
- GitHubのWebhook構成
- Microservice Builder Pipeline(Jenkinsマスター)
 - GitHubへのアクセス情報を入力して，Jenkinsマスターを構成 

とは言え，この構成を自らオープンソースで組み上げて構成しようとすると，実はいろんな箇所で骨の折れる作業が発生します。

## 今後つかっていく際にやること
次回以降はめちゃめちゃ楽です。コード書いてpush。これだけです。

- アプリ改修の場合 (あとは自動デプロイ)
 - コーディング
 - GitHubにpush

- 新規にアプリを追加する場合 (新規にリポジトリを用意するだけでOK。特に設定不要)
 - コーディング
 - GitHubの既存組織に新規アプリ名でリポジトリを作成する
 - GitHubにpush

Microservice Builderで作ったアプリは，生成された瞬間からCI/CDの枠組みに組み込まれています。

つまり，一度Microservice Builder Pipelineの構成を行うことで，継続的にアプリ更新を行って，IBM Cloud Privateにデプロイされる構成になります。

組織内で標準化に苦労している場合や，毎度CI/CDを含めた構成をプロジェクトごとに用意している方は，ありがたみを実感できると思います。

当然ながら，自由にカスタマイズすることも可能です。
例えば，

- パイプラインの各ステージ内で，既存のテストツールやロジックを流す
- ビルドとデプロイを分離する
- (従来の環境区分けをしたい場合) Prod/Test/Devのように対象を分けてデプロイする
- その他諸々



## おわりに
Kubernetes環境(IBM Cloud Private)を題材として，Microservice Builderというツールで，新規アプリ開発〜デプロイ自動化までを試してみました。

Microservice Builderは，Kubernetesをベースにマイクロサービスの開発・運用を助けてくれます。ただ，まだ一部しか利用できていないので，また実践編を書きたいと思います。


参考: 
Officialマニュアル: [Microservice Builder](https://www.ibm.com/support/knowledgecenter/en/SS5PWC/index.html)

IBM Cloud Private 導入手順 ==> [IBM Cloud Private: Kubernetesをオンプレミス(IaaS)に導入してみる](https://qiita.com/capsmalt/items/d15055ab3cb423d2d7ae)
CLI導入など ==> [IBM Cloud Private k8sクラスターをCLIで操作してみる](https://qiita.com/capsmalt/items/9f282ce26c58873e22b6)