DACエンジニアブログ:アドテクゑびす界

DACのエンジニアやマーケター、アナリストが執筆するアドテクの技術系ブログです。

kubernetes の全ノード上で同じコンテナを動かす

今回は、kubernetes上で同一コンテナを全ノードで動かす方法を紹介したいと思います。kubernetes自体の起動方法はここでは割愛します。

はじめに

以前、CoreOSのFleet上でmackerel-agentを動かすということを行いました。今回は、kubernetes上で同じようにクラスタ全ノードでコンテナを動かしたいと思います。

Pod

kubernetesでのコンテナの管理は、Podといわれる幾つかのコンテナをグループ化したもの(Pod内に1コンテナでも良い)で管理します。このPodの単位で起動、停止などを行います。

Podの特徴はいくつかあり、例えばPod内のコンテナは同一ホストにデプロイされる(Pod単位でホストにデプロイされる)などがあります。

例えば以下のように記述します。例ではmackerel-agentを使っていますが、docker-dd-agentでもnginxでも構いません。

[code] apiVersion: v1 kind: Pod metadata: name: mackerel-agent spec: containers: - name: mackerel-agent image: mackerel/mackerel-agent imagePullPolicy: Always env: - name: apikey value: <your api key> - name: opts value: -role=<Service>:<Role> - name: enable_docker_plugin value: foo lifecycle: preStop: exec: command: ["/usr/local/bin/mackerel-agent", "retire", "-force"] volumeMounts: - name: docker-sock mountPath: /var/run/docker.sock - name: mackerel-id mountPath: /var/lib/mackerel-agent/ volumes: - name: docker-sock hostPath: path: /var/run/docker.sock - name: mackerel-id hostPath: path: /var/lib/mackerel-agent/ [/code]

Replica Set

Replica Setは、Podの"Replica"を指定台数動かし続けるための仕組みです。以前は Replication Controllerと呼ばれていました。 Replication Controllerとの違いは、selector が使えるかどうかです。

The only difference between a Replica Set and a Replication Controller right now is the selector support.

仮にReplica Setで作成されたkubernetes上のPodに異常があったりPodを削除した場合でも、Replica SetによりPodが再作成されます。

[code] apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: mackerel-agent spec: replicas: 3 selector: matchLabels: name: mackerel-agent template: metadata: labels: name: mackerel-agent spec: containers: - name: mackerel-agent image: mackerel/mackerel-agent env: - name: apikey value: <your api key> - name: opts value: -role=<Service>:<Role> - name: enable_docker_plugin value: foo lifecycle: preStop: exec: command: ["/usr/local/bin/mackerel-agent", "retire", "-force"] volumeMounts: - name: docker-sock mountPath: /var/run/docker.sock - name: mackerel-id mountPath: /var/lib/mackerel-agent/ [/code]

Daemon Set

それでは本題に入りたいと思います。 今まででもReplica Setの設定でNodePortを設定することで、特定のポートを利用するPodは1Podしかの1ノードに稼働できないことを利用して裏技的に全ノードで動かすことができました。なぜこのようなことをするかというとReplica Setsだと同一ノードに同じコンテナが複数動くことがありうるためです。 kubernetesのDaemon Set 実装でそのようなことをせずに全ノードでPodを動かすことが出来るようになりました。では、Daemon Set は何でしょうか。公式ドキュメントには以下のようにあります。

http://kubernetes.io/docs/admin/daemons/#what-is-a-daemon-set

Some typical uses of a Daemon Set are: running a cluster storage daemon, such as glusterd, ceph, on each node. running a logs collection daemon on every node, such as fluentd or logstash. running a node monitoring daemon on every node, such as Prometheus Node Exporter, collectd, New Relic agent, or Ganglia gmond.

用途は様々ですが、今までのようなことをせずに全部のノードでコンテナを動かしたい時に利用するものということがわかります。

Daemon Set設定

それでは、Daemon Setを設定してみましょう。kubernetesは起動済みだとします。今回は、例としてmackerel-agentをkubernetes全ノードで動かしてみたいと思います。

設定方法

DaemonSetの設定用yamlのサンプルです。mackerel-agent以外のimageを動かしたい方は、利用したいimageにあわせて変更をお願いします。同じようにdocker-dd-agentを動かすこともできます。

[code] apiVersion: extensions/v1beta1 kind: DaemonSet metadata: labels: name: mackerel-agent name: mackerel-agent spec: template: metadata: labels: app: mackerel-agent spec: containers: - name: mackerel-agent image: mackerel/mackerel-agent imagePullPolicy: Always env: - name: apikey value: <your api key> - name: opts value: -role=<Service>:<Role> - name: enable_docker_plugin value: foo lifecycle: preStop: exec: command: ["/usr/local/bin/mackerel-agent", "retire", "-force"] volumeMounts: - name: docker-sock mountPath: /var/run/docker.sock - name: mackerel-id mountPath: /var/lib/mackerel-agent/ volumes: - name: docker-sock hostPath: path: /var/run/docker.sock - name: mackerel-id hostPath: path: /var/lib/mackerel-agent/ [/code]

上記ファイルを保存したら、kubectl が使えるホスト上で以下のコマンドを実行してください。

[code] $ kubectl create -f <保存したファイル名> daemonset "mackerel-agent" created [/code]

稼働確認

それでは、きちんとDaemon SetとPodが作成されているか確認しましょう。 Daemon Setは以下のように確認できます。

[code] $ kubectl get ds NAME DESIRED CURRENT NODE-SELECTOR AGE mackerel-agent 20 20 <none> 3d [/code]

20ノードのクラスタだということがわかりますね。 Podも以下のように確認できます。

[code] $ kubectl get pod mackerel-agent NAME READY STATUS RESTARTS AGE mackerel-agent-ald9q 1/1 Running 0 3d (snip) mackerel-agent-zl8cn 1/1 Running 0 3d [/code]

まとめ

今回は、kubernetsの全ノードで同一コンテナを動かす方法をご紹介しました。 監視用のコンテナを全ノードで動かすことが簡単になり、mackerel-agentやdocker-dd-agentなどで監視設定を入れるものより容易になると思います。