EKSやGKEで動作確認したマニフェストをIKSで動かした結果


自己研鑽のメモであり、AWS EKS や GCP GKE で動かしたマニフェスト(YAML)は、IKSでも動くのか?  という疑問に対して、手を動かして調べた記録です。 

関連記事は以下の二つです。

* [AWS初心者だけど、EKSのクラスタを作って、NodePort と ELBアクセス、EBSのPVを確認したよ](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed)
* [GCP初心者が、GKEクラスタを作って、NodePort、ロードバランサー、永続ボリュームを使ってみたよ。](https://qiita.com/MahoTakara/items/1e36f82215f2af0b3e84)

---

# 準備事項

1. [IBM Cloud のアカウント取得](https://www.ibm.com/cloud/)
1. idt-installer による必要なコマンドのインストール

~~~
curl -sL https://ibm.biz/idt-installer | bash
~~~

上記で、必要なOSSコマンド brew,git,docker,kubectl,helm,bxをインストールしてくれます。
そして、クラウドにログインして、地域のセットまで実施しておきます。

~~~
bx login -a https://api.au-syd.bluemix.net
~~~

~~~
bx cs region-set ap-north
~~~

---


# クラスタの作成

メニューからコンテナーを選択すると、次の画面が表示されるので、「クラスターの作成」をクリックして、進めます。

![スクリーンショット 2018-10-22 13.22.33.png](https://qiita-image-store.s3.amazonaws.com/0/42829/70b8e6a4-4c3e-72c8-9cdc-c0f7f3659e71.png "スクリーンショット 2018-10-22 13.22.33.png")


---

東京リージョンの３つのデータセンターに、ワーカーノードを１台づつデプロイします。 

![スクリーンショット 2018-10-22 13.24.53.png](https://qiita-image-store.s3.amazonaws.com/0/42829/cc9339e8-b538-0f09-ae3f-44265c339e0c.png "スクリーンショット 2018-10-22 13.24.53.png")

---

ワーカーノードは、仮想サーバーの共有型と占有型、そして、物理サーバー（ベアメタル）の３つから選べます。
仮想サーバーのCPUコア数は、最小2コアから、最大56コアまで選択できます。 経験上では仮想サーバーで8コア以上使っても性能を出すためのチューニングが難しいので、８コア超えるワーカーノードが必要なら、ベアメタルがお勧めです。（個人の見解であり、会社を代表していません）

![スクリーンショット 2018-10-22 13.26.49.png](https://qiita-image-store.s3.amazonaws.com/0/42829/63306893-ada3-7fc5-1fbd-2b1956fec79f.png "スクリーンショット 2018-10-22 13.26.49.png")

---
ベアメタルの場合は、4コアから28コアまで利用できます。 ここでのコア数は物理的なコア数です。従って、Xeonプロセッサは、1コア=2スレッドですから、4コアの場合は、仮想サーバーのvCPU 8コアと同等になります。 でも経験上では、ベアメタルの方が性能は、はるかに上です。 でも料金は月額なので注意です。

![スクリーンショット 2018-10-22 13.27.10.png](https://qiita-image-store.s3.amazonaws.com/0/42829/76bd5630-6688-e8a7-16a0-b350daccf447.png "スクリーンショット 2018-10-22 13.27.10.png")

---

ディスクの暗号化にチェックと入れて、ゾーン（データセンター）あたりのワーカーノード数を１として、クラスタ名を作成します。

![スクリーンショット 2018-10-22 13.28.46.png](https://qiita-image-store.s3.amazonaws.com/0/42829/71088144-271c-792c-09b7-84e8cc2e2f9c.png "スクリーンショット 2018-10-22 13.28.46.png")

---

クラスタの作成が完了すると、次のアクセス手段をセットアップする画面が表示されます。 これを順番にやっていけば、k8sを利用できるようになります。

![スクリーンショット 2018-10-22 13.40.41.png](https://qiita-image-store.s3.amazonaws.com/0/42829/33b78eb4-eee1-e535-2c69-649b62b731b6.png "スクリーンショット 2018-10-22 13.40.41.png")

---


# クラスタへのアクセス

クラスタにアクセスするは、ibmcloudコマンド、または、bxコマンドで、次を実行すると、認証情報をダウンロードして後に、保管場所を指すための環境変数の設定が表示されるので、export KUBECONFIG... の行をコピペして、実行します。 これで、kubectlコマンドが利用できるようになります。

~~~
bx cs cluster-config iks1
<中略>

export KUBECONFIG=/Users/$USER/.bluemix/plugins/container-service/clusters/iks1/kube-config-tok04-iks1.yml
~~~

次のように、iksを選択されていることを確認して、kubectlコマンド実行します。

~~~
$ kubectl config get-contexts
CURRENT   NAME      CLUSTER   AUTHINFO            NAMESPACE
*         iks1      iks1      takara@jp.ibm.com   default
~~~

ノードのリストを表示したところです。 
   
~~~
$ kubectl get nodes
NAME            STATUS    ROLES     AGE       VERSION
10.132.253.17   Ready     <none>    30m       v1.10.8+IKS
10.192.9.105    Ready     <none>    30m       v1.10.8+IKS
10.193.10.41    Ready     <none>    30m       v1.10.8+IKS
~~~

クラスタのワーカーノード上のポッドのリストです。指定しなくてもcalico-nodeが動作しています。 

~~~
$ kubectl get po --all-namespaces
NAMESPACE     NAME                                        READY     STATUS    RESTARTS   AGE
ibm-system    ibm-cloud-provider-ip-128-*-75bf7445-6hqwr  1/1       Running   0          15m
ibm-system    ibm-cloud-provider-ip-128-*-75bf7445-z5wlm  0/1       Pending   0          15m
ibm-system    ibm-cloud-provider-ip-128-*-f79fbc6b-ctj7g  1/1       Running   0          59m
ibm-system    ibm-cloud-provider-ip-128-*-f79fbc6b-ps7hr  0/1       Pending   0          59m
ibm-system    ibm-cloud-provider-ip-165-*-769c455c-mlsp7  0/1       Pending   0          48m
ibm-system    ibm-cloud-provider-ip-165-*-769c455c-s88kn  1/1       Running   0          48m
ibm-system    ibm-cloud-provider-ip-169-*-ccfbcf-8smw4    1/1       Running   0          45m
ibm-system    ibm-cloud-provider-ip-169-*-ccfbcf-j65n6    0/1       Pending   0          45m
kube-system   calico-kube-controllers-67ddb99848-l4d5x    1/1       Running   0          1h
kube-system   calico-node-b978z                           2/2       Running   0          1h
kube-system   calico-node-ks9tn                           2/2       Running   0          1h
kube-system   calico-node-q5prc                           2/2       Running   0          1h
kube-system   heapster-74547548dd-bxbl7                   2/2       Running   0          1h
kube-system   ibm-file-plugin-6f544b66c5-vswnh            1/1       Running   0          1h
kube-system   ibm-keepalived-watcher-hsw78                1/1       Running   0          1h
kube-system   ibm-keepalived-watcher-jkfth                1/1       Running   0          1h
kube-system   ibm-keepalived-watcher-sjgz4                1/1       Running   0          1h
kube-system   ibm-kube-fluentd-5djs4                      1/1       Running   0          1h
kube-system   ibm-kube-fluentd-fz6n6                      1/1       Running   0          1h
kube-system   ibm-kube-fluentd-hpszh                      1/1       Running   0          1h
kube-system   ibm-storage-watcher-56d698bc7-mc4bw         1/1       Running   0          1h
kube-system   kube-dns-amd64-84454d78cf-vlgft             3/3       Running   0          1h
kube-system   kube-dns-amd64-84454d78cf-z6c2c             3/3       Running   0          1h
kube-system   kube-dns-autoscaler-87c768b59-p5d9s         1/1       Running   0          1h
kube-system   kubernetes-dashboard-66ddf6bfd-hfx4v        1/1       Running   1          1h
kube-system   public-cr41679d0*56c-alb1-bd445c945-twjg2   0/2       Pending   0          55m
kube-system   public-cr41679d0*56c-alb1-bd445c945-wctl9   2/2       Running   0          55m
kube-system   public-cr41679d0*56c-alb2-96b88774-72nhw    0/2       Pending   0          45m
kube-system   public-cr41679d0*56c-alb2-96b88774-xgd7h    2/2       Running   0          45m
kube-system   public-cr41679d0*56c-alb3-87b788b65-nrxzt   2/2       Running   0          45m
kube-system   public-cr41679d0*56c-alb3-87b788b65-sp7pc   0/2       Pending   0          45m
kube-system   vpn-75f9f5f696-ccbq7                                          
~~~

---

# アプリケーションのデプロイ

ネットワークとストレージの基本的な部分を以下の３つのケースで確認しました。ここで使ったマニフェストは、「AWS初心者だけど、EKSのクラスタを作って、NodePort と ELBアクセス、EBSのPVを確認したよ」で利用したものを再利用しました。

1. ノードポート パブリックIPアドレスでノードのポートをアクセスします。
2. ロードバランサー ロードバランサーのパブリックIPでアクセスします。
3. 永続ボリューム ブロックストレージをアクセスします。

---

## 1. ノードポート

マニフェストは、前述のEKSとGKEに使ったものと同じものです。

~~~
$ kubectl apply -f apl-1.yml
deployment.apps/web-apl1 created
service/web-apl1 created
imac:yaml maho$ kubectl get svc,deploy,po
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   172.21.0.1       <none>        443/TCP        54m
service/web-apl1     NodePort    172.21.128.124   <none>        80:30082/TCP   18s

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/web-apl1   1         1         1            1           18s

NAME                            READY     STATUS    RESTARTS   AGE
pod/web-apl1-5dd7b5dcc4-6ztbm   1/1       Running   0          18s
~~~

アクセステストのために、ワーカーノードのパブリックIPをリストします。 ログインは完了しているのですが、bx sl initで IaaSのトークンを取る必要があるので、必ず実行しておきます。仮想サーバーのリストを表示します。

~~~
$ bx sl init

$ bx sl vs list
id         hostname                 ドメイン     cpu   メモリー   public_ip   private_ip      datacenter
63893657   kube-tok02-cr4167*c-w2   cloud.ibm    2     4096    161.*.*.*   10.132.253.17   tok02
63893651   kube-tok04-cr4167*c-w1   cloud.ibm    2     4096    128.*.*.*   10.192.9.105    tok04
63893663   kube-tok05-cr4167*c-w3   cloud.ibm    2     4096    165.*.*.*   10.193.10.41    tok05
~~~

ベアメタルのワーカーノードの場合は、次の様にします。

~~~
$ bx sl hardware list
id        hostname                 ドメイン    public_ip   private_ip     datacenter
1403293   kube-tok02-cr09a8*4-w4   cloud.ibm 161.*.*.*2  10.132.253.38   tok02     
~~~

マニフェストをデプロイして、確認します。 サービスのTYPEに、NodePortが表示されアクセス可能になっていることが判ります。
このマニフェストは、[EKS/GKEで利用したもの](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed#1ノードポート)と同じです。

~~~
$ kubectl apply -f apl-1.yml
deployment.apps/web-apl1 created
service/web-apl1 created

$ kubectl get svc,deploy,po
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   172.21.0.1       <none>        443/TCP        54m
service/web-apl1     NodePort    172.21.128.124   <none>        80:30082/TCP   18s

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/web-apl1   1         1         1            1           18s

NAME                            READY     STATUS    RESTARTS   AGE
pod/web-apl1-5dd7b5dcc4-6ztbm   1/1       Running   0          18s
~~~


curlでノードのパブリックIPを指定して、アクセスします。 ポッドは１個なので、どのワーカーノードにアクセスしても、同じポッドが応答しています。

~~~
$ curl http://128.*.*.*:30082/
Hostname: web-apl1-5dd7b5dcc4-6ztbm

$ curl http://165.*.*.*:30082/
Hostname: web-apl1-5dd7b5dcc4-6ztbm

$ curl http://161.*.*.*:30082/
Hostname: web-apl1-5dd7b5dcc4-6ztbm
~~~



## 2. ロードバランサー

このマニフェストも[EKS/GKEで利用したもの](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed#2%E3%83%AD%E3%83%BC%E3%83%89%E3%83%90%E3%83%A9%E3%83%B3%E3%82%B5%E3%83%BC)と同じです


~~~
$ kubectl apply -f apl-3.yml
deployment.apps/web-apl3 created
service/web-apl3 created

$ kubectl get svc,deploy,po
NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
service/kubernetes   ClusterIP      172.21.0.1       <none>           443/TCP        58m
service/web-apl3     LoadBalancer   172.21.8.26      128.*.*.*        80:32549/TCP   5s

NAME                             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/web-apl3   1         1         1            1           6s

NAME                            READY     STATUS    RESTARTS   AGE
pod/web-apl3-dc7dcbfdf-vp55l    1/1       Running   0          5s

~~~

ロードバランサーのVIPへアクセスすることで、ポッドからの応答が帰ってきています。

~~~
$ curl http://128.*.*.*/
Hostname: web-apl3-dc7dcbfdf-vp55l

$ curl http://128.*.*.*/
Hostname: web-apl3-dc7dcbfdf-vp55l

$ curl http://128.*.*.*/
Hostname: web-apl3-dc7dcbfdf-vp55l
~~~




## 3. 永続ボリューム

永続ボリューム要求を作成して、ポッドからマウントします。このマニフェストも[EKS/GKEで利用したもの](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed#3%E6%B0%B8%E7%B6%9A%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0)です。

永続ボリューム要求のオブジェクトを作成します。

~~~
$ kubectl apply -f pvc.yml
persistentvolumeclaim/data1 created

$ kubectl get pvc
NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
data1     Bound     pvc-ce98006c-d5bd-11e8-b359-d22a4ee08c9c   20Gi       RWO            ibmc-file-bronze   2m
~~~

ポッドのマニフェストを適用して、永続ボリュームをマウントします。

~~~
$ kubectl apply -f pod.yml
pod/pod1 created

$ kubectl get po
NAME                        READY     STATUS    RESTARTS   AGE
pod1                        1/1       Running   0          11s
~~~

ポッドに対話型シェルを起動して、永続ボリュームのマウント状態を確認します。 /mntの下に、永続ボリュームがマウントされています。
マニフェストでは、ボリューム容量は、2GBでしたが、IKSでは最小ボリューム容量が20GBが確保されています。(要注意)

~~~
$ kubectl exec -it pod1 -- bash
root@pod1:/# df -h
Filesystem                                                      Size  Used Avail Use% Mounted on
overlay                                                          99G  1.3G   92G   2% /
tmpfs                                                           2.0G     0  2.0G   0% /dev
tmpfs                                                           2.0G     0  2.0G   0% /sys/fs/cgroup
fsf-tok0201d-fz.service.softlayer.com:/IBM02SEV289550_9/data01   20G     0   20G   0% /mnt
/dev/mapper/docker_data                                          99G  1.3G   92G   2% /etc/hosts
shm                                                              64M     0   64M   0% /dev/shm
tmpfs                                                           2.0G   12K  2.0G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                                                           2.0G     0  2.0G   0% /sys/firmware
root@pod1:/# ls -al /mnt
total 8
drwxr-xr-x 2 nobody 4294967294 4096 Oct 22 05:47 .
drwxr-xr-x 1 root   root       4096 Oct 22 05:49 ..
~~~


# クリーンアップ方法

削除したいクラスタの右端に、メニューのアイコン「...」があるので、クリックして削除を選択する。

![スクリーンショット 2018-10-22 18.51.23.png](https://qiita-image-store.s3.amazonaws.com/0/42829/cde7252f-c130-3867-fb3b-9b83c039fe5f.png "スクリーンショット 2018-10-22 18.51.23.png")


# 感想

永続ボリューム要求やロードバランサーに関わる部分は、マニフェストを修正しないと、いけないと思っていましたが、実際にアプライすると、拍子抜けするくらい簡単に動いてしまいました。 

もちろん、awsコマンド、gcloudコマンド、ibmcloud / bx コマンドの部分は、それぞれ、仕様が異なりますが、kubectlで適用するマニフェストは、クラウドベンダーに関係なく使えました。


## 参考資料
[1] IKS チュートリアル、https://console.bluemix.net/docs/containers/cs_tutorials.html#cs_cluster_tutorial