目次
- 前回のおさらい
- ヘルスチェック機能とは
- ヘルスチェックの種類
- ハンドラー
- 実践
- 用語について
- あとがき
前回のおさらい
前回のkubernetesを学ぶ~その4~は、マニフェストとコントローラについて記載してみた。YAML形式は癖があるなーってのと、コントローラの種類について理解できたと思う。トラブルシューティングも少し経験したので良かったと思う。
ヘルスチェック機能とは
ポッドのコンテナには、アプリケーションのヘルスチェック(死活監視)を行い、異常を検知したらコンテナを強制終了からの起動をする機能があります。
K8sでは、ノードに常駐するkubeletがヘルスチェックを実施します。
イメージは、↓こんな感じです。
※200 OK は、リクエストが成功した場合に返すレスポンスコード。
500は、サーバーがリクエストを実行を妨げる予期しない条件に遭遇したことを示すサーバエラーレスポンスコード。
ヘルスチェックの種類
kubeletのヘルスチェックは2種類のプローブを使用してチェックします。
活性プローブ(Liveness Probe)
コンテナが実行中であることを探査します。例えば、アプリが応答なしになったとか。
応答がないとコンテナを強制終了して起動します。
マニフェストにLiveness Probeの記述がないと、チェックしません。
準備状態プローブ(Readiness Probe)
コンテナのアプリケーションがリクエストを受け付けられるか探査します。例えば、初期のロード処理で重くなってリクエスト返せないとか。応答がない場合は、リクエストが転送しません。
マニフェストにReadiness Probeの記述がないと、チェックされないのでリクエストを転送し続けます。
ハンドラー
従来だとロードバランサーでヘルスチェックを行う場合、HTTPで生きてるかどうかチェックしていましたが、同じようにポッドのコンテナはプローブに対応するハンドラーを実装する必要があります。
ハンドラーには、種類が3つあります。
- exec
- tcpSocket
- httpGet
exec
コンテナ内のコマンドを実行します。EXITコード0で診断成功となります。
livenessProbe:
exec:
command:
- cat:
- /tmp/healthy
initialDelaySeconds: 3 #初回起動から探査開始までの猶予時間(秒)
periodSeconds: 5 #チェック間隔(秒)
timeoutSeconds: 2 #タイムアウトを指定(秒)デフォは1秒
successThreshold: 2 #Probeが成功したと判断する最小回数を指定 デフォは1回
failureThreshold: 5 #Probeが失敗したと判断する最小回数を指定 デフォは3回
tcpSocket
指定したTCPポート番号でコネクションを張ることができれば診断成功となります。
readinessProbe:
tcpSocket:
port: 80
httpGet
指定したパスとポート番号にHTTP GETが定期的に実行し、HTTPステータスコードが200~400未満であれば診断成功となります。
readinessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 3 #初回起動から探査開始までの猶予時間(秒)
periodSeconds: 5 #チェック間隔(秒)
timeoutSeconds: 2 #タイムアウトを指定(秒)デフォは1秒
successThreshold: 2 #Probeが成功したと判断する最小回数を指定 デフォは1回
failureThreshold: 5 #Probeが失敗したと判断する最小回数を指定 デフォは3回
注意点
あくまでもポッドを実行しているノード上にあるkubeletから実施されているので、対象はポッド上のコンテナなので、ノードがハード障害で停止するといった場合は、kubeletごと停止するのでノード障害対応の方法ではないことです。どこで何が機能しているか把握していないと「あーノード障害は、kubeletがあるから大丈夫ですよ。」なんで、とんでも勘違いをしてしまいます。※私に言っていますw
実践
実践の流れは、LivenessProbeとreadienessProbeの挙動確認。
- マニフェスト作成・適用
- indexファイルを削除してエラー発生
マニフェスト作成・適用(LivenessProbe)
apiVersion: v1
kind: Pod
metadata:
name: liveness-check
spec:
containers:
- image: nginx
name: nginx
livenessProbe:
httpGet:
port: 80
path: /
failureThreshold: 3
periodSeconds: 3
実行
D:\Repository\kubernetes\vagrant-kubernetes>kubectl apply -f ./LivenessProbe_test.yml
pod/liveness-check created
確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get po
NAME READY STATUS RESTARTS AGE
liveness-check 1/1 Running 0 71s
詳細確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl describe po liveness-check
Name: liveness-check
Namespace: default
Priority: 0
Node: node2/172.16.20.13
Start Time: Mon, 08 Feb 2021 12:55:53 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.2.27
IPs: <none>
Containers:
nginx:
Container ID: docker://fbecc20c37432146df765f26d7aa6c0428483ad7ec4c708d51c1027ef477f650
Image: nginx
Image ID: docker-pullable://nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 08 Feb 2021 12:55:58 +0900
Ready: True
Restart Count: 0
Liveness: http-get http://:80/ delay=0s timeout=1s period=3s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-4vlhd (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-4vlhd:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4vlhd
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m25s default-scheduler Successfully assigned default/liveness-check to node2
Normal Pulling 2m23s kubelet Pulling image "nginx"
Normal Pulled 2m19s kubelet Successfully pulled image "nginx"
Normal Created 2m19s kubelet Created container nginx
Normal Started 2m19s kubelet Started container nginx
確認箇所は、
Liveness: http-get http://:80/ delay=0s timeout=1s period=3s #success=1 #failure=3
indexファイルを削除してエラー発生
削除
D:\Repository\kubernetes\vagrant-kubernetes>kubectl exec liveness-check -- rm /usr/share/nginx/html/index.html
詳細確認
D:\Repository\kubernetes\vagrant-kubernetes> kubectl describe po liveness-check
Name: liveness-check
Namespace: default
Priority: 0
Node: node2/172.16.20.13
Start Time: Mon, 08 Feb 2021 12:55:53 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.2.27
IPs: <none>
Containers:
nginx:
Container ID: docker://d8de55c8ab78df6978f135551c8871aef517d42ea4b8f0e7c9015553e260e997
Image: nginx
Image ID: docker-pullable://nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 08 Feb 2021 13:02:28 +0900
Last State: Terminated
Reason: Completed
Exit Code: 0
Started: Mon, 08 Feb 2021 12:55:58 +0900
Finished: Mon, 08 Feb 2021 13:02:24 +0900
Ready: True
Restart Count: 1
Liveness: http-get http://:80/ delay=0s timeout=1s period=3s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-4vlhd (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-4vlhd:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4vlhd
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6m46s default-scheduler Successfully assigned default/liveness-check to node2
Normal Pulling 14s (x2 over 6m44s) kubelet Pulling image "nginx"
Warning Unhealthy 14s (x3 over 20s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 403
Normal Killing 14s kubelet Container nginx failed liveness probe, will be restarted
Normal Pulled 10s (x2 over 6m40s) kubelet Successfully pulled image "nginx"
Normal Created 10s (x2 over 6m40s) kubelet Created container nginx
Normal Started 10s (x2 over 6m40s) kubelet Started container nginx
ちゃんと検知と再作成を行っていますね。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6m46s default-scheduler Successfully assigned default/liveness-check to node2
Normal Pulling 14s (x2 over 6m44s) kubelet Pulling image "nginx"
Warning Unhealthy 14s (x3 over 20s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 403
Normal Killing 14s kubelet Container nginx failed liveness probe, will be restarted
Normal Pulled 10s (x2 over 6m40s) kubelet Successfully pulled image "nginx"
Normal Created 10s (x2 over 6m40s) kubelet Created container nginx
Normal Started 10s (x2 over 6m40s) kubelet Started container nginx
次は、readinessProbeです。
マニフェスト作成・適用(ReadinessProbe)
apiVersion: v1
kind: Pod
metadata:
name: readiness-check
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
readinessProbe:
httpGet:
port: 80
path: /
failureThreshold: 1
periodSeconds: 1
apiVersion: v1
kind: Service
metadata:
name: readiness-check-svc
spec:
selector:
app: nginx
ports:
- port: 80
ポッド作成
D:\Repository\kubernetes\vagrant-kubernetes>kubectl apply -f ./ReadinessProbe_test.yml
pod/readiness-check created
サービス作成
D:\Repository\kubernetes\vagrant-kubernetes>kubectl apply -f ./ReadinessProbe_svc_test.yml
service/readiness-check-svc created
確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get po
NAME READY STATUS RESTARTS AGE
readiness-check 1/1 Running 0 3m40s
詳細
D:\Repository\kubernetes\vagrant-kubernetes>kubectl describe po readiness-check
Name: readiness-check
Namespace: default
Priority: 0
Node: node2/172.16.20.13
Start Time: Mon, 08 Feb 2021 13:11:08 +0900
Labels: app=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.28
IPs: <none>
Containers:
nginx:
Container ID: docker://e780be7f11f1b628971ab205236fb73a9227e21b9812079898d446b05b0d8fe5
Image: nginx
Image ID: docker-pullable://nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 08 Feb 2021 13:11:13 +0900
Ready: True
Restart Count: 0
Readiness: http-get http://:80/ delay=0s timeout=1s period=1s #success=1 #failure=1
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-4vlhd (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-4vlhd:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4vlhd
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m55s default-scheduler Successfully assigned default/readiness-check to node2
Normal Pulling 3m54s kubelet Pulling image "nginx"
Normal Pulled 3m50s kubelet Successfully pulled image "nginx"
Normal Created 3m50s kubelet Created container nginx
Normal Started 3m50s kubelet Started container nginx
サービス確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 6d17h
readiness-check-svc ClusterIP 10.32.0.6 <none> 80/TCP 4m30s
詳細
D:\Repository\kubernetes\vagrant-kubernetes>kubectl describe svc readiness-check-svc
Name: readiness-check-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Families: <none>
IP: 10.32.0.6
IPs: <none>
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.28:80
Session Affinity: None
Events: <none>
別ノードからアクセス
D:\Repository\kubernetes\vagrant-kubernetes>vagrant ssh node1
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-135-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Mon Feb 8 04:41:02 UTC 2021
System load: 0.06 IP address for enp0s3: 10.0.2.15
Usage of /: 6.3% of 38.71GB IP address for enp0s8: 172.16.20.12
Memory usage: 27% IP address for enp0s9: 192.168.11.41
Swap usage: 0% IP address for docker0: 172.17.0.1
Processes: 105 IP address for cni0: 10.244.1.1
Users logged in: 0
* Introducing self-healing high availability clusters in MicroK8s.
Simple, hardened, Kubernetes for production, from RaspberryPi to DC.
https://microk8s.io/high-availability
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
7 packages can be updated.
0 of these updates are security updates.
To see these additional updates run: apt list --upgradable
New release '20.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Last login: Mon Feb 8 04:36:38 2021 from 10.0.2.2
vagrant@node1:~$ wget -O - -T 1 10.32.0.6
--2021-02-08 04:41:06-- http://10.32.0.6/
Connecting to 10.32.0.6:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 612 [text/html]
Saving to: ‘STDOUT’
- 0%[ ] 0 --.-KB/s <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100%[=================================================>] 612 --.-KB/s in 0s
2021-02-08 04:41:06 (113 MB/s) - written to stdout [612/612]
vagrant@node1:~$
indexファイルを削除してエラー発生
コピー
D:\Repository\kubernetes\vagrant-kubernetes>kubectl exec readiness-check -- cp -r /usr/share/nginx/html/index.html /usr/share/nginx/html/index_bk.html
削除
D:\Repository\kubernetes\vagrant-kubernetes>kubectl exec readiness-check -- rm /usr/share/nginx/html/index.html
確認
D:\Repository\kubernetes\vagrant-kubernetes>kubectl describe po readiness-check
Name: readiness-check
Namespace: default
Priority: 0
Node: node2/172.16.20.13
Start Time: Mon, 08 Feb 2021 13:40:51 +0900
Labels: app=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.29
IPs: <none>
Containers:
nginx:
Container ID: docker://6162644eb97f23bfed4e6341e8d7752c736e9f21f214a0af86f24532c627533f
Image: nginx
Image ID: docker-pullable://nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 08 Feb 2021 13:40:56 +0900
Ready: False
Restart Count: 0
Readiness: http-get http://:80/ delay=0s timeout=1s period=1s #success=1 #failure=1
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-4vlhd (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-4vlhd:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4vlhd
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m3s default-scheduler Successfully assigned default/readiness-check to node2
Normal Pulling 4m2s kubelet Pulling image "nginx"
Normal Pulled 3m58s kubelet Successfully pulled image "nginx"
Normal Created 3m58s kubelet Created container nginx
Normal Started 3m58s kubelet Started container nginx
Warning Unhealthy 1s (x18 over 18s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 403
接続確認
vagrant@node1:~$ wget -O - -T 1 10.32.0.6
--2021-02-08 04:47:14-- http://10.32.0.6/
Connecting to 10.32.0.6:80... failed: Connection timed out.
Retrying.
死んでいるので接続できませんね。
D:\Repository\kubernetes\vagrant-kubernetes>kubectl exec readiness-check -- cp -r /usr/share/nginx/html/index_bk.html /usr/share/nginx/html/index.html
他のノードから接続してみる。
vagrant@node1:~$ wget -O - -T 1 10.32.0.6
--2021-02-08 04:58:16-- http://10.32.0.6/
Connecting to 10.32.0.6:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 612 [text/html]
Saving to: ‘STDOUT’
- 0%[ ] 0 --.-KB/s <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100%[=================================================>] 612 --.-KB/s in 0s
2021-02-08 04:58:16 (51.6 MB/s) - written to stdout [612/612]
vagrant@node1:~$
今回は、動作確認のために繋がらないことで確認した。本番運用で繋がらないことで動作確認するのはダメと思っています。ステータスなどで確認かと思う。だって、システム動いていますから。
用語について
・プローブ
探査のこと。
あとがき
運用でよく理解しておく必要があるヘルスチェックについて学んだ。EXTERNAL-IPが設定されていないのでノードに接続してアクセス確認をしたりと、まだ環境を確認するのに面倒だなー思っています。
次回は、デプロイメントについてもう少し詳しくやろうかな。