目的:
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形式でも出力可能です。
ただし、CPU,メモリ以外の情報を出力することはできませんでした。
[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マニフェストファイルに定義し、構築進めたいと思います。
以上です。