Monitoring Kubernetes

CTOのid:stanakaです。

この記事ははてなエンジニアアドベントカレンダー2014の13日目です。(ちなみにもう一度登場予定です。)

昨日、gcp ja night #29 (Google Cloud Platform (GCP)の話を肴にピザとビールをいただく会)Kubernetesのmonitoringについて話してきました。

Kubernetesとは

KubernetesはGoogleが開発している複数のDockerコンテナを協調動作させることのできるクラスタ管理ミドルウェアです。Kubernetesは今年の夏前にオープンソースとして公開されたばかりということもあり、まだまだ荒削りなところがあります。プロダクションに入れるには時期尚早ですが、2015年には完成度も高くなってくることが期待できそうです。

まずプロダクションに入れる際には必須となるリソース状況のMonitoringについて調べてみました。詳しくは上記のプレゼン資料に書いてあります(といってもそれほど詳しくないです)が、以下にまとめてみます

Monitoring Kubernetes

Kubernetesのクラスタは、Master componentsとMinion(クラスタのノード)から構成されます(下図参照)。

このクラスタのMonitoringをするには各Minionの状況とそれらの内部で動いているDockerコンテナの状況を知る必要があります。Kubernetesが持つmonitoringに関連する構成要素は、kubelet, cAdvisor, heapsterの3つで、それぞれ以下の役割を持ちます。

  • kubelet .. 各Minionで起動するプロセス。REST APIにより色々な制御、情報収集ができる
  • cAdvisor .. Dockerなどのコンテナのリソース状況を収集するツールで、kubeletと協調動作します。
  • heapster .. クラスタ内の各Minionから情報を収集し、InfluxDBへインポートします。

Kubernetes標準ではheapster + InfluxDB + Grafana による構成が用意されており、以下のような画面です。

heapsterは各Minion上で動作しているkubeletにリソース情報を問合せています。例えば以下のようなAPIを叩きます。

$ curl http://10.240.153.49:10250/stats/ | jq 'keys'
[
  "name",
  “spec",
  “stats",
  "subcontainers"
]

statsにリソース情報が入っており、60秒分のcpu, memory, network, filesystem, ioの情報が入っています。

各Minion上で動作するDockerコンテナ単位のリソース情報を収集するには、以下のようにすることで指定したコンテナに関する情報が得られます。

curl http://10.240.56.195:10250/stats/90559c9f-8123-11e4-a0ec-42010af08f91/php-redis

KubernetesではあるDockerイメージを複数のDockerコンテナをMinionで動かすことができ、それらはPodsという概念で管理されています。どこのMinionでどのPodsに関するコンテナが動いているかは以下のようにMaster componentsに問合せることで分かります。

$  cluster/kubecfg.sh -json list pods
{
  "items": [
    {
     "id": "73f777c6-8123-11e4-a0ec-42010af08f91",
     "host": "kubernetes-minion-4.c.buoyant-zodiac-558.internal",
     ...
      "desiredState": {
        "manifest": {
          "containers": [
            {
              "image": "brendanburns/php-redis",
              "name": "php-redis"
              ...

これで得られた情報から各Minionのkubeletに問合せを行うことでリソース情報は一通り収集できるようになります。

この先には得られた情報からオートスケールもさせたくなるのですが、そのためには動的にコンテナ数を変更する必要があります。これはkubecfgでresizeを実行することで実現できます。

$ cluster/kubecfg.sh list replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
frontendController     brendanburns/php-redis     name=frontend       3

$ cluster/kubecfg.sh resize frontendController 4

$ cluster/kubecfg.sh list replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
frontendController     brendanburns/php-redis     name=frontend       4

おわりに

Kubernetesはまだまだ荒削りなソフトウェアですが、クラスタ設計やコンテナ配置などにGoogleのこれまでのコンテナ運用に関するノウハウがこめられており、非常に興味深いプロダクトです。実際にプロダクション環境に入れるかどうかは置いておいて、その思想や実装方針などは一通り掘り下げて見ておいたほうが良いと思っています。