ReplicaSetの動作を確認する

#はじめに
Podの性能や可用性を高めるために、Kubernetesは基本的に「スケールアウト」させます。スケールアウトはノード（ここではPod/コンテナ）のCPU/メモリを増やすのではなく、ノード（Pod/コンテナ）を増やします。
ちなみに、CPUやメモリを増やすのは「スケールアップ」。
このスケールアウトの仕組みとしてReplicaSetがあるので、今回はこの動作を確認してみます。

#ReplicaSetの作成
以下のyamlファイルを作成しました。

```sampleReplicaSet.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-pod3
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-redis
  template:
    metadata:
      labels:
        app: nginx-redis
    spec:
      containers:
        - name: nginx
          image: nginx:latest
        - name: redis
          image: redis:latest
```
デプロイします。

```
$ kubectl apply -f sampleReplicaSet.yaml
replicaset.apps/sample-pod3 created
```
ここでは、一発でデプロイできてることになってますが、実際にはyamlファイルのミスで何度かエラーが出てます。
・スペルミス
・インデントがずれてる
yamlの書式にも慣れていかないと。

##確認

```
$ kubectl get rs
NAME          DESIRED   CURRENT   READY   AGE
sample-pod3   3         3         3       16m
$ kubectl get replicasets.apps -o wide
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS    IMAGES                      SELECTOR
sample-pod3   3         3         3       16m   nginx,redis   nginx:latest,redis:latest   app=nginx-redis
$ kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-7nxxr   2/2     Running   0          18m   192.168.69.216   k8s-worker02   <none>           <none>
sample-pod3-86kqh   2/2     Running   0          18m   192.168.79.74    k8s-worker01   <none>           <none>
sample-pod3-thbbx   2/2     Running   0          18m   192.168.69.202   k8s-worker02   <none>           <none>
```

sample-pod3のレプリカが3つ作成されていることが確認できます。
Pod名は「[metadata.name]-[ランダムな英数字]」になっています。
ちなみに、レプリカセットを確認するサブコマンドの「rs」と「replicasets.apps」は同じ意味です。

Podがデプロイされているworkerノードも分散されていますね。
図で書くとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/702d0357-f25c-d3be-5c84-72771dad7c05.png)

#セルフヒーリング機能の確認
Kubernetesの特徴としてセルフヒーリング機能があります。これは、何かしら障害が発生した場合にもあらかじめ設定してある「あるべき姿」に戻す機能です。
この場合の「あるべき姿」はsample-pod3のレプリカが3つであることです。

##workerノードの停止
ここではworker01を停止します。shutdownするだけなので、割愛。
状態を確認します。worker01がNotReadyになっています。

```
$ kubectl get node
NAME           STATUS     ROLES    AGE   VERSION
k8s-master     Ready      master   11d   v1.17.3
k8s-worker01   NotReady   <none>   11d   v1.17.3
k8s-worker02   Ready      <none>   11d   v1.17.3
```

##ReplicaSetの確認
停止して少し待ってから状態を確認します。

```
$ kubectl get pod -o wide
NAME                READY   STATUS        RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
sample-pod3-7nxxr   2/2     Running       0          66m   192.168.69.216   k8s-worker02   <none>           <none>
sample-pod3-86kqh   2/2     Terminating   0          66m   192.168.79.74    k8s-worker01   <none>           <none>
sample-pod3-ngw8x   2/2     Running       0          20m   192.168.69.217   k8s-worker02   <none>           <none>
sample-pod3-thbbx   2/2     Running       0          66m   192.168.69.202   k8s-worker02   <none>           <none>
$ kubectl get rs
NAME          DESIRED   CURRENT   READY   AGE
sample-pod3   3         3         3       70m
```

worker01にあった「sample-pod3-86kqh」が「Terminating」状態になって、__新たに__「sample-pod3-ngw8x」がworker02にデプロイされています。
新しく作成されているところがポイントで、Active-Standbyのようなデータを引き継いだフェイルオーバーではなく、新しいPodがデプロイされています。つまり、いままでworker01で処理されていたデータは引き継がれていません。
Kubernetesで実現するマイクロサービスは、このようにデータを保持しない「ステートレス」なアプリを基本とします。
そのために、保持しなければいけないデータやログなんかは別のボリュームに保存したりするので、この辺りはまた調べたいと思います。

なお、Podのデプロイ履歴は以下で確認できます。

```
$ kubectl describe rs sample-pod3
Name:         sample-pod3
・・・
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  49m    replicaset-controller  Created pod: sample-pod3-thbbx
  Normal  SuccessfulCreate  49m    replicaset-controller  Created pod: sample-pod3-86kqh
  Normal  SuccessfulCreate  49m    replicaset-controller  Created pod: sample-pod3-7nxxr
  Normal  SuccessfulCreate  3m30s  replicaset-controller  Created pod: sample-pod3-ngw8x
```

このTerminatingになっているPodは、deleteで消せばいいらしいです。
[Kubernetes.io](https://kubernetes.io/ja/docs/concepts/workloads/pods/pod/#pod%e3%81%ae%e7%b5%82%e4%ba%86)

```
$ kubectl delete pod sample-pod3-86kqh
pod "sample-pod3-86kqh" deleted
```

なんとなく、使えなくなったPodのdeleteまでやってくれればいい気がしますが、何か理由でもあるのかな？
これで一通りReplicaSetの動作の確認ができました。ReplicaSetはKubernetesを使っていくうえで重要な要素だと思いますので、もう少し調べてみたいと思います。