Kubernetes Metricsについて調べる

クラスター構築・更新が一通り実装できてきて、Productionを見据えたあれこれを進めるのだが、まずはモニタリング、特にメトリクスまわりからやっていく。以前調べたりもしたが、再度基本的な所を調べておく。

Tools for Monitoring Resourcesを見ると、アプリケーションのメトリクスはリソースメトリクスパイプラインとフルメトリクスパイプラインに分かれている。前者はkubectl topやHorizontalPodAutoscalerで使われるもので、kubeletに内蔵されているcAdvisorが取得するメトリクスをmetrics-serverに集約、KubernetesのAPIから利用できるようにするのが一般的なようだ。

以前だとheapsterがクラスターレベルで分析・監視をするためのソフトウェアとして使われていたと思うが、現在EOLであった。基本的なCPUやメモリ、HPAメトリクスはmetrics-server、汎用的なモニタリングはPrometheusベース、イベントトランスファー(これは調べていない)はeventrouterという風に、用途別に後継ソフトウェアがあるようだ。

それならば、ということでまずはmetrics-serverを試す。kube-apiserverのオプション・metrics-server双方にオプションの追加が必要で手こずったが、NodeとPodのtopが見えることを確認した。手元でパッと見るのによさそう。

HPAはkube-controllermanagerにオプションを追加し、HorizontalPodAutoscalerリソースを作成すれば動く。ちょっと反応が鈍いと感じるが、ここは設定で変わるのだろうか?Prometheusとの連携も気になるところ。

metrics-serverに触れたので、次はPrometheusとGrafanaを見る。入れるだけならyamlでシュッと入れられる。Grafanaのダッシュボードを作るのが大変だよなあ…と思っていたのだけど、Grafana Labsというところからインポートすることができることがわかった。Kubernetes Cluster (Prometheus) dashboard for Grafanaが結構いいかんじぽい。さらには、kubernetes plugin for Grafanaというプラグインがあり、Kubernetesをデータソースとして扱い、Cluster・Node・Podなどのダッシュボードがすぐ使えるようになることがわかった。また、Grafana自体にアラート機能もあるようで、可視化とアラートをGrafanaに集約するのがいいのかな、とも思ったりした。PrometheusのAlertManagerとどちらがいいんだろう。ここは別途調べたい。

メトリクスデータの永続化をどうするか、とか複数クラスターがあるときに見ないと行けない場所が複数あるのがダルそうという課題が残ってはいる(後者についてはメトリクスを集約してあげればよいと思う)が、クラスターを建てたらmetrics-serverとPrometheus、Grafanaを同時にインストールし、GrafanaのKubernetes Pluginですぐにメトリクスが見える状態になっているとかなり便利そうじゃないかなあ。

Hashicorp VaultのPKI Secret Engineを扱うためのCLIツールを書いた

VaultをPKIとして活用していくぞ、という流れが完全にできているのだけど、vaultコマンドやAPIからだと少し利用しにくい。 PKI Secret EndineのAPI がそのままコマンドになっているといいなあと思ったので takaishi/vault-pkiをガッと書いた。現状使えるのは以下のコマンド。

  • pkiの有効化・無効化、一覧表示
  • Root CAの生成・削除
  • Roleの作成・削除・一覧表示
  • Certificateの生成・失効・一覧表示・読み込み
  • URLのセットと読み込み

ガッと書いただけなのでオプションが足りなかったり動かない場所があるかも知れないけど、使うのは自分なので都度直していく。

mdtoc: .mdファイルに目次を挿入するためのツール

takaishi/mdtocという、マークダウン ファイルに目次を挿入するためのCLIツールを作成した。

なぜ作ったかというと、そのまんまで目次の作成を楽にしたかったから。半年くらい定期的に追記したり見返すマークダウン ファイルがあるのだけど、結構長くて目的の見だしを探すのが大変だったりする。GitHub上で表示するので、見だし名を使った内部リンクを作成できるのだけど、見だし数がそこそこ多いので面倒。じゃあツール作って挿入できるようにしよう、と思って作った。

使い方はリポジトリのREADMEを参照してほしい。MacならHomebrewでインストールできるようになっている。go getでもインストールできると思う。なお、Homebrew fomulaの更新はGoReleaserを使って自動化した。GoReleaser、かなり便利なので別途紹介したい。

CustomControllerでinformerを使ってリソースの追加や更新といったイベント毎に処理を行う

Hello Custom Controller!ではカスタムリソースの取得を素朴にループで実装している。しかし、code-generatorにはinformer-genというコマンドがあり、これを使うとリソースの追加や更新、削除といったイベントに対応して任意の処理を実行することが出来る。コードの見通しもよくなるので、informerを使った形に書き換えてみよう。

準備

kubernetes v1.12.3を使う。minikubeで環境を作成:

  • go: v1.11.2

informer用のコードを生成する

code-generatorのinformer-genを使う。

コントローラーの実装

informerを素朴に使った実装は以下の通り。リソースの追加、更新、削除に対応して任意の処理を実行できる。

後はビルドしてデプロイするだけ。注意点として、使用するサービスアカウントがリソースをwatchできる必要があるのでRoleの更新が必要。

カスタムリソースを追加するとaddFunc関数が呼び出されることが確認できる。

informerを使えばイベントに応じて任意の処理を書くことが出来る、ということを確認出来た。code-generatorでコードを生成できるので、基本的にはinformerを使っていくのがよさそうだなあ。

Hello Custom Controller!

2019年はカスタムコントローラーや!ということで2018年末頃から少しづつ調べている。まずは非常に簡単なものを動かしてみる。

Custom Controller is…

CRDについてのメモにも書いたが、CRD自体はただのデータなので、それだけでは何も起こらない。Kubernetesのdeclarative APIを活用するためにはコントローラーの作成が必要。なお、本記事は以下のページを参考にしています。

作っていく

カスタムコントローラーを作っていくわけだが、いきなり複雑なものを作るのは難しい。そこで、まずはカスタムリソースを読み込み、ログに出力するだけのコントローラーを作る。カスタムコントローラー用のSDKやBuilderがいろいろあるようだがこれも使わず、KubernetesのAPI用コードを出力するだめの code-generator を用いて素朴に作ってみる。code-generatorはいくつかの機能を持っている。

  • deepcopy-gen – 各型についてDeepCopy用のメソッドを生成
  • client-gen – カスタムリソースを扱うためのクライアントセットを生成
  • informer-gen – カスタムリソースの変更に対応するためのイベントベースインターフェースを生成
  • lister-gen – GetとListについて、読み取り用キャッシュレイヤを扱うコードを生成

本格的にカスタムリソースを扱うためにはinformer-genやlister-genが必要になるが、今回はdeepcopy-genとclient-genのみ。deepcopy-genも不要な気がするが、これなしでうまく動かす方法がちと分からなかった。

生成元のコードを用意する

まずは apis/foo/v1alpha/doc.go

次にapis/foo/v1alpha/register.go

最後にapis/foo/v1alpha/types.go

コード生成

これらのファイルを用意したら、code-generatorでコードを生成する。なお、code-generatorのバージョンは kubernetes-1.12.3を使用。

カスタムコントローラーを実装

これで、GoからFooリソースを扱うことが出来る。カスタムコントローラー用のコードを書いていく:

コントローラー用のマニフェスト。defaultアカウントがオブジェクトを取得できるようにRBACの設定も行っている:

デプロイして動作確認する

カスタムコントローラーのビルドからKubernetesへのデプロイまで行うためのMakefile:

デプロイする:

カスタムコントローラーのログを見ると、Fooリソースを取得してログに出力していることが確認できた:

非常にシンプル、というかとくに何もしていないが、カスタムコントローラーができたといっていいだろう。理屈ではログ出力の部分をロジックに置き換えればいいはず。実際にはinformerを用いてイベントベースで処理を行うようなコードになるのだと思う。次はログ出力だけではなく別リソースを扱うようにしていきたい。

ソースコードなどはtakaishi/hello2019にあります。