KubernetesのCNCFプロジェクトのドキュメントは、古いもの、新しいもの、意気込み表明のもの、などなど色々なもの混合になっていて、何を取り入れたら適切なのか解りづらいところが苦しい。 もちろん、クラウドベンダーのドキュメントと合わせて見るのが良いが、それでも、基本的なことは、OSSプロジェクトの資料で勉強してから来てね… という立場を取られる事も少なくないから、Kubernetesの技術を習得し難いと感じる。
今回は、Kubernetesの Task, Moniror, Log and Debugのモニタリングツールやロギングツールの一部について、調べて解ったことを書き残しておきます。
今回も、実際にソフトウェアを実際に動かして、ドキュメントと実装を確認しながら書いていきます。 vagrantでのKubernetesクラスタの構築、そして、適用したYAMLファイル等は、https://github.com/takara9/vagrant-k8s においてあります。
コアメトリックス・パイプライン Core metrics pipeline
Heapsterをインストールしていれば、kubectl top
コマンドを利用することができる。ウェブブラウザを操作しなくても、CPUとメモリの使用量を絶対値と相対値で知ることが便利で便利なコマンドである。 これは、k8sのAPIサーバーのエンドポイント以下のパスで/apis/metrics.k8s.io/でアクセスでき、セキュリティ、スケーラビリティ、信頼性を提供するとされています。
しかし、注意書きが有り、"Metrics Server"がデプロイされていないと使えいないとある。 しかし、インストールのガイドの通りに実行しても、"kubectl topの実行例"からも判る通り、インストールされていません。
kubectl top の実行例
vagrant@node-1:~$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-1 85m 8% 931Mi 49%
node-2 37m 3% 846Mi 44%
node-3 32m 3% 1342Mi 70%
vagrant@node-1:~$ kubectl top pod
NAME CPU(cores) MEMORY(bytes)
nginx-6f596bfb6d-dc5l6 0m 2Mi
vagrant@node-1:~$ kubectl top pod --all-namespaces
NAMESPACE NAME CPU(cores) MEMORY(bytes)
default nginx-6f596bfb6d-dc5l6 0m 2Mi
kube-system elasticsearch-59d89bf8d-wlp4h 6m 793Mi
kube-system etcd-node-1 8m 53Mi
kube-system fluentd-9rbz6 2m 72Mi
kube-system fluentd-9wnp9 2m 77Mi
kube-system heapster-69b5d4974d-84d9n 0m 28Mi
kube-system kibana-7959c48fd-8glxv 3m 235Mi
kube-system kube-apiserver-node-1 16m 239Mi
kube-system kube-controller-manager-node-1 23m 39Mi
kube-system kube-dns-86f4d74b45-plmnd 0m 23Mi
kube-system kube-flannel-ds-8g82w 1m 9Mi
kube-system kube-flannel-ds-bfj67 1m 9Mi
kube-system kube-flannel-ds-tz9nj 1m 10Mi
kube-system kube-proxy-5lcb5 1m 10Mi
kube-system kube-proxy-g75c9 1m 10Mi
kube-system kube-proxy-vjph7 2m 10Mi
kube-system kube-scheduler-node-1 7m 11Mi
kube-system kubernetes-dashboard-7d5dcdb6d9-lzl86 0m 16Mi
Metrics Serverは、どこに行ったのかと、ソースコード https://github.com/kubernetes-incubator/metrics-server を参照すると、"kubernetes-incubator" となっており、https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/metrics-server.md では、Kubernetesの設計として受理された提案というレベルの様に伺えます。
この様な情報から、k8sのインストーラーから普通に導入されるレベルにならないと、ここに依存するには、早すぎるという印象を受けました。
計算、ストレージ、そして、ネットワークの資源監視ツール
(Tools for Monitoring Compute, Storage, and Network Resources)
この章では、Kubernetesのモニタリングのアーキテクチャとして引用される事も多い下図があります。 この図から、Heapsterは、Nodeの一つに常駐して、自己が存在するノード、および、他のすべてのノードの kubelet と連携して、Storage Backendで何かを送り出す役割であることが理解できます。
Kubelet
Kubeletは、Kubernetesマスターと各ノードの間の橋渡しとして機能します。Kubeletは、各ポッドを構成コンテナに変換し、cAdvisorから個々のコンテナ使用統計をフェッチします。 次に、集約されたポッドリソース使用統計をREST APIを介して公開します。
cAdvisorについて
Advisorは、オープンソースコンテナリソースの使用状況とパフォーマンス分析エージェントです。コンテナ用に専用に設計されたもので、ネイティブにDockerコンテナをサポートしています。Kubernetesでは、cAdvisorはKubeletバイナリに統合されています。cAdvisorは、マシン内のすべてのコンテナを自動検出し、CPU、メモリ、ファイルシステム、およびネットワーク使用状況の統計情報を収集します。つまり、cAdvisorは、kubeletの一部として動作しているとの事です。 ここで、ポート4194でウェブUIを提供しているとなっていますが、しかし、現在(1.10)、k8sのインストーラのパッケージでは、次の様にセキュリティの観点から 4194ポートは閉じられているので、ドキュメントを鵜呑みにしない様に注意が必要です。 後述するPrometheusは、プル型のメトリックス収集をおこなう時系列データベースであるが、ポート番号を10255に変更しなければ、メトリックスを収集できません。
vagrant@node-1:~$ cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf |grep cadvisor
Environment="KUBELET_CADVISOR_ARGS=--cadvisor-port=0"
Heapster
現在の公式のKubernetesダッシュボードでは、CPU /メモリー使用率メトリックを表示するためにHeapsterが使用されています。ダッシュボードがPrometheusと他のプラグイン可能な監視ソリューションをサポートするというオープンな機能要求が存在しますが、今のところ、Heapsterはどのプロダクション・クラスタにとっても欠かせないコンポーネントです。
Heapsterの機能要約
- モニターおよびイベント・データをKubernetesクラスター全体から集約する
- ネイティブにサポートされ, すべてのバージョンで動作
- クラスタ内でポッドとして動作、アプリケーション実行と同様
- クラスタ内のすべてのノードを検出し、各ノードのKubeletから情報を収集、Kubeletは、cAdvisorからデータを取得
- 関連するラベルとともにポッドで情報をグループ化、ストレージとビジュアライゼーションのために構成可能なバックエンドにプッシュ
- 現在サポートされているバックエンドには、InfluxDB(視覚化のためのGrafana)
ストレージバックエンド (Storage Backends)
InfluxDB と Grafana が紹介されている。 現在、主流のPrometheusとGrafanaの組み合わせと比べると、この組み合わせ専用のコンテナが提供されており、ただちに、使い始められる点で、とても便利である。
Heapster-InfluxDB-Grafana 実行例
以下の利用しているyamlファイルは、https://github.com/kubernetes/heapster/tree/master/deploy/kube-config/influxdb を k8s 1.10 の vagarantの環境に合わせて、動作する様に修正したものです。 heapsterは、'kubectl top'を実行するために、予め動かしていたので、unchanged になっています。 4つのYAMLファイルを適用するだけで、前述の図の構成を作り、Grafanaのウェブ画面でモニタすることができる様になります。
vagrant@node-1:~$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-influxdb/heapster-rbac.yaml
clusterrolebinding.rbac.authorization.k8s.io "heapster" configured
vagrant@node-1:~$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-influxdb/heapster.yaml
serviceaccount "heapster" unchanged
deployment.extensions "heapster" unchanged
service "heapster" unchanged
vagrant@node-1:~$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-influxdb/influxdb.yaml
deployment.extensions "monitoring-influxdb" created
service "monitoring-influxdb" created
vagrant@node-1:~$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-influxdb/grafana.yaml
deployment.extensions "monitoring-grafana" created
service "monitoring-grafana" created
vagrant@node-1:~$ kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
heapster ClusterIP 10.244.216.216 <none> 80/TCP 1h
monitoring-grafana NodePort 10.244.20.94 <none> 80:31500/TCP 24s
monitoring-influxdb ClusterIP 10.244.163.105 <none> 8086/TCP 48s
InfluxDB - Grafana モニタリング画面
前述のYAMLの適用結果で、vagrant仮想サーバーをブラウザから、http://(ip-address-of-node-1):31500/ としてアクセスすることで、Grafanaの画面を閲覧することができます。カッコ内は、IPアドレスに置き換えてください。 GitHub Vagrantfileの設定を使ったとすれば、192.168.1.91になります。
ダッシュボードのテンプレートと普及状況
こんなに便利で手軽ならば、広く多く使われ、主流のツールになっていると考えたくなるのですが、そうなっていません。 コミュニティで作成されたダッシュボードを、データソース:InfuxDB の条件で検索すると、わずか5件だけで、ダウンロード数も1000未満となっています。
Kubenetes ダッシュボード
せっかく、Heapsterを動かしたので、ダッシュボードのグラフを見てみたいと思います。 ダッシュボードの設定方法は、K8s on Vagrant, ダッシュボードのセットアップ を参照してください。 Heapsterが動作していない場合は、円グラフの上のCPU Usage と Memory Usageのグラフは表示されません。
次のポッドのサマリー画面では、Heapsterが動作していないと、CPU(コア数)とメモリ(バイト)列が表示されません。
プロメテウス Prometheus
僕は、プロメテウスという音を聞くと、何故か銀河鉄道999の優しくて美しいメーテルの怖ーいおっかさん、プロメシュームが連想してしまいます。プロメシューム(プロメチウム)は、元素(Pm)の名前でもあり、天然に存在するものは確認されず,1945年に核分裂生成物から初めて存在が確認されたため、ギリシャ神話に出て来る英雄プロメテウスが天上から火を盗んだかどで岩山に鎖で縛られた話にちなんで、元素に付けられた名前です。
どうでも良い話は、ここまでにして、
プロメテウスは、もともとSoundCloudで構築されたオープンソースのシステム監視と警報のツールキット です。2012年の創業以来、多くの企業や組織がプロメテウスを採用しており、このプロジェクトは非常に活発な開発者とユーザーコミュニティを持っています。これは現在、スタンドアロンのオープンソースプロジェクトであり、どの企業からも独立して管理されています。これを強調し、プロジェクトのガバナンス構造を明確にするために、プロメテウスはKubernetesの後の第2のホストプロジェクトとして2016年にCloud Native Computing Foundationに参加しました。 https://prometheus.io/docs/introduction/overview/ には、プロメテウスの特徴や得意とするユースケースが記載されています。
プロメテウスは、cAdvisor, node-expoter, kube-state-metrics などのメトリックス・コレクタと呼ばれるCPU,メモリ、ネットワークなどの使用量をノード、コンテナ、ポッドなどの単位で収集するソフトウェアです。
プロメテウスの設定として、prometheus.yamlファイルに、メトリックス・コレクタのジョブを定義しておくことで、例えば 10秒 間隔で情報を収集して、蓄積していってくれます。 k8sでプロメテウスを利用する場合には、prometheus.yamlを ConfigMapとして名前空間下のクラスタ環境に統督して、プロメテウスのポッドから、ConfigMapをボリュームとしてマウントして利用します。
次のプロメテウスの実行例は、vagrantのk8sクラスタ用にカスタマイズしたもので、https://github.com/takara9/vagrant-k8s/tree/master/mon-prometheus に置いてある YAMLファイルを適用したものです。
vagrant@node-1:/vagrant$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-1 83m 8% 968Mi 50%
node-2 37m 3% 848Mi 44%
node-3 34m 3% 1418Mi 74%
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/rbac.yaml
clusterrolebinding.rbac.authorization.k8s.io "kube-state-metrics" created
clusterrole.rbac.authorization.k8s.io "kube-state-metrics" created
serviceaccount "kube-state-metrics" created
clusterrolebinding.rbac.authorization.k8s.io "prometheus" created
clusterrole.rbac.authorization.k8s.io "prometheus" created
serviceaccount "prometheus-k8s" created
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/node-exporter.yaml
daemonset.extensions "node-exporter" created
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/kube-state-metrics.yaml
deployment.extensions "kube-state-metrics" created
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/prometheus-configmap.yaml
configmap "prometheus-core" created
configmap "prometheus-rules" created
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/prometheus.yaml
deployment.extensions "prometheus-core" created
service "prometheus" created
vagrant@node-1:/vagrant/prometheus$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-prometheus/grafana.yaml
deployment.extensions "grafana-prometheus" created
service "grafana-prometheus" created
vagrant@node-1:/vagrant/prometheus$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-1 126m 12% 992Mi 52%
node-2 171m 17% 874Mi 46%
node-3 189m 18% 1525Mi 80%
Grafanaセットアップ
上記の設定を変更していなければ、http://192.168.1.91:31510/ でGrafanaへのログイン画面が表示されます。 Grafanaへは、admin/adminでログインできます。
データソースの設定
先ほどは、InfuxDB用に作られたコンテナのGrafanaでしたから設定が不要でしたが、こちらは設定操作が必要です。 次の画面から add data sourceをクリックします。
設定画面で入力するには、3箇所です。 Nameにデータソースが識別できる名前をセットします。Typeは選択リストになっているので、Prometheusを選択します。 そして、最後にHTTP URLのフィールドに、http://prometheus:9090 をセットして、「Save & Test」をクリックして "Data source is working" が表示されたら完了です。
ダッシュボードの選択
サイドメニューのダッシュボードのアイコンをクリックして、画面上のHOMEの表示をクリックすると、次の画面が出ます。 右側のメニューの一番下 "Find dashboard on Grafana.com" をクリックします。
別のタブに、Grafana.comのダッシュボードの検索画面があらわれます。そこで、"Filter by:"のフィールドに、次の様にセットして、ダッシュボードを絞り込みます。 Data Source に、"Prometheus", Search within this list に "kubernetes" とすると、プロメテウスでKubernetesに関するダッシュボードが表示されます。 この中で、最もダウンロード数が多い下から2番目をクリックします。
ダッシュボードの番号が表示されるので、クリップボードにコピーしておくか、番号を暗記します。 インポートの画面に戻って、番号をインプットして "Load" をクリックします。
データソースに、Prometheusに設定した名前を選択します。これで、k8sクラスタを監視するダッシュボードが表示される様になりました。簡単ですね。それに、ダッシュボードはコミュニテーで作られたた沢山のアセットがありますから、Grafanaを知らなくても、色々なビューで見ることができます。
メトリックスコレクタの設定
プロメテウスが、メトリクス・コレクタへポーリングして、収集する状況を見ることができるのが、次の画面です。これは、PrometheusのサービスをNodePortで外部へ開いて、ブラウザからアクセスする事で参照できます。 ここでは、http://192.168.1.91:31600/target
で参照できます。 これは、prometheus.yamlファイルによって定義されたジョブの実行結果を表しており、不適切な設定があると、Sateの列にDOWNとして表示されます。
このPrometheusの設定は、ConfigMapとして環境にデプロイしていますから、configmapをリストして、名前を確認して、エディットすることができます。 または、元のYAMLファイル prometheus-configmap.yaml で編集します。
vagrant@node-1:~$ kubectl get configmap -n kube-system
NAME DATA AGE
prometheus-core 1 1h
vagrant@node-1:~$ kubectl edit configmap prometheus-core -n kube-system
ファイルを編集させた後は、該当のポッドを削除する事で先起動させて、設定を反映させます。
$ kubectl get po -n kube-system |grep prometheus-core
prometheus-core-7c5bfbb4d4-sf79n 1/1 Running 0 1h
$ kubectl delete po prometheus-core-7c5bfbb4d4-sf79n -n kube-system
pod "prometheus-core-7c5bfbb4d4-sf79n" deleted
$ kubectl get po -n kube-system |grep prometheus-core
prometheus-core-7c5bfbb4d4-9zjr7 0/1 ContainerCreating 0 18s
$ kubectl get po -n kube-system |grep prometheus-core
prometheus-core-7c5bfbb4d4-9zjr7 1/1 Running 0 26s
プロメテウス・オペレータ
Kubernetes AddOn の プロメテウス には、このコードはE2Eテスト用であり、本番利用には、Kubernetes Operator または [Kube-Prometheus] (https://github.com/coreos/prometheus-operator/tree/master/contrib/kube-prometheus)などの成熟したセットアップを確認する様にとのコメントもある。 KubeCon2018 の RedHat社のキーノートセッションでも、オペレータフレームワークを紹介していた事もあり、今後、注目しておくべき、プロジェクトの一つではないかと思う。
ログ分析 ElassticSearch
並列分散クラスタの実行環境で、クラスタを構成するサーバーの中で、それぞれログが出力されていると、ログの分析や問題判別が、とても大変な作業になります。 この課題を解決するために、クラスタ環境では、ログ転送ツール fluentd を使用して、全文検索データベース ElassticSearchへ蓄積して、 ブラウザUI Kibana で視覚化と分析が、一般的になっています。 Kubernetesのクラスタ環境でも同じ状況にあります。
ElassticSearch, Kibana, Fluentdは、コンテナとして、DockerHubでも公開さてており、Kubernetes上でも利用することができます。また、本番環境を想定した構成のYAMLファイルなどもあります。
しかし、ElassticSearchは、大規模なログ分析を想定したツールなので、本番環境用の設定では、小さな小さなvagrant上で手軽に動かすことができません。 そこで、デベロパー用モードのElassticSearch環境を構築して、検証してみます。
以下の3本のYAMLファイルは、標準的なRBAC下用の Fluentd, vagrant環境用にカスタマイズした、ElasstiecSearch, Kibanaです。
$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-elasticsearch/elasticsearch.yaml
$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-elasticsearch/kibana.yaml
$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-elasticsearch/fluentd-daemonset-elasticsearch-rbac.yaml
このファイルを適用することで、http://192.168.1.91:31601/ でKibanaの画面を参照できる様になります。
NGINXを使用したお試しのログ分析
以下のYMALを提供して、NGINXのサーバーを作り、curlで連続してアクセスして、アクセスログを出力させ、ElassticSearchで収集して、Kibanaでグラフ化してみます。
$ kubectl apply -f https://raw.githubusercontent.com/takara9/vagrant-k8s/master/mon-elasticsearch/nginx.yaml
$ imac:~ maho$ while true; do curl http://192.168.1.91:32000/;sleep 1; done
<!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>
...continue...
収集したログデータに、タイムスタンプでインデックスを付与することで、次の様なリクエスト数の推移を出すことができます。
まとめ
今回、解ったことを列挙します。 ドキュメントを読んだだけでは正しい理解はできず、実際に動作させてみて、判る事も多いと再実感した。
- CNCFプロジェクトTask, Moniror, Log and Debugの幾つかの文書は古かったり、早すぎるものがあり、読者自身が吟味しなければならない。
- Metrics_server は、インキュベーションレベルであり、インストーラによるセットアップでは導入されない。
- Heapsterは、ダッシュボードや
kubectl top
コマンドで、CPUやメモリの使用量を表示するために必須なコンポーネントである。 - Heapster - InfluxDB - Grafana は簡単に設定できて便利であるが、利用者は少数であり、コミュニティも活発ではない。
- Prometheus - Grafana の組み合わせは、活発で、メトリックス・コレクタ、Grafanaダッシューボードなども活発な活動が続いている。
- Prometheusオペレータ、kube-Prometheusは、注目しておくべき、プロジェクトであろうと思う。
- Fluentd - ElassticSeach - Kibana は、k8sでもログ分析の主流である、しかし、Javaで開発されている事もあり、大量のメモリを消費するため、本番運用時には注意が必要である。
k8s on Vagrant の他記事
この記事は、自分のMacOS上のVagrant環境で、小さなKubernetesクラスタを構築して、検証した記録の一部です。これまでに、Vagrantの仮想サーバーのk8sクラスタで、以下の検証を進めてきましたので、参考までにリンクを挙げておきます。
- Kubenetes v1.10 クラスタをVagrantで構築したメモ
- K8s on Vagrant, Node障害時の振る舞いについての検証記録
- K8s on Vagrant, ダッシュボードのセットアップ
- K8s on Vagrant, NFS 永続ボリュームの利用メモ
- K8s on Vagrant, NGINX Ingress Controller の利用
- K8s on Vagrant, Workerノードの追加と削除
- K8s on Vagrant, kube-keepalived-vip を利用したサービスIP設定
- K8s on Vagrant, MetalLB BGP ECMP を利用したロードバランサーの検証