【Kubernetes構築】Minikubeを使ってワーカノード単位のリソース情報を取得する

## 目的：
KubernetesのPod、ノードの状態を監視するため、CPUやメモリなどの情報取得を行えるようにすることを目的としています。サーバの統計情報をモニタリングで収集・可視化する際、自前のスクリプト（例えばvmstatの結果をログに出力・管理する）を用意するケースもあれば、Prometheusなどのツールを利用するケースもありますが、
オートスケーリングや障害自動復旧によりPodやノードが作成された場合、サーバの統計情報をいつとるかが問題になってきます。
ノードをスケールアウト時にスクリプトをどう起動するべきかを考えれば解決な気もしますが、
もっと簡単な方法かつ、より汎用的に収集できないかを検討しました。

## 前提
検討するにあたって、ローカルマシンでKubernetes環境（minikube）を事前に用意します。最近のバージョンだと（v.1.26.2だったかな…）だと、minikubeでもノードをスケーリングすることができるようになりました。
インストール方法はminikubeのインストール方法を参照してください。

## 内容

### ①Metrics Server
参考：https://qiita.com/dingtianhongjie/items/a8ddc2d7f7b57291a13e
#### Metrics Serverとは
KubernetesのpodやNodeのメトリクスを取得することが可能なツールです。

#### 導入方法
※Minikubeを作成・インストールは下記のサイトを参考に導入可能。
　https://kubernetes.io/ja/docs/tutorials/hello-minikube/

curl http://localhost:8001/apis/metrics.k8s.io/v1beta1/pods/
例えば、ノードのリソースに関しては、
「kubectl top node」で確認ができ、取得自体は簡単そうです。
しかしながら、取得できるものが限られていており、うーんて感じですね…
CPU、メモリの量は取れそうですが、使用率となると、オプションを指定しないといけないさそうです。
```
[root@t_kyn039 kube-capacity]# kubectl top node
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
minikube   315m         15%    1043Mi          36%       
[root@t_kyn039 kube-capacity]# kubectl top node --until

```
### ②kube-capacityの利用
#### kube-capacityとは
Podやnode のリソース値（設定値と使用率）をシンプルに表示することができるツールになります。

インストールするには、kube-capacityはbrewのインストールが前提となります。
しかしながら、brewインストールはCentOS7ではgitバージョンが最新化できない問題があることから、CentOS7で使用する場合は、git cloneでモジュールを入れた方法で行っています。

#### 導入方法：1. brewをインストールしたうえで使う。⇒CentOS7では導入コストがかかるため中断×
brewをインストール後、brewでkube-capacityを導入する方法ですが、
brewはsudoerの編集が必要で、sudo権限の一般ユーザが必要。
セキュリティ大丈夫かなという懸念はあるため、個人的にはお勧めしないかと思います。
https://qiita.com/libra_lt/items/548fcbdfbcf992cba4ed
あと、CentOS7ではそもそもgitのバージョン最新化が不可能なので、Pythonのバージョンを上げるなりしないと難しいかと思います。
（本来はセキュリティ強化するならばアップデートはすべきですが、システムの都合上アップデートが難しい場合もあるかと思いますので、ご参考になればと思います。）。

https://nissy-lab.com/blogs/homebrew-centos7/
⇒セキュリティリスクもあるし、何かと編集しないといけなかったり手間がかかる記事もありました。

#### 導入方法：2. githabからクローンして、実行。
gitサイト：https://github.com/robscott/kube-capacity
以下のやり方に沿って、インストール・構築します。
※gitがインストール済であれば、goのみインストールするでもよいと思います。
```
sudo yum install -y git go
git clone https://github.com/robscott/kube-capacity.git
cd kube-capacity
```
たったこれだけで実行できました。
必要であれば、kube-capacityのPATHを設定することで、kube-capacityというコマンドでCPU、メモリの結果を表示できます。
コンテナ単位でもpod単位、ノード単位でも出すことは可能で、
オプションを指定すればJSON形式でも出力可能です。
ただし、ＣＰＵ，メモリ以外の情報を出力することはできませんでした。

```
[root@t_kyn039 kube-capacity]# ./kube-capacity --util --containers --sort cpu.util
NODE           NAMESPACE              POD                                         CONTAINER                   CPU REQUESTS   CPU LIMITS   CPU UTIL      MEMORY REQUESTS   MEMORY LIMITS   MEMORY UTIL
*              *                      *                                           *                           1050m (26%)    200m (5%)    1037m (25%)   470Mi (8%)        270Mi (4%)      1426Mi (25%)
                                                                                                                                                                                          
minikube-m02   *                      *                                           *                           100m (5%)      100m (5%)    647m (32%)    50Mi (1%)         50Mi (1%)       369Mi (13%)
minikube-m02   kube-system            kube-proxy-twsk8                            *                           0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        37Mi (1%)
minikube-m02   kube-system            kube-proxy-twsk8                            kube-proxy                  0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        37Mi (1%)
minikube-m02   default                nginx-deployment-85996f8dbd-8hkrx           *                           0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   default                nginx-deployment-85996f8dbd-8hkrx           nginx                       0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   default                nginx-deployment-85996f8dbd-c4dgl           *                           0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   default                nginx-deployment-85996f8dbd-c4dgl           nginx                       0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   default                nginx-deployment-85996f8dbd-rpptn           *                           0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   default                nginx-deployment-85996f8dbd-rpptn           nginx                       0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        0Mi (0%)
minikube-m02   kube-system            kindnet-h8527                               *                           100m (5%)      100m (5%)    0m (0%)       50Mi (1%)         50Mi (1%)       0Mi (0%)
minikube-m02   kube-system            kindnet-h8527                               kindnet-cni                 100m (5%)      100m (5%)    0m (0%)       50Mi (1%)         50Mi (1%)       0Mi (0%)
                                                                                                                                                                                          
minikube       *                      *                                           *                           950m (47%)     100m (5%)    390m (19%)    420Mi (14%)       220Mi (7%)      1058Mi (37%)
minikube       kube-system            kube-apiserver-minikube                     *                           250m (12%)     0m (0%)      64m (3%)      0Mi (0%)          0Mi (0%)        345Mi (12%)
minikube       kube-system            kube-apiserver-minikube                     kube-apiserver              250m (12%)     0m (0%)      64m (3%)      0Mi (0%)          0Mi (0%)        345Mi (12%)
minikube       kube-system            etcd-minikube                               *                           100m (5%)      0m (0%)      60m (3%)      100Mi (3%)        0Mi (0%)        62Mi (2%)
minikube       kube-system            etcd-minikube                               etcd                        100m (5%)      0m (0%)      60m (3%)      100Mi (3%)        0Mi (0%)        62Mi (2%)
minikube       kube-system            kube-controller-manager-minikube            *                           200m (10%)     0m (0%)      27m (1%)      0Mi (0%)          0Mi (0%)        124Mi (4%)
minikube       kube-system            kube-controller-manager-minikube            kube-controller-manager     200m (10%)     0m (0%)      27m (1%)      0Mi (0%)          0Mi (0%)        124Mi (4%)
minikube       kube-system            kube-scheduler-minikube                     *                           100m (5%)      0m (0%)      10m (0%)      0Mi (0%)          0Mi (0%)        61Mi (2%)
minikube       kube-system            kube-scheduler-minikube                     kube-scheduler              100m (5%)      0m (0%)      10m (0%)      0Mi (0%)          0Mi (0%)        61Mi (2%)
minikube       kube-system            kindnet-ftxxv                               *                           100m (5%)      100m (5%)    5m (0%)       50Mi (1%)         50Mi (1%)       25Mi (0%)
minikube       kube-system            kindnet-ftxxv                               kindnet-cni                 100m (5%)      100m (5%)    5m (0%)       50Mi (1%)         50Mi (1%)       25Mi (0%)
minikube       kube-system            metrics-server-6588d95b98-l7tlc             *                           100m (5%)      0m (0%)      5m (0%)       200Mi (7%)        0Mi (0%)        40Mi (1%)
minikube       kube-system            metrics-server-6588d95b98-l7tlc             metrics-server              100m (5%)      0m (0%)      5m (0%)       200Mi (7%)        0Mi (0%)        40Mi (1%)
minikube       kube-system            coredns-787d4945fb-jwphn                    *                           100m (5%)      0m (0%)      3m (0%)       70Mi (2%)         170Mi (6%)      42Mi (1%)
minikube       kube-system            coredns-787d4945fb-jwphn                    coredns                     100m (5%)      0m (0%)      3m (0%)       70Mi (2%)         170Mi (6%)      42Mi (1%)
minikube       kube-system            storage-provisioner                         *                           0m (0%)        0m (0%)      3m (0%)       0Mi (0%)          0Mi (0%)        30Mi (1%)
minikube       kube-system            storage-provisioner                         storage-provisioner         0m (0%)        0m (0%)      3m (0%)       0Mi (0%)          0Mi (0%)        30Mi (1%)
minikube       kube-system            kube-proxy-ztjs7                            *                           0m (0%)        0m (0%)      2m (0%)       0Mi (0%)          0Mi (0%)        48Mi (1%)
minikube       kube-system            kube-proxy-ztjs7                            kube-proxy                  0m (0%)        0m (0%)      2m (0%)       0Mi (0%)          0Mi (0%)        48Mi (1%)
minikube       default                nginx-deployment-85996f8dbd-vbrd2           *                           0m (0%)        0m (0%)      2m (0%)       0Mi (0%)          0Mi (0%)        2Mi (0%)
minikube       default                nginx-deployment-85996f8dbd-vbrd2           nginx                       0m (0%)        0m (0%)      2m (0%)       0Mi (0%)          0Mi (0%)        2Mi (0%)
minikube       kubernetes-dashboard   dashboard-metrics-scraper-5c6664855-c9wck   *                           0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        14Mi (0%)
minikube       kubernetes-dashboard   dashboard-metrics-scraper-5c6664855-c9wck   dashboard-metrics-scraper   0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        14Mi (0%)
minikube       kubernetes-dashboard   kubernetes-dashboard-55c4cbbc7c-t5rv6       *                           0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        21Mi (0%)
minikube       kubernetes-dashboard   kubernetes-dashboard-55c4cbbc7c-t5rv6       kubernetes-dashboard        0m (0%)        0m (0%)      1m (0%)       0Mi (0%)          0Mi (0%)        21Mi (0%)
minikube       default                nginx-deployment-85996f8dbd-xqd92           *                           0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        3Mi (0%)
minikube       default                nginx-deployment-85996f8dbd-xqd92           nginx                       0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        3Mi (0%)
minikube       default                nginx-deployment-85996f8dbd-wmk2s           *                           0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        2Mi (0%)
minikube       default                nginx-deployment-85996f8dbd-wmk2s           nginx                       0m (0%)        0m (0%)      0m (0%)       0Mi (0%)          0Mi (0%)        2Mi (0%)
```

### ③cadvisorを利用
#### cadvisorとは
Googleが提供および管理するオープンソースのコンテナ監視ツールになります。

Pod、ノードでは、コンテナそのものの状態監視はなく、kube-capacityやMetricsServerでは取得できないようなリソース（ディスク使用率やネットワークトラフィック等）を収集したいときに便利です。
これにより、Pod内部のコンテナのディスク状況、ネットワークの稼働状況を監視します。

#### 導入方法
参考gitサイト：https://github.com/google/cadvisor
特にgitをcloneせず、READMEに記載している
「Quick Start: Running cAdvisor in a Docker Container」
の内容から、dockerをビルド、起動するだけで、コンテナのリソース情報を取得できました。
こちらの内容からKubernetesのマニフェストファイルに定義しておくことで、Kubernetesでも取得可能かと思います。

取得可能なcAdvisorのメトリクスの種類については、こちらが参考になりそうです。
https://qiita.com/MetricFire/items/4aa2d9889c49148a3d7f
https://qiita.com/ysakashita/items/cb471a561501b344534c

メトリクス取得結果は以下の通りで、
curl http://localhost:8080/metrics
で取得はできそうです。
※tailで10行表示していますが、実際は出力行数は多いです。
```
[root@t_kyn039 ~]# curl http://localhost:8080/metrics | tail
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0100 3145k  100 3145k    0     0  7392k      0 --:--:-- --:--:-- --:--:-- 7401k
process_open_fds 13
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 1.62746368e+08
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.68464405353e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.441234944e+09

```

この結果をまとめて統計情報として、保管する方法として、
・外部のエンドポイントにデータをpost（サーバーに送信）する
・他のデータベースにインポートする
などする作りこみが必要そうですが、この辺で確認がとれたので、区切らせていただきたいと思います。
（載せてはいないですが、ブラウザからも見ることができました。）

## あとがき
以上を踏まえると、最低でもkube-capacityだけは入れておきたいというのが結論で、
より詳細な監視をしたい場合は、cadvisorを入れるのがよいかと思います。
しかし、AWSやほかの監視サービスなどのモニタリングに結果をpostしたり、
kube-capacityに関してはbrewを実行するのにsudoerを編集する必要があるので、
結構だるいです。
なので、理想はcAdvisorのみでPrometeus監視するのが最善かもしれません。
cadvisorでも取得できない場合、コンテナ内部で独自にエラーメッセージをはかせ、ログ監視するほうがよさそうです。
 
### リソースが潤沢にあるならば、やっぱりPrometheus、Thenos、Grafanaは使いたい。
KubernetesであればPrometheusというメトリクス情報を収集・蓄積・検索・監視・表示するツールがあります。
Prometheusが取得したメトリクス情報は、Granafaで可視化したり、Thanosに長期保管したりと、コスト削減や運用監視でメリットがありそうなので、最も最適なのは以下の3点を導入するのが最適かと思います。
・Prometheus（メトリクス情報取得）
・Grafana（可視化・監視）
・Thanos（長期保管）
※リソースに余裕あればこちらもKubernetesマニフェストファイルに定義し、構築進めたいと思います。

参考：https://blog.fltech.dev/entry/2020/04/15/Prometheus%2BThanos%E3%81%A7%E5%A4%A7%E8%A6%8F%E6%A8%A1%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9%E7%AE%A1%E7%90%86

以上です。