kubernetesで障害時や調査の時に使うコマンドたちのたそがれ

今回はkubernetes使用時に色々調査するためのコマンドについてみて行きたいと..
おもおもおもおもおも思います！（スマイリー風）

###1. nodeを確認
まずは切り分けとして、Podの前にnodeを確認していきまうす
Podは物理的なnodeの上で動作しているものなので、Podが正常でも
nodeがお亡くなりになっていた場合、もちろんPodも影響を受けます。
`-o wide`をつけることで付加情報が得られます。普段は必要ないかもですが、調査の時なんかはあってもいいかも。

```
$ kubectl get node -o wide
NAME                                STATUS   ROLES   AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-nodepool1-xxxxxxxx-vmss000001   Ready    agent   63d   v1.15.5   xxx.xx.xxx.xx   <none>        Ubuntu 16.04.6 LTS   4.15.0-1069-azure   docker://3.0.8
aks-nodepool1-xxxxxxxx-vmss000004   NotReady agent   44d   v1.15.5   xxx.xx.xxx.x    <none>        Ubuntu 16.04.6 LTS   4.15.0-1069-azure   docker://3.0.8
aks-nodepool1-xxxxxxxx-vmss000013   Ready    agent   30d   v1.15.5   xxx.xx.xxx.xx   <none>        Ubuntu 16.04.6 LTS   4.15.0-1069-azure   docker://3.0.8
```

ここで重要なのは`STATUS`の項目です。正常時は`Ready`が出力されます。
`Not Ready`が出力されている場合は、単純にnodeが新しく生成されて
まだ準備ができていないか、node単位で障害が起こってる可能性があります。

`vmss000004`が`NotReady`になっているため、`describe`コマンドで詳細を確認します。

```
$ kubectl describe node aks-nodepool1-xxxxxxxx-vmss000004
~①
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Thu, 14 May 2020 16:34:01 +0900   Thu, 12 Mar 2020 02:01:38 +0900   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Thu, 14 May 2020 16:34:01 +0900   Thu, 12 Mar 2020 02:01:38 +0900   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Thu, 14 May 2020 16:34:01 +0900   Thu, 12 Mar 2020 02:01:38 +0900   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Thu, 14 May 2020 16:34:01 +0900   Thu, 12 Mar 2020 02:01:38 +0900   KubeletReady                 kubelet is posting ready status. AppArmor enabled
~②
Non-terminated Pods:          (28 in total)
  Namespace                   Name                                              CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                   ----                                              ------------  ----------  ---------------  -------------  ---
  dev                         tomato-b69d9485b-hwp2v                            100m (2%)     0 (0%)      0 (0%)           0 (0%)         50d
  dev                         tomato2-7d95f9bb8b-tdrzt                          100m (2%)     0 (0%)      0 (0%)           0 (0%)         63d
~③
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource                       Requests     Limits
  --------                       --------     ------
  cpu                            1940m (50%)  1100m (28%)
  memory                         794Mi (7%)   1450Mi (13%)
  ephemeral-storage              0 (0%)       0 (0%)
  attachable-volumes-azure-disk  0            0
~④
Events:                          <none>
```

情報が多いので端折っていますが、優先で確認した方が良いかなと思う項目を4つほどあげてみました。
（上記例は正常時のものしか取れなかったため平和な感じになってしまっています..）
① Conditions
`Ready` Podを配置できる状態にあればTrue
`MemoryPressure` ノードのメモリの空き容量が少ない時にTrue
などなど、nodeのコンディションについて出力されます。
詳しくは下記のドキュメント参照
https://kubernetes.io/ja/docs/concepts/architecture/nodes/#condition

② Non-terminated Pods
namespaceごとに該当のnodeにデプロイされているPodを表示します。
もし障害nodeをdescribeしている場合、ここに表示されているPodがnode障害の影響を受ける恐れがあります。
もしそのPodが、他の正常稼働しているnodeに分散されておらず単一障害点になっている場合は
そこを起因としてシステム障害が起こっている可能性があるので、重点的な調査が必要になります。

③ Allocated resources
nodeに対して割り当てられているリソースがどれくらいかを表示しています。
CPUやmemoryなどのRequestsが増えすぎていないことは確認しておいた方が良いかと。

④ Events
エラーなどのイベントがあればこちらに表示されます。


### 2.Podを確認
続きましてPodが元気かをお問い合わせしてみましょう。

こちらも`-o wide`をつけることで~~どうでも良い~~付加情報を得られます。
しかしそんな情報から解決の糸口を得られることもあるので、調査時にはばかにできません。

```
$ kubectl get po -o wide
NAME                                     READY   STATUS    RESTARTS   AGE    IP               NODE                                NOMINATED NODE   READINESS GATES
tomato-b69d9485b-hwp2v                   1/1     Running   0          50d    xxx.xx.xxx.xx    aks-nodepool1-xxxxxxxx-vmss000001   <none>           <none>
tomato2-7d95f9bb8b-tdrzt                 1/1     Running   0          63d    xxx.xx.xxx.xx    aks-nodepool1-xxxxxxxx-vmss000001   <none>           <none>
```

ここでもっとも重要なのは`STATUS`と`READY`の項目です。
正常時は上記のように`1/1 Running`のように表示されます。
`0/1 Running`のようになっている場合は、単純にまだコンテナが立ち上がりきっていないか
ReadinessでのHealthcheckが失敗している可能性が高いと思います。

### 2-1.よくある起動失敗時のSTATUS

#### 2-1-1.CrashLoopBackOff
コンテナが再起動を待っている状態ですが、多くの場合コンテナ内で
エラーが発生していることが多いように思われます。
下記のコマンドでコンテナ内でエラーが発生していないか確認できます。

`kubectl get event | grep [deployment名]`
もしくは
`kubectl logs [Pod名]`


#### 2-1-2.ImagePullBackOff
コンテナimageをPullする時に失敗しています。
よくあるのは権限がない、認証系のエラーとか、単純なタイポとかですかね。
こちらについても下記のコマンドで確認できます。
`kubectl get event | grep [deployment名]`


#### 2-1-3.Terminating
文字通りコンテナが終了している状態です。多くの場合は静観すればPodが終了し、新しいPodが立ち上がるなどの処理が自動で行われます。

ただし、node障害などの場合はPodがTerminatingのまま終了も再起動もしないという状態があり得ます。
その場合、下記のコマンドでPodを強制的に終了させることで、他の正常なnodeでの再起動を促すという方法が取れることがあります。
ただし、プロセスの強制終了などに値するので、ご利用は慎重に..
`kubectl delete pod [Pod名]`

その他のSTATUSについては下記の公式docをご覧いただければ。
https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-lifecycle/#pod%E3%81%AEphase

つまるところ、Podの調査については下記のコマンドを打っておけば、だいたいの理由はわかるかと。えへへ。
`kubectl get event | grep [deployment名]`
もしくは
`kubectl logs [Pod名]`

疲れたので今日はここまで。
ではまた🙋‍♂️

## さいごに
ZEROBILLBANKでは一緒に働く仲間を募集中です。
なんとかjsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。

[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com)