GCP初心者が、GKEクラスタを作って、NodePort、ロードバランサー、永続ボリュームを使ってみたよ。


これは、自己研鑽のメモです。


# 準備事項

事前に次の３点を実施しておきます。 

* GCP アカウント取得、https://cloud.google.com/
* Google Cloud SDK のインストール、https://cloud.google.com/sdk/downloads?hl=JA#interactive
* Install and Set Up kubectl、https://kubernetes.io/docs/tasks/tools/install-kubectl/

---

# GKEクラスタのセットアップ

## クラスタの起動

東京(asis-northeast1)のリージョンのデータセンターに各1ノード、合計３のノードを立ち上げます。 
[Google Cloud Platform](https://console.cloud.google.com/)のメニューから、Kubenetes Engine へ移動して、「クラスタを作成」をクリックします。

![スクリーンショット 2018-10-21 9.20.28.png](https://qiita-image-store.s3.amazonaws.com/0/42829/c2c65125-5b82-74f4-56c7-33f3d28ea712.png "スクリーンショット 2018-10-21 9.20.28.png")

そして、入力フォーム下部の「詳細オプション」を展開して、ネットワークポリシーを有効にするにチェックを入れます。これで Calico のデーモンセットがインストールされ、アクセスポリシーが適用できるようになります。

![スクリーンショット 2018-10-22 10.01.24.png](https://qiita-image-store.s3.amazonaws.com/0/42829/9a79e26d-88eb-ab45-02c7-e5800087ba1f.png "スクリーンショット 2018-10-22 10.01.24.png")


筆者が測ったところ、開始 9:22  完了 9:30  8分以内の起動時間でした。 



## 環境変数の設定
複数のk8sの環境を作っているので、ホームディレクトリに、ディレクトリ gcp-gke を作ってコマンドを集めています。 kubectlコマンドは、CNCFからダウンロードしたコマンドを利用しますから、このディレクトリには置かないで、/usr/local/binに置きました。

~~~
$ mkdir gcp-gke
$ cd gcp-gke
$ echo $KUBECONFIG
$ mkdir .kube
$ export KUBECONFIG=/Users/maho/gcp-gke/.kube/config
$ echo $KUBECONFIG
/Users/maho/gcp-gke/.kube/config
~~~


## kubecltコマンドのセットアップ

GKEのクラスタのリスト画面のクラスタ gke1行の「接続」をクリックして、「クラスタに接続」のポップアップを表示します。

![スクリーンショット 2018-10-21 9.33.55.png](https://qiita-image-store.s3.amazonaws.com/0/42829/acac5f19-d6f3-f5d4-483c-8d263c49d586.png "スクリーンショット 2018-10-21 9.33.55.png")

gloudコマンドが表示されるので、パソコンにコピペして実行しました。

![スクリーンショット 2018-10-21 9.34.15.png](https://qiita-image-store.s3.amazonaws.com/0/42829/dbae988a-621e-a9df-f10f-5ba79ea5701d.png "スクリーンショット 2018-10-21 9.34.15.png")

実行後に、kubectl コマンドの接続先リストを表示して、確認したところです。

~~~
$ gcloud beta container clusters get-credentials gke1 --region asia-northeast1 --project intense-base-183010
Fetching cluster endpoint and auth data.
kubeconfig entry generated for gke1.

$ kubectl config get-contexts
CURRENT   NAME                                           CLUSTER                                        AUTHINFO                                       NAMESPACE
*         gke_intense-base-183010_asia-northeast1_gke1   gke_intense-base-183010_asia-northeast1_gke1   gke_intense-base-183010_asia-northeast1_gke1   
~~~

ノードのリスト表示

~~~
$ kubectl get no
NAME                                  STATUS    ROLES     AGE       VERSION
gke-gke1-default-pool-7610f13e-9hdr   Ready     <none>    15m       v1.9.7-gke.6
gke-gke1-default-pool-7ad8b5d5-zn68   Ready     <none>    15m       v1.9.7-gke.6
gke-gke1-default-pool-a6fb39f0-2qwc   Ready     <none>    15m       v1.9.7-gke.6
~~~


ポッドのリストです。 calico-nodeも動作しています。

~~~
$ kubectl get po --all-namespaces
NAMESPACE     NAME                                                 READY     STATUS    RESTARTS   AGE
kube-system   calico-node-79xtz                                    2/2       Running   0          1h
kube-system   calico-node-8dv6z                                    2/2       Running   0          1h
kube-system   calico-node-c9t7t                                    2/2       Running   0          1h
kube-system   calico-node-vertical-autoscaler-664dc78496-xz64v     1/1       Running   0          1h
kube-system   calico-typha-67c95cc844-s6wp2                        1/1       Running   0          1h
kube-system   calico-typha-horizontal-autoscaler-b69899885-wj8hc   1/1       Running   0          1h
kube-system   calico-typha-vertical-autoscaler-6947c8fd8c-cps7f    1/1       Running   1          1h
kube-system   event-exporter-v0.1.9-5c8fb98cdb-7l7qb               2/2       Running   4          1h
kube-system   fluentd-gcp-v2.0.17-j5pns                            2/2       Running   0          1h
kube-system   fluentd-gcp-v2.0.17-jrgvx                            2/2       Running   0          1h
kube-system   fluentd-gcp-v2.0.17-w89g7                            2/2       Running   0          1h
kube-system   heapster-v1.5.2-8699c56b8c-g729q                     3/3       Running   3          1h
kube-system   ip-masq-agent-4jngg                                  1/1       Running   0          1h
kube-system   ip-masq-agent-lg29t                                  1/1       Running   0          1h
kube-system   ip-masq-agent-n9k57                                  1/1       Running   0          1h
kube-system   kube-dns-5dcfcbf5fb-9t8gx                            4/4       Running   1          1h
kube-system   kube-dns-5dcfcbf5fb-9vkb8                            4/4       Running   0          1h
kube-system   kube-dns-autoscaler-69c5cbdcdd-t7wcq                 1/1       Running   0          1h
kube-system   kube-proxy-gke-gke1-default-pool-92b16305-s2xx       1/1       Running   0          1h
kube-system   kube-proxy-gke-gke1-default-pool-d456928e-v0rr       1/1       Running   0          1h
kube-system   kube-proxy-gke-gke1-default-pool-dc1f4e5e-2l33       1/1       Running   0          1h
kube-system   kubernetes-dashboard-d746596c4-nz446                 1/1       Running   1          1h
kube-system   l7-default-backend-57856c5f55-b9w6l                  1/1       Running   0          1h
kube-system   metrics-server-v0.2.1-7f8dd98c8f-jk7gg               2/2       Running   0          1h
~~~



---

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

ネットワークとストレージの基本的な部分を以下の３つのケースで確認しました。ここで使ったマニフェストは、[AWS初心者だけど、EKSのクラスタを作って、NodePort と ELBアクセス、EBSのPVを確認したよ](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed)で利用したものを再利用しました。

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

---

## 1.ノードポート

ファイアウォールの設定で、NodePortの範囲を開けておきます。

~~~
$ gcloud compute firewall-rules create myservice --network=default --allow tcp:30000-32765
Creating firewall.../Created [https://www.googleapis.com/compute/v1/projects/intense-base-183010/global/firewalls/myservice].                                                      
Creating firewall...done.                                                                                                                                                          
NAME       NETWORK  DIRECTION  PRIORITY  ALLOW            DENY
myservice  default  INGRESS    1000      tcp:30000-32765
~~~

マニフェストを適用します。

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

このマニフェストは、[EKSで利用したもの](https://qiita.com/MahoTakara/items/91ec1c4a24100798a9ed#1%E3%83%8E%E3%83%BC%E3%83%89%E3%83%9D%E3%83%BC%E3%83%88)と同じものです。

次は結果の確認です。

~~~
$ kubectl get svc,deploy,po
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.39.240.1     <none>        443/TCP        41m
service/web-apl1     NodePort    10.39.246.189   <none>        80:31374/TCP   32s

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

NAME                            READY     STATUS    RESTARTS   AGE
pod/web-apl1-5c4485bd46-5wnq9   1/1       Running   0          32s
~~~

ノードのIPアドレスのリストは、次のコマンドで取得します。

~~~
$ gcloud compute instances list
NAME                                 ZONE               MACHINE_TYPE  INTERNAL_IP  EXTERNAL_IP  STATUS
gke-gke1-default-pool-7610f13e-9hdr  asia-northeast1-a  g1-small      10.146.0.2   3*.*.*.135   RUNNING
gke-gke1-default-pool-a6fb39f0-2qwc  asia-northeast1-b  g1-small      10.146.0.4   3*.*.*.52    RUNNING
gke-gke1-default-pool-7ad8b5d5-zn68  asia-northeast1-c  g1-small      10.146.0.3   3*.*.*.72    RUNNING
~~~

インターネットからのアクセス結果です。 ポッドが一つなので、どのノードにアクセスしても、同じポッドに転送されています。

~~~
$ curl http://3*.*.*.135:31374/
Hostname: web-apl1-5c4485bd46-5wnq9

$ curl http://3*.*.*.52:31374/
Hostname: web-apl1-5c4485bd46-5wnq9

$ curl http://3*.*.*.72:31374/
Hostname: web-apl1-5c4485bd46-5wnq9
~~~



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

模擬アプリケーションのマニフェストは、[EKSで利用したもの](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      10.39.240.1     <none>          443/TCP        47m
service/web-apl3     LoadBalancer   10.39.242.81    3*.*.*.45       80:31446/TCP   1m

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

NAME                            READY     STATUS    RESTARTS   AGE
pod/web-apl3-585949549c-727zv   1/1       Running   0          1m
~~~

ポッドは１個だけですが、VIPにアクセスと、ポッドに転送されていることが確認できます。

~~~
$ curl http://3*.*.*.45/
Hostname: web-apl3-585949549c-727zv

$ curl http://3*.*.*.45/
Hostname: web-apl3-585949549c-727zv

$ curl http://3*.*.*.45/
Hostname: web-apl3-585949549c-727zv
~~~




## 3.永続ボリューム

永続ボリューム要求のマニフェストを適用します。 [これもEKSで利用したもの](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-7250c712-d4ce-11e8-a6c5-42010a92003f   2Gi        RWO            standard       16s
~~~

永続ボリュームをマウントするポッドを起動して、マウントを確認します。 ポッドのシェルから df -h の結果で、永続ボリュームが確認できます。

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

$ kubectl get po
NAME                        READY     STATUS    RESTARTS   AGE
pod1                        1/1       Running   0          1m

$ kubectl exec -it pod1 -- bash
root@pod1:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          95G  2.7G   92G   3% /
tmpfs           851M     0  851M   0% /dev
tmpfs           851M     0  851M   0% /sys/fs/cgroup
/dev/sdb        2.0G  6.0M  1.8G   1% /mnt             <--- 永続ボリューム
/dev/sda1        95G  2.7G   92G   3% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           851M   12K  851M   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs           851M     0  851M   0% /sys/firmware
root@pod1:/# ls -al /mnt
total 24
drwxr-xr-x 3 root root  4096 Oct 21 01:14 .
drwxr-xr-x 1 root root  4096 Oct 21 01:14 ..
drwx------ 2 root root 16384 Oct 21 01:14 lost+found
~~~

---


# クリーンナップ

ゴミバケツのアイコンをクリックして、確認画面で「削除」をクリックして、クラスタを削除できます。この際に、永続ボリュームは、ディスクとして残ってしました。

![スクリーンショット 2018-10-21 10.18.52.png](https://qiita-image-store.s3.amazonaws.com/0/42829/08bcef44-2f3d-e1b7-f30a-a1d2e5edbd90.png "スクリーンショット 2018-10-21 10.18.52.png")


# 感想

k8sクラスタを作成するだけで、ノードも一緒に作成してくれ、簡単で良いですね。


## 参考資料
https://cloud.google.com/kubernetes-engine/docs/quickstart