GCPでやってみる - クラスタの操作に慣れる


# 今日の教科書

阿佐 志保,真壁 徹. しくみがわかるKubernetes Azureで動かしながら学ぶコンセプトと実践知識 (Japanese Edition) (Kindle Location 1634). Kindle Edition. 

この本はAzureを想定して書かれてるんですが、GCPでやってみようと思います。

# 事前設定

- `gcloud` のコマンドラインがインストールされている
- GCPのプロジェクトが作られている
- `kubectl` の自動補完なども必要に応じてやっておくとよい

# 1. 練習用の GitHub レポジトリ

以下を使わせていただこうかと思います。

```
git clone https://github.com/ToruMakabe/Understanding-K8s
```

# 2. デプロイするコンテナイメージをつくる

GCPでのコンテナイメージの作成は、[Cloud Build](https://cloud.google.com/cloud-build/docs/quickstart-docker?hl=ja) で。先のGitレポジトリの `Understanding-K8s/chap02/v1.0` にて

```
$ gcloud builds submit --tag gcr.io/$PROJECT_ID/photo-view:v1.0 .
```

以下で見ると `photo-view` ができている

```
$ gcloud container images list
```

`Understanding-K8s/chap02/v2.0` でも同じようにビルドする

```
$ gcloud container images list-tags gcr.io/$PROJECT_ID/photo-view
DIGEST        TAGS  TIMESTAMP
d53baa7e2494  v2.0  2020-02-06T12:35:19
3dedf7c9c4de  v1.0  2020-02-06T12:23:04
```

Web Console の `Container Registry` でも確認できる 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/411b476d-e0d7-9460-b7ec-2e69dfbcf007.png)

# 3. クラスタを作る

```
$ gcloud container clusters create photo-view-cluster --num-nodes=3
``` 

... 数分かかる

・クラスタの情報は `~/.kube/config ` に持っている
・クラスタ複数ある場合には、`gcloud container clusters get-credentials <cluster-name>` で認証情報を選択すれば良いと思われる

クラスタの情報

```
$ kubectl cluster-info 
Kubernetes master is running at https://35.230.85.107
GLBCDefaultBackend is running at https://35.230.85.107/api/v1/namespaces/kube-system/services/default-http-backend:http/proxy
Heapster is running at https://35.230.85.107/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://35.230.85.107/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://35.230.85.107/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
```
```
$ kubectl get nodes
NAME                                                STATUS   ROLES    AGE   VERSION
gke-photo-view-cluster-default-pool-e402dd14-986t   Ready    <none>   54m   v1.14.10-gke.17
gke-photo-view-cluster-default-pool-e402dd14-r0ww   Ready    <none>   54m   v1.14.10-gke.17
gke-photo-view-cluster-default-pool-e402dd14-zbw9   Ready    <none>   54m   v1.14.10-gke.17
```

# 4. リソース

サービスもデプロイもレプリカセットも Kubernetes の世界では全部リソースのうち

## デプロイメント

`Understanding-K8s/chap03` にあるファイルをつかってデプロイ

- `tutorial-deployment.yaml` の `image:` のところを `gcr.io/${PROJECT_ID}/photo-view:v1.0` にする
- `tutorial-service.yaml` はそのままで

```
$ kubectl apply -f tutorial-deployment-gke.yaml 
deployment.apps/photoview-deployment created
```
```
$ kubectl get deployment.app
NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
photoview-deployment   5/5     5            5           9m16s
```

## サービス

外からアクセスできるようにする

```
$ kubectl apply -f tutorial-service.yaml
service/webserver created
```
```
$ kubectl get services
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE
kubernetes   ClusterIP      10.23.240.1   <none>           443/TCP        97m
webserver    LoadBalancer   10.23.245.5   35.233.170.121   80:31342/TCP   7m26s
```

Podにアクセス

`EXTERNAL-IP` にアクセス。ブラウザをリロードして画像や `Pod` が変わる（LBが動いている）ことがわかる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/97a7d61c-010d-d804-872d-7535040d5cc5.png)

## レプリカセット

レプリカセットをつくる

`Understanding-K8s/chap04/webserver.yaml` を `apply` すると `nginx` の `pod` が 10個、動き出す

```
$ kubectl apply -f webserver.yaml 
replicaset.apps/webserver created
```
```
$ kubectl get pods -o wide
NAME                                    READY   STATUS    RESTARTS   AGE   IP           NODE                                                NOMINATED NODE   READINESS GATES
photoview-deployment-754d77b768-2n2q9   1/1     Running   0          21h   10.20.1.4    gke-photo-view-cluster-default-pool-e402dd14-zbw9   <none>           <none>
photoview-deployment-754d77b768-5gmwj   1/1     Running   0          21h   10.20.2.5    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
photoview-deployment-754d77b768-8r47b   1/1     Running   0          21h   10.20.2.3    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
photoview-deployment-754d77b768-c94sw   1/1     Running   0          21h   10.20.0.10   gke-photo-view-cluster-default-pool-e402dd14-986t   <none>           <none>
photoview-deployment-754d77b768-nts6q   1/1     Running   0          21h   10.20.2.4    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
webserver-5gpb5                         1/1     Running   0          14s   10.20.2.7    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
webserver-5vt7b                         1/1     Running   0          14s   10.20.2.6    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
webserver-8kgln                         1/1     Running   0          14s   10.20.0.13   gke-photo-view-cluster-default-pool-e402dd14-986t   <none>           <none>
webserver-b7bw6                         1/1     Running   0          14s   10.20.1.6    gke-photo-view-cluster-default-pool-e402dd14-zbw9   <none>           <none>
webserver-c95zn                         1/1     Running   0          14s   10.20.0.11   gke-photo-view-cluster-default-pool-e402dd14-986t   <none>           <none>
webserver-cjjlx                         1/1     Running   0          14s   10.20.0.12   gke-photo-view-cluster-default-pool-e402dd14-986t   <none>           <none>
webserver-mthj7                         1/1     Running   0          14s   10.20.1.5    gke-photo-view-cluster-default-pool-e402dd14-zbw9   <none>           <none>
webserver-rqkhk                         1/1     Running   0          14s   10.20.2.8    gke-photo-view-cluster-default-pool-e402dd14-r0ww   <none>           <none>
webserver-w9n7h                         0/1     Pending   0          14s   <none>       <none>                                              <none>           <none>
webserver-xhlm8                         1/1     Running   0          14s   10.20.1.7    gke-photo-view-cluster-default-pool-e402dd14-zbw9   <none>           <none>
```
```
$ kubectl get replicasets.apps 
NAME                              DESIRED   CURRENT   READY   AGE
photoview-deployment-754d77b768   5         5         5       21h
webserver                         10        10        9       11m
```
```
$ kubectl describe replicasets.apps webserver
Name:         webserver
Namespace:    default
Selector:     app=webfront
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"name":"webserver","namespace":"default"},"spec":{"replicas":10,"...
Replicas:     10 current / 10 desired
Pods Status:  9 Running / 1 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=webfront
  Containers:
   webfront-container:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-mthj7
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-5vt7b
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-c95zn
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-xhlm8
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-5gpb5
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-8kgln
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-b7bw6
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-cjjlx
  Normal  SuccessfulCreate  12m   replicaset-controller  Created pod: webserver-rqkhk
  Normal  SuccessfulCreate  12m   replicaset-controller  (combined from similar events): Created pod: webserver-w9n7h
```

## デプロイメント vs. レプリカセット

`ReplicaSet` でやってることって `Deployment` でもできるのではないか？どう使い分けするのがいいのか？ → [ReplicaSet](https://kubernetes.io/ja/docs/concepts/workloads/controllers/replicaset/) に書かれている

>ReplicaSetはどんな時でも指定された数のPodのレプリカが稼働することを保証します。しかし、DeploymentはReplicaSetを管理する、より上位レベルの概念で、Deploymentはその他の多くの有益な機能と共に、宣言的なPodのアップデート機能を提供します。それゆえ、我々はユーザーが独自のアップデートオーケストレーションを必要としたり、アップデートを全く必要としないような場合を除いて、ReplicaSetを直接使うよりも代わりにDeploymentを使うことを推奨します。

>これは、ユーザーがReplicaSetのオブジェクトを操作する必要が全く無いことを意味します。 代わりにDeploymentを使用して、specセクションにユーザーのアプリケーションを定義してください。

おかたずけ

```
$ kubectl delete -f webserver.yaml 
replicaset.apps "webserver" deleted
```

## ラベル

ラベルの使い方いろいろ。[前にやった](https://qiita.com/narutaro/items/cbf8bc62a3f25d673b7f#%E3%83%A9%E3%83%99%E3%83%AB%E3%81%A8%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)のでスキップする

## ネームスペース

>Kubernetesにはリソースをまとめて仮想的に分離するNamespaceという機能があります。これを使うと1つのKubernetesクラスターを複数プロジェクトで利用することができます。複数のリソースをまとめて入れるフォルダのようなものと理解するとよいでしょう。

>阿佐 志保,真壁 徹. しくみがわかるKubernetes Azureで動かしながら学ぶコンセプトと実践知識 (Japanese Edition) (Kindle Location 1634). Kindle Edition. 

```
$ kubectl get namespace
NAME              STATUS   AGE
default           Active   23h
kube-node-lease   Active   23h
kube-public       Active   23h
kube-system       Active   23h
```

あるネームスペース `kube-system` の pod を表示

```
$ kubectl get pod --namespace kube-system 
NAME                                                           READY   STATUS    RESTARTS   AGE
event-exporter-v0.2.5-7df89f4b8f-h9znq                         2/2     Running   0          23h
fluentd-gcp-scaler-54ccb89d5-2vk9z                             1/1     Running   0          23h
fluentd-gcp-v3.1.1-5285m                                       2/2     Running   0          23h
fluentd-gcp-v3.1.1-pj86r                                       2/2     Running   0          23h
fluentd-gcp-v3.1.1-qqt4r                                       2/2     Running   0          23h
heapster-gke-57d9dc7fc8-jjlwp                                  3/3     Running   0          23h
kube-dns-5877696fb4-dfspd                                      4/4     Running   0          23h
kube-dns-5877696fb4-n2z8v                                      4/4     Running   0          23h
kube-dns-autoscaler-8687c64fc-xrt5j                            1/1     Running   0          23h
kube-proxy-gke-photo-view-cluster-default-pool-e402dd14-986t   1/1     Running   0          23h
kube-proxy-gke-photo-view-cluster-default-pool-e402dd14-r0ww   1/1     Running   0          23h
kube-proxy-gke-photo-view-cluster-default-pool-e402dd14-zbw9   1/1     Running   0          23h
l7-default-backend-8f479dd9-fpv6r                              1/1     Running   0          23h
metrics-server-v0.3.1-5c6fbf777-2dglq                          2/2     Running   0          23h
prometheus-to-sd-7ftzb                                         2/2     Running   0          23h
prometheus-to-sd-nxjgb                                         2/2     Running   0          23h
prometheus-to-sd-qxmkq                                         2/2     Running   0          23h
stackdriver-metadata-agent-cluster-level-c6dd68b8c-ddfnl       1/1     Running   0          23h
```

ネームスペースを作成する

```
$ kubectl apply -f namespace.yaml 
namespace/trade-system created
```
```
$ kubectl get namespaces 
NAME              STATUS   AGE
default           Active   24h
kube-node-lease   Active   24h
kube-public       Active   24h
kube-system       Active   24h
trade-system      Active   10s
```

>namespaceオプションで明示的に指定していないときは、「default」のNamespaceに含まれるリソースを操作していることになります。

>阿佐 志保,真壁 徹. しくみがわかるKubernetes Azureで動かしながら学ぶコンセプトと実践知識 (Japanese Edition) (Kindle Locations 1665-1666). Kindle Edition. 

```
$kubectl config set context mycontext namespace=tradesystem
```

# 基本的なコマンドのおさらい

`gcloud`

-  アカウントがいっぱいあって、誰でログインしているかわからない `gcloud auth list`
-  どのプロジェクト使ってるかわからない `gcloud projects list`
-  上記二つを一回で `gcloud config list`

`kubectl`

- クラスタの内部コンポーネント基本情報 `kubectl cluster-info`
- ノード情報 `kubectl get nodes` `-o wide`
- ノード情報詳細 `kubectl describe node <name>`
- YAMLでいろいろ操作 `kubectl apply -f <file.yaml>`