[Kubernetes]Readiness Probeの動作を確認する

#はじめに
[前回](https://qiita.com/dingtianhongjie/items/441dbb9af48e98e0d24a)はLiveness Probeの動作を確認しましたので、今回はReadiness Probeの動作を確認したいと思います。

Liveness ProbeとReadiness Probeの違い、ヘルスチェック方式、間隔は前回の内容を参照いただければと思います。

[[Kubernetes]Liveness Probeの動作を確認する](https://qiita.com/dingtianhongjie/items/441dbb9af48e98e0d24a)

#動作確認
Podが2つある場合、Readiness Probeのチェックが成功しているときは、LoadBalancerからトラフィックはバランシングされます。（以下図 左）
チェックに引っかかると、LoadBalancerからのトラフィックが流れないように制御されます。（以下図 右）
このとき、Readiness ProbeはLiveness Probeと違ってPodを再起動させません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/c4b5eea9-1685-1056-65e1-17d066fb0bad.png)

この動作を実際に確認したいと思います。

##exec
###サービス、Podのデプロイ
まずはLoadBalancerとReadiness Probeを設定していないPodをデプロイします。

```lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: load-balancer
spec:
  ports:
  - name: load-balancer
    port: 8080
    protocol: TCP
    targetPort: 80
    nodePort: 30002
  selector:
    app: app1
  type: LoadBalancer
```
```nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: app1
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
```
```
$ kubectl apply -f lb.yaml
service/load-balancer created
$ kubectl apply -f nginx.yaml
pod/nginx created
```

次にReadiness Probeを設定したPodをデプロイします。
今回は、workerノードの/testをhostPathで/checkにマウントし、配下のtestfileが存在しているかをチェック対象としています。
なお、チェック対象のtestfileは、各workerノードに事前に作成してあります。

```readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: app1
  name: nginx-readiness
spec:
  containers:
  - name: nginx-readiness
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: /check
      name: check-vol
    readinessProbe:
      exec:
        command:
        - cat
        - /check/testfile
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 1
  volumes:
  - name: check-vol
    hostPath:
      path: /test
      type: Directory
```

```
$ kubectl apply -f readiness-exec.yaml
pod/nginx-readiness created
```
外部からのアクセスを確認したいので、各コンテナのindex.htmlにホスト名を書いてどちらにバランシングされているかわかるようにします。

```
$ kubectl exec -it nginx /bin/bash
root@nginx:/# echo `hostname` > /usr/share/nginx/html/index.html
root@nginx:/# cat /usr/share/nginx/html/index.html
nginx
```

もう一つのPodも同様の手順でホスト名を記載します。

###動作確認

外部からLoadBalancerに対して5秒間隔でアクセスします。

```
[client]$ while true; do  curl -s http://10.20.30.150:8080 ;sleep 5; done
nginx-readiness
nginx
nginx-readiness
nginx
nginx-readiness
nginx
nginx-readiness
nginx
```
このときは2つのPodにバランシングされています。

Podがデプロイされているノードを確認して、testfileをworkerノードから削除してみます。

```
$ kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES
nginx             1/1     Running   0          11m     192.168.79.99    k8s-worker01   <none>           <none>
nginx-readiness   1/1     Running   0          7m35s   192.168.69.247   k8s-worker02   <none>           <none>
$ ssh k8s-worker02
[worker02]$ sudo rm /test/testfile
```

そうすると、「nginx」のみにバランシングされていることがわかります。

```
[client]$ while true; do  curl -s http://10.20.30.150:8080 ;sleep 5; done
nginx-readiness
nginx
nginx-readiness
nginx
・・・　# Readiness Probeが失敗↓
nginx
nginx
nginx
nginx
nginx
nginx
nginx
nginx
nginx
```

testfileを元に戻してみます。

```
[worker02]$ sudo touch /test/testfile
```
再び、2つのPodにバランシングされるようになります。

```
[client]$ while true; do  curl -s http://10.20.30.150:8080 ;sleep 5; done
nginx-readiness
nginx
nginx-readiness
nginx
・・・　# Readiness Probeが失敗↓
nginx
nginx
nginx
nginx
nginx
nginx
・・・　# Readiness Probeが再び成功↓
nginx-readiness
nginx
nginx-readiness
nginx
nginx-readiness
nginx
```

これらのPodの状態の変化を確認すると、以下のようになります。

```
$ kubectl get pod -w
NAME              READY   STATUS    RESTARTS   AGE
nginx             1/1     Running   0          4m56s
nginx-readiness   1/1     Running   0          36s
nginx-readiness   0/1     Running   0          7m58s #testfileを削除し、Readiness Probeが失敗する
nginx-readiness   1/1     Running   0          9m58s #testfileを復元し、Readiness Probeが成功する
```

PodはREADY状態ではなくなるだけで、再起動はしていないことがわかりますね。

##httpGet/tcpSocket
httpGetとtcpSocketについては、

* 設定方法はLiveness Probeのマニフェストの「livenessProbe」を「readinessProbe」に変更
* 動作はReadiness Probeのexecと同様

ですので、詳細は割愛します。

#まとめ
前回と今回でPodのヘルスチェック機構である「Liveness Probe」と「Readiness Probe」の動作を確認しました。どちらも設定自体はあまり難しくありませんが、要件に応じて何をどうチェックするかを設計するのが難しそうですね。

また、Liveness ProbeとReadiness Probeは、両方同時に設定することもできますので、システムの起動時と動作中のチェックを分けて考える必要がありますね。