ICPをIBM Cloudにインストールしてみる

変更履歴：
2019/1/25 ICP導入前提で、必要なソフトウェア導入手順が丸々漏れていました・・・。追記しました。その他、記載ミスを修正

IBM Cloud Private(以下、ICP)を、IBM CloudのIaaS上でインストールしてみました。
IBM Cloud Privateは、Dockerコンテナのオーケストレーションを担うkubernetesをベースに、様々なOSSを組み込んで運用しやすくしたソフトウェアです。
ICP概要はこちらの記事をご参照ください。
[IBM Cloud Private: Kubernetesをオンプレミス(IaaS)に導入してみる](https://qiita.com/capsmalt/items/d15055ab3cb423d2d7ae)


バージョン: ICP 3.1.1 (2018/12時点で最新)
エディション: ICP Community Edition (ICPCE、無償版)

流れはこんな感じです。
1. IBM Cloudで仮想サーバーをオーダー
2. 仮想サーバー上のOS(Ubuntu)のセットアップ
3. (masterノードのみ)ICPを導入するための準備
4. ICP導入
5. ICPの管理コンソールにログイン

執筆にあたり、以下記事を参考にさせていただきました。

- [AWSにIBM Cloud Private-CE 3.1をインストールする](https://qiita.com/sotoiwa/items/9cab9497d9753e1984ed)
- [無償版 Kubernetes インストール手順 (ICP CE V3.1.0)](https://qiita.com/capsmalt/items/fe83a08a619ae9b296d0)
- [IBM Cloud Private 3.1 インストール方法（RHEL編)](https://blogs.networld.co.jp/main/2018/10/ibm-cloud-priva-3599.html)

####0. 前提
IBM Cloudのアカウントが必要です。無償のアカウントとして、ライトアカウントがあります。
ライトアカウントでは、IaaSのオーダーができないため、アカウントのアップグレードが必要になります。
アカウントやIBM Cloudでの仮想サーバーのオーダーについては記事しましたので、よろしければご覧ください。
[初めてのIBM Cloud IaaS] (https://qiita.com/sirotans/items/0a6005dd19aa41143152)

####1. 仮想サーバーをセットアップ
####1-1. IBM Cloudで仮想サーバーをオーダー

IBM Cloudにログインすると、ダッシュボード画面になるかと思います。
画面上部の「カタログ」をクリックすると、IBM Cloudでオーダーできるカタログ画面になります。
画面左上のカテゴリーから「コンピュート」を選択し、「Virtual Server」を選択します。

![catalog01.png](https://qiita-image-store.s3.amazonaws.com/0/135937/418aea3a-8b6b-2298-7ebf-57fb7d71674c.png)


仮想サーバーはいくつか種類がありますが、ベーシックな「Public Virtual Server」を選択します。
Public Virtual Serverの場合、GUIからオーダーした場合でも、パワーオフしているときは、課金が停止される(Suspend Billing)ようになりましたので、テスト用などで常時起動しない場合は、起動時間にもよりますが、全稼働した場合の25%の料金に収めることも可能です(全く稼働停止していても、最低25%の料金は掛かる)。
それでも不安な場合は、テスト用ならばTransient Server(Public Virtual Serverの25%の料金。ただしクラウドの利用状況によって、他ユーザーに優先され使えない可能性がある)でも良いと思います。

![catalog02.png](https://qiita-image-store.s3.amazonaws.com/0/135937/e977e0dc-acc4-5c82-8b0a-0e1e51d14f80.png)


今回は2台構成とします。システム稼働要件から、以下のようにしました。
Masterノード: 

- 数量1, Billing: 毎時, ホスト名: icpmaster01(任意の名前), ドメイン: XXX.cloud(任意の名前)
- 配置グループ: なし
- 場所: アジア太平洋、プルダウンメニューで「TOK04 - Tokyo」を選択(TOK02、TOK05も東京リージョンで選択可能です)
- B1.8x16 8vCPU, 16GB RAM
- イメージ: Ubuntu 18.04 Minimal LTS
- ディスク:ブート・ディスク 25GB, ディスク1 200GB
- ネットワーク・インターフェース: 100Mbps Public & Private Network Uplinks

Workerノード: 

- 数量1 , Billing: 毎時, ホスト名: icpworker01(任意の名前), ドメイン: XXX.cloud(任意の名前)
- 配置グループ: なし
- 場所: アジア太平洋、プルダウンメニューでTOK04 - Tokyoを選択
- B1. 2x4 2vCPUs, 4GB RAM
- イメージ: Ubuntu 18.04 Minimal LTS
- ディスク:ブート・ディスク 25GB, ディスク1 150GB
- ネットワーク・インターフェース: 100Mbps Public & Private Network Uplinks

(参考)[ICPv3.1.1のシステム稼働要件](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.1/supported_system_config/hardware_reqs.html)

####1-2. セキュリティーグループの設定
IBM Cloudでは、デフォルトでPublic IPアドレス(インターネット通信可能なPublic Network Interface)と、Private IPアドレス(IBM Cloudデータセンター内・データセンター間で通信可能なPrivate Network Interface)を1つずつ付与されます。
デフォルトのオーダーの場合は、ファイアウォールも何もオーダーしていないので、外部から意図しない通信を受信する危険性があります。
ここでは、セキュリティーグループを利用して、必要なポートだけ開けることにします。
注意が必要なのは、Public Network Interface、Private Network Interfaceごとに、5つまでのルール設定のため、まとめて一つのルールを作成するか、よく使うルール(ICMP,80,443,22(ssh)など)はあらかじめ設定すると良いでしょう。
なおSecurity Group以外にもIBM Cloudのファイアウォールサービスもありますが、有償となります。

Public Network Interface
8001, 8443, 8500については、masterノードのみ。

(参考)[ICPv3.1.1の使用するポート番号](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.1/supported_system_config/required_ports.html)

| Direction | Type   | Protocol   | Port Range | Source/Destination |
|:----------|:-------|:-----------|:-----------|:-------------------|
| Outbound  | IPv4   | Any        | Any        | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 80         | 0.0.0.0/0          |
| Inbound   | IPv4   | ICMP       | Any        | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 443        | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 22         | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 8001       | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 8443       | 0.0.0.0/0          |
| Inbound   | IPv4   | TCP        | 8500       | 0.0.0.0/0          |

Private Network Interface

| Direction | Type   | Protocol   | Port Range | Source/Destination |
|:----------|:-------|:-----------|:-----------|:-------------------|
| Outbound  | IPv4   | Any        | Any        | 0.0.0.0/0          |
| Inbound   | IPv4   | Any        | Any         | \<Private IPアドレスのサブネット>          |


####2. 仮想サーバー上のOS(Ubuntu)のセットアップ
仮想サーバーにrootユーザーでログインします。

この後、masterノードとworkerノードで作業をしていきますが、2ノード同じ作業をするのが面倒、と思います。
IBM Cloudでは、テンプレート保存をして、保存したテンプレートを適用すると、イメージバックアップ/リストアのようなことができます(手順は別途書きます)。
ここでは、2ノードともに手作業でやっていきます。

```
$ ssh -l root <IPアドレス>
``` 
####2-1. ubuntuユーザー作成(masterノード, workerノード)
```
# adduser ubuntu
# gpasswd -a ubuntu sudo
# su - ubuntu
# sudo passwd ubuntu  <--パスワードの設定
```

以下、ubuntuユーザーで作業します。
####2-2. OS更新(masterノード, workerノード)
```
$ sudo apt update
$ sudo apt upgrade
$ sudo apt dist-upgrade
$ sudo apt autoremove
```

上記実行すると、"sudo apt upgrade"のところで、以下のようなエラーが出る場合があります。


```
run-parts: /etc/kernel/postinst.d/x-grub-legacy-ec2 exited with return code 1
dpkg: error processing package linux-image-4.15.0-42-generic (--configure):
 installed linux-image-4.15.0-42-generic package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 linux-image-4.15.0-42-generic
E: Sub-process /usr/bin/dpkg returned an error code (1)
```
df /コマンドのリターンを確認して、/boot/grub/menu.lst内の、
<変更前># groot=XXX --> <変更後> # groot=/dev/xda2
に変更します(コメントアウトのままでOK)。
そのあと再度実行。

```
$ sudo df /
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/xvda2      25412852 1437724  22661184   6% /

$ sudo vi /boot/grub/menu.lst

```

Ubuntuのエラー対処については、[ここ](https://ubuntuforums.org/showthread.php?t=2395594)を参考にしました。


####2-3. 前提ソフトウェアの導入(masterノード, workerノード)

Pythonをインストールします。が、すでにPython3が導入されていましたので、パスを変更します。

```
$ sudo python --version

Command 'python' not found, but can be installed with:

apt install python3       
apt install python        
apt install python-minimal

You also have python3 installed, you can run 'python3' instead.
$ sudo ln -s /usr/bin/python3 /usr/bin/python
$ sudo python --version
Python 3.6.7
```

socatをインストールします。

```
$ sudo apt install socat
```

Dockerをインストールする準備をします。

```
$ sudo apt-get update
$ sudo apt-get install \
> apt-transport-https \
> ca-certificates \
> curl \
> software-properties-common

$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK

$ sudo add-apt-repository \
> "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) \
> stable"

$ sudo apt-get update
```

Dockerをインストールします。

```
$ sudo apt-cache madison docker-ce
 docker-ce | 5:18.09.0~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 18.06.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 18.06.0~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 18.03.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages

$ sudo apt-get install docker-ce=18.03.1~ce~3-0~ubuntu

$ sudo docker version
Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Wed Jun 20 21:43:51 2018
 OS/Arch:      linux/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Wed Jun 20 21:42:00 2018
  OS/Arch:      linux/amd64
  Experimental: false
```

####2-4. hostnameを変更(masterノード, workerノード)
```
$ sudo hostname icpmaster01
$ sudo vi /etc/hostname
```
workerノードでも同様に実行します。

```
$ sudo hostname icpworker01
$ sudo vi /etc/hostname
```

####2-5. /etc/hostsを変更(masterノード, workerノード)

```
$ sudo vi /etc/hosts
```
```ruby:hostsファイル
127.0.0.1	localhost.localdomain localhost
<masterノードのPublic IPアドレス>	icpmaster01
<workerノードのPublic IPアドレス>	icpworker01
```

####2-6. SSH鍵の交換(masterノード, workerノード)
ICPインストール時に、masterノードからworkerノードへSSH接続できるようにするために、ubuntuユーザーでSSH鍵の交換を実行。

```
(masterノードで実行)
$ ssh-keygen -b 4096 -f ~/.ssh/id_rsa -N ""
$ cat ~/.ssh/id_rsa.pub | tee -a ~/.ssh/authorized_keys
出力結果をコピペ。
(workerノードで実行)
$ mkdir ~/.ssh
$ echo "<上記の出力された公開鍵>" >> ~/.ssh/authorized_keys
```

SSHログイン可能なことを確認

```
$ sudo ssh ubuntu@icpmaster01 whoami
The authenticity of host 'icpmaster01 (xx.xx.xx.xx)' can't be established.
ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'icpmaster01,xx.xx.xx.xx' (ECDSA) to the list of known hosts.
ubuntu

$ sudo ssh ubuntu@icpworker01 whoami
The authenticity of host 'icpworker01 (yy.yy.yy.yy)' can't be established.
ECDSA key fingerprint is SHA256:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'icpworker01,yy.yy.yy.yy' (ECDSA) to the list of known hosts.
ubuntu

```


####3. ICPを導入するための準備(以降、masterノードのみ)
ここからmasterノードのみ作業します。

####3-1. dockerイメージのダウンロード

```
$ sudo docker pull ibmcom/icp-inception:3.1.1
(省略)
Status: Downloaded newer image for ibmcom/icp-inception:3.1.1
```

####3-2. ファイル抽出
```
$ sudo mkdir /opt/ibm-cloud-private-ce-3.1.1
$ cd /opt/ibm-cloud-private-ce-3.1.1
$ sudo docker run -e LICENSE=accept \
  -v "$(pwd)":/data ibmcom/icp-inception:3.1.1 cp -r cluster /data
```
####3-3. hostsファイルの編集

```
$ sudo vi ./cluster/hosts
```
今回は、masterノードとproxyノードが同居するため同じIPアドレスに変更、managementノードとvaノードは導入しないためそのままにします。

```
[master]
<masterノードのPublic IPアドレス>

[worker]
<workerノードのPublic IPアドレス>

[proxy]
<masterノードのPublic IPアドレス>

#[management]
#4.4.4.4

#[va]
#5.5.5.5
```

####3-4. /home/ubuntu/.sshにある秘密鍵をコピー

```
$ sudo cp ~/.ssh/id_rsa ./cluster/ssh_key
```

####3-5. ICPインストール時の設定であるconfig.yamlファイルの編集

```
$ cd /opt/ibm-cloud-private-ce-3.1.1
$ sudo cp ./cluster/config.yaml ./cluster/config.yaml.org
$ sudo vi ./cluster/config.yaml
```
編集するのは3箇所。

```ruby:config.yamlファイル
## Advanced Settings
default_admin_user: admin <-- ICP管理コンソールのユーザー名。必要に応じて変更
default_admin_password: admin <-- ICP管理コンソールのユーザーパスワード。必要に応じて変更
ansible_user: ubuntu  <-- ここではubuntuユーザーで作業するため、コメントアウトして変更
ansible_become: true <-- コメントアウト
ansible_become_password: XXXXXXXX <-- コメントアウトしてubuntuユーザーのパスワードに変更
(省略)
## External loadbalancer IP or domain
## Or floating IP in OpenStack environment
cluster_lb_address: xx.xx.xx.xx <--コメントアウトしてmasterノードのPublic IPアドレスに変更

## External loadbalancer IP or domain
## Or floating IP in OpenStack environment
proxy_lb_address: xx.xx.xx.xx <--コメントアウトしてmasterノードのPublic IPアドレスに変更
(省略)
## Allow loopback dns server in cluster nodes
loopback_dns: true <-- コメントアウトしてtrueに変更
```

####3-6. インストール実行
```
$ sudo docker run --net=host -t -e LICENSE=accept \
> -v "$(pwd)":/installer/cluster ibmcom/icp-inception:3.1.1 install -vvv | tee ~/install.log
```
IaaSのネットワーク回線を100Mbps(NICの追加料金無し)にしているせいか、HELMパッケージのアップロードで結構時間がかかり、待つこと1時間あまり。

```
PLAY RECAP *********************************************************************
xx.xx.xx.xx              : ok=150  changed=91   unreachable=0    failed=0   
yy.yy.yy.yy              : ok=142  changed=89   unreachable=0    failed=0   
localhost                  : ok=248  changed=155  unreachable=0    failed=0   


POST DEPLOY MESSAGE ************************************************************

The Dashboard URL: https://<masterノードのPublic IPアドレス>:8443, default username/password is admin/admin

Playbook run took 0 days, 1 hours, 12 minutes, 31 seconds
```

####3-7. インストールに失敗したら
~/install.logにログがあるので、そちらを確認します。
一旦アンインストールしてから、再度3-6. インストールへ。

```
$ sudo docker run -e LICENSE=accept --net=host \
-t -v "$(pwd)":/installer/cluster ibmcom/icp-inception:3.1.1 uninstall

$ sudo service docker restart
```

####3-8. インストール完了

ブラウザで
https://\<masterノードのPublic IPアドレス>:8443/
へアクセスします。
おそらく、ブラウザでセキュリティー警告が出ますので、上記URLへのアクセスを例外承認をします。
管理コンソールの画面が出たらインストール成功！

![icptop.png](https://qiita-image-store.s3.amazonaws.com/0/135937/82be8454-6353-6d12-73f5-bb2c799e0525.png)

左下に以下を入力してログイン。
ID: admin(デフォルト)
パスワード: admin(デフォルト)
3-5.で述べたように、ユーザー名、パスワードはインストール時にconfig.yaml内の以下で変更できます。


今回はパブリッククラウドのIaaS環境に導入しましたが、もし同様スペックの物理マシンやVMwareゲストOSが利用できれば、無償で導入は可能です。なかなか必要コア数が大きいですが・・・。

Virtual Physical Serverの場合は、電源ONの場合は利用料金が追加され続けますので、不要な時はGUIからPOWER OFFしておきましょう。

ここまでお付き合いいただきありがとうございました。
次回は、導入したICPを使って何かしたいと思います。