Kubernetesのリソース確認

#はじめに
KubernetesのクラスタにPodを立てていくとリソースを消費するわけで、Pod/コンテナのリソース消費量は少ないとは言え、やはりリソースの監視は必要になります。
実運用ではPrometheusとか別ツールで監視するのが一般的だと思いますが、ここではkubectlコマンドでの確認方法をまとめます。


#kubectl topコマンド
kubectl topコマンドを使用するには、metrics-serverを構築する必要がある場合があります。
[Kubernetesのmetrics-serverを構築する](https://qiita.com/dingtianhongjie/items/a8ddc2d7f7b57291a13e)

##node
以下のコマンドでクラスタを構成する各ノードのCPU、メモリの使用量と使用率が確認できます。

```
$ kubectl top node
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-master     318m         15%    987Mi           35%
k8s-worker01   1035m        51%    1705Mi          62%
k8s-worker02   1039m        51%    1460Mi          53%
```

##Pod
以下のコマンドで各Podが使用するCPU、メモリの使用量が確認できます。
-n でnamespaceを指定しないと、defaultのnamespaceのPodのみが表示されます。

```
$ kubectl -n kube-system top pod
NAME                                      CPU(cores)   MEMORY(bytes)
calico-kube-controllers-77c4b7448-6prr9   2m           11Mi
calico-node-2hc9b                         29m          40Mi
calico-node-cgdgk                         30m          47Mi
calico-node-tkcz5                         39m          43Mi
coredns-6955765f44-55wbn                  22m          10Mi
coredns-6955765f44-bhdvr                  25m          10Mi
etcd-k8s-master                           24m          52Mi
kube-apiserver-k8s-master                 48m          343Mi
kube-controller-manager-k8s-master        18m          46Mi
kube-proxy-8pngh                          1m           16Mi
kube-proxy-gqt42                          2m           17Mi
kube-proxy-pq2fb                          1m           14Mi
kube-scheduler-k8s-master                 5m           16Mi
metrics-server-fbc46dc5f-9k6kt            1m           10Mi
```

Podには複数のコンテナがデプロイされる場合もあります。その場合は、--containersオプションを付けることで、コンテナごとの使用量も確認できます。

```
$ kubectl -n kube-system top pod --containers
POD                                       NAME                      CPU(cores)   MEMORY(bytes)
calico-kube-controllers-77c4b7448-6prr9   calico-kube-controllers   1m           11Mi
calico-node-2hc9b                         calico-node               29m          42Mi
calico-node-cgdgk                         calico-node               26m          50Mi
calico-node-tkcz5                         calico-node               31m          50Mi
coredns-6955765f44-55wbn                  coredns                   20m          12Mi
coredns-6955765f44-bhdvr                  coredns                   24m          12Mi
etcd-k8s-master                           etcd                      21m          56Mi
kube-apiserver-k8s-master                 kube-apiserver            44m          343Mi
kube-controller-manager-k8s-master        kube-controller-manager   15m          45Mi
kube-proxy-8pngh                          kube-proxy                1m           17Mi
kube-proxy-gqt42                          kube-proxy                1m           19Mi
kube-proxy-pq2fb                          kube-proxy                1m           17Mi
kube-scheduler-k8s-master                 kube-scheduler            4m           16Mi
metrics-server-fbc46dc5f-9k6kt            metrics-server            1m           10Mi
```
この例だと1Pod/1コンテナなので、あまり意味はないけど・・

#kubectl describeコマンド
kubectl describeは指定したリソースの詳細を表示します。その中で使用リソースを確認することもできます。
nodeを指定すると、そのノードにデプロイされているPodと使用量が確認できます。

```
$ kubectl describe node k8s-worker02
Name:               k8s-worker02
Roles:              <none>
・・・
Non-terminated Pods:          (12 in total)
  Namespace                   Name                              CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                   ----                              ------------  ----------  ---------------  -------------  ---
  default                     sample-web1                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         13h
  default                     sample-web2                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         12h
  kube-system                 calico-node-tkcz5                 250m (12%)    0 (0%)      0 (0%)           0 (0%)         10d
  kube-system                 kube-proxy-8pngh                  0 (0%)        0 (0%)      0 (0%)           0 (0%)         10d
  kube-system                 metrics-server-fbc46dc5f-9k6kt    0 (0%)        0 (0%)      0 (0%)           0 (0%)         3d12h
  loadtest                    load-test-7f75b94bb8-njm97        0 (0%)        0 (0%)      0 (0%)           0 (0%)         5d12h
  sock-shop                   carts-5fc45568c4-r4fqk            300m (15%)    300m (15%)  500Mi (18%)      500Mi (18%)    5d12h
  sock-shop                   orders-74c6b45f4f-42rns           200m (10%)    500m (25%)  500Mi (18%)      500Mi (18%)    5d12h
  sock-shop                   orders-db-df75f545f-vvth6         0 (0%)        0 (0%)      0 (0%)           0 (0%)         5d12h
  sock-shop                   rabbitmq-c7b9db6cc-bb5hn          0 (0%)        0 (0%)      0 (0%)           0 (0%)         5d12h
  sock-shop                   user-559d7f794f-65sxs             100m (5%)     300m (15%)  100Mi (3%)       100Mi (3%)     5d12h
  sock-shop                   user-db-87f548457-ldqvh           0 (0%)        0 (0%)      0 (0%)           0 (0%)         5d12h
・・・
```

#リソースの単位
##CPU
CPUの使用量には「m」の単位がついています。これは$10^-3$を表す「ミリ」で、「1(v)CPU=1000m」となります。物理的なCPUのクロック周波数とは無関係です。
[Kubernetesドキュメント](https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-cpu-resource/#cpu%e3%81%ae%e5%8d%98%e4%bd%8d)

以下の場合、k8s-worker01には2コア（2000m）割り当ててますので、使用量が847mだと使用率が「847/2000=0.42」で42％になります。

```
$ kubectl top node k8s-worker01
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-worker01   847m         42%    1797Mi          65%
```

##メモリ
メモリの単位には「Mi」がついています。メモリの単位はバイト単位になります。
[Kubernetesドキュメント](https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-memory-resource/#%e3%83%a1%e3%83%a2%e3%83%aa%e3%83%bc%e3%81%ae%e5%8d%98%e4%bd%8d)

上の結果の場合メモリの使用量は「1797Mi」になっています。
k8s-worker01には3GB割り当ててますので、「1797/(3*1024)=0.58」になります。でもメモリの利用率（65%）と合わない。

そこで、OS上でメモリ容量を確認してみると「2914176KiB」になってました。
VertualBoxで少し取られるのかな？

```
$ top

top - 11:25:19 up  1:13,  1 user,  load average: 2.72, 2.77, 2.40
Tasks: 164 total,   1 running, 163 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.8 us,  2.4 sy,  0.0 ni, 91.8 id,  0.0 wa,  0.0 hi,  2.1 si,  0.0 st
KiB Mem :  2914176 total,   718616 free,   994636 used,  1200924 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1751636 avail Mem
・・・
```

改めて計算してみると「(1797*1024)/2914176=0.63」。まだ微妙に合わない。
kubectl describeで確認してみると、「Capacity」の値はOSから認識されている容量ですが、「Allocatable」の値は微妙に減っています。
Kubernetesが少し使うのかな？

```
$ kubectl describe node k8s-worker01
Name:               k8s-worker01
Roles:              <none>
・・・
Capacity:
  cpu:                2
  ephemeral-storage:  17394Mi
  hugepages-2Mi:      0
  memory:             2914176Ki
  pods:               110
Allocatable:
  cpu:                2
  ephemeral-storage:  16415037823
  hugepages-2Mi:      0
  memory:             2811776Ki
  pods:               110
・・・
```
Allocatableの値で確認してみると「(1797*1024)/2811776=0.65」。合った！

わずかではありますが、CapacityとAllocatableの値に違いがあるのが気になりますが、リソースの確認方法を確認することができました。