こんにちは、SPEEDAのSREチームの阿南です。前回から少し時間が経ってしまいましたが、今回はKubernetesのメトリクス取得についてです。本番環境でkubernetesを運用する際、ポッドがどの程度リソースを消費しているのか、クラスター自体のリソースは大丈夫かなど常に把握しておく必要があります。ただ、Kubernetesってどう監視すればいいのって疑問ありますよね。PrometheusとかGrafanaとかよく出てきて概要は理解できるんだけど、実際どう構築すればいいの、とお悩みの方に役立つ記事にしたいと思います。ちなみに弊社ではRancher上にKubernetes環境を本番で利用していますが、大枠は今回紹介するような構成で運用しています。
構築する環境
利用する環境はGKEです。まずKubernetesクラスターの中にPrometheusを構築し、メトリクスを取得します。さらに、クラスター外部にfederation用のPrometheusを構築し、Grafanaでメトリクスを可視化します。概要をざっくりと箇条書きすると、下記のようになります。
【クラスター内部(図の左側)】
KubernetesクラスターにPrometheus ポッドを稼働させる
Prometheus ポッドでクラスター内のメトリクスを取得する
NodeExporter ポッドをDaemonSetで稼働させ、Node(GCEインスタンス)のメトリクスを取得
Prometheus ポッドで取得したデータについては保持期間を1日とする
【 クラスター外部(図の右側)】
federationを使ってクラスター外部のPrometheusから値を取得
Grafanaでメトリクスを可視化
本記事では、まずKubernetesクラスターの中にprometheus ポッドを稼働させて値を取得するところまで紹介し、federationやGrafanaでの可視化周りは次回記事で紹介したいと思います。
構築手順
前回同様手順は別途まとめていますのでこちらをご参照ください。
Kubernetesの認証方式について
GKEのKubernetesバージョン1.8からはRBACがデフォルトで適用されているため、Prometheusで監視をする際に監視に必要な権限を与えてあげる必要があります。 さて構築する際のポイントですが、まずは自分自身のアカウント(kubectlを実行するユーザ)にcluster-adminを付与します。
$ gcloud info | grep Account $ kubectl create clusterrolebinding anan-cluster-admin-binding --clusterrole=cluster-admin --user=sample-owner@sample-project.iam.gserviceaccount.com
cluster-adminを設定する理由は、kubectlを実行するユーザの権限より強い権限をroleとして設定することはできないためです。
ちなみにbindingには、clusterrolebinding
とrolebinding
の2つがあり、それぞれ適用範囲をクラスター全体にするか、細かく設定するかを選択できるようになっています。この辺りの設計は利用するサービスや会社によって最適な設定が異なると思いますので、ぜひ事例があれば聞いてみたいですね。
次にPrometheus用にサービスアカウントを作成します。
$ kubectl create serviceaccount prometheus --namespace monitoring
このサービスアカウントに対して、参照権限を付与します。ここで、resources
がpods, services, deployment
などのリソースを表し、verbs
がそのリソースに対する操作を表します。Prometheusは全てのリソースに対して参照権限を与えたいので、
Prometheusの監視について、secrets等は閲覧権限不要のため内容を修正しました。ご指摘いただいた方ありがとうございます!resources
を *
とし、verbs
で get, watch, list
の動作を許可します。nonResourceURLs
はエンドポイントの権限設定なので、細かく設定する際は/api
等のエンドポイントを指定します。今回はnonResourceURLs
を*
、verbsをget
としてエンドポイントに対してGETリクエストを許可します。これでread_onlyな形で権限を作成することができました。
GKEの場合1.7まではデフォルトのサービスアカウントで全てのリソース、操作が許可されていました。Kubernetes v1.8からRBACがstableになっているのでGKE側でもこの辺りの変更が入っているようです。まだPrometheusにはたどり着いておりません。序盤からハマリどころ満載で、楽しくなってきました。
ConfigMap設定
ConfigMapにPrometheusのconfigファイルを設定します。最初のglobal設定で、メトリクスの取得間隔を指定しています。ポイントとして、 kubernetes_sd_configs
を利用してメトリクスの取得先をdiscoveryできるようにしています。このservice discoveryの設定を利用することにより、サーバが追加になったりした際にも自動的にそれを検知しメトリクスを取得できるようになります。Prometheusの強力な機能ですね。
kubernetes_sd_configs
の中身については正直いきなり理解するのは難しいと思いますので、とりあえず細かい説明は置いて次に進みます。
Deployment設定
PrometheusのDeploymentの設定ですが、ここで最初に作成しておいたサービスアカウントが登場します。下記16行目にserviceAccountName: prometheus
の記載があります。これを指定することで、全てのリソースに対する参照all-reader
ができるようにしています。ちなみに、サービスアカウントを作成するとsecretにca.crt、tokenというデータが作成されます。このsecretはポッドが起動した際に、自動的に/var/run/secrets/kubernetes.io/serviceaccount
の配下にマウントされます。これをPrometheusのconfigに指定することでAPI Serverの認証をパスできるようにしています。先ほどのConfigMapの設定でca_file
とbearer_token_file
によくわからないパスが出てきましたがシークレットがマウントされていたんですね。この辺りの仕様は公式ドキュメントに記載がありますので見てみるといいと思います。Deploymentにサービスアカウントを指定しなかった場合、defaultのサービスアカウントが適用されますので、認証が通らずメトリクスの収集ができなくなります。だからと言って権限を全解放すると色々な事故が起こる可能性がありますし、後からこの認証を入れていくのはかなりしんどいと思います。最初から正しく仕事をする。頑張りましょう。
Service設定とポート解放
Prometheusのサービスを公開します。今回はNodePortモードでノードの30001番ポートを解放しています。つまり、http://<Prometheus 稼働中 Node IP>:30001
にアクセスするとPrometheus ポッドの9090番ポートに接続されるので、Prometheusにアクセスするためには30001番のポートをGCPのネットワーク設定で解放しておく必要があります。GCPの管理コンソールのVPC ネットワーク > ファイアウォールルール
からポートを解放してください。ちなみに、本記事では手間を省くためにNodePortモードを利用しておりますが、Production環境等ではInternalのLoadBalancerを利用した方がノードに依存することがなくなるため運用しやすいと思います。
最後に、Prometheusにアクセスしてみて下記のようにサービスディスカバリができていれば完了です! 結構難しいですよね。。。弊社の本番環境でもPrometheusを利用していますが、正直全てのメトリクスを把握できないほどの種類を取得しています。それだけ細かく取得できているのは素晴らしいのですが、どうやって可視化するのか迷いますよね。次回はそんな方にオススメのGrafana周りを紹介しますのでご興味のある方は楽しみにしていてください。
お知らせ
SREチームでは「No Challenge, No SRE, No SPEEDA」を掲げ、ユーザベースグループのミッションである「経済情報で、世界をかえる」の実現に向けて、日々業務に取り組んでいます。 興味を持ってくださった方はこちらをご確認ください。
また、2018/03/15(木)にハートビーツ社主催で「SRE大全:ユーザベース編」 が開催されます。Youtube Liveでも配信されますのでご興味ある方はぜひご覧ください。