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


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

はじめに

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

Pod

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

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

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

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/

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が再作成されます。

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/

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を動かすこともできます。

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/

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

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

稼働確認

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

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

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

$ 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

まとめ

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


DACエンジニア採用情報

  関連記事

Libra
【HTML5】4ツール出力ファイルサイズ比較

こんにちは、近江です。 前回もHTML5のSwiffyについて書かせて頂きましたが、まだまだHTML5について調査しています。 今回はSwiffyを含めた4つのHTML5系ツールで、同じ素材で同じアニメーションを作成した時のファイルサイズを比較したいと思います。 何故ファイルサイズの比較をするかと言 …

gnu
いまさらですが… GNU screen チートシート

最近はローカル環境で開発するようになってきたので、screen コマンドを使う機会も少なくなって来たような気がします。で、使ってないと忘れてしまうので、チートシートを作ってみました。 参照サイト GNU screen [quick_reference] 起動 コマンド 動作 screen -S &l …

logos
【小ネタ】タスク管理ツール移行: Trello から Asana

  プロジェクトチームのタスク管理ツールを Trello から Asana に変えることになり、 タスクの移行が意外と簡単にできた、というお話です。 Trello と Asana もともと使っていたのは Trello(トレロ)です。 プロジェクト > タスクグループ > タスク …

ie10
modern.IEを使ってMac上でWindows10を動かす

Microsoftが提供している modern.IE というプロジェクトがある。そこで提供されている仮想環境を使って、MacにWindows10をインストールしてみる。ちなみに、このプロジェクトの本来の目的はInternet Explorerの表示確認やデバッグの支援。 VirtualBoxの準備 …

image2
自社サービスのDocker化(前編)

こんにちは。 インフラ開発部の上田です。 普段は自社開発システムのインフラ担当として、日々頑張って仕事をしています。 今回は、近年話題になっているDockerについて、取り上げてみようと思います! なぜDockerなのか・・・? そもそもDockerとは何か・・・?   当社では様々なサー …

index
Android 非同期処理についてまとめてみた

Androidには、UIに影響を与えないよういくつか非同期処理が用意されています。 今回は非同期処理の代表的な ・Service ・IntentService ・HandlerThread について違いを踏まえながらまとめます! 非同期処理について(http://codezine.jp/articl …

スクリーンショット 2015-05-29 6.49.13
Vagrantの機能を使って開発環境の効率をあげてみた。

プラットフォーム・ワンのシステムの運用・保守担当のエンジニアです。 保守の仕事に関わると、 ユーザからのお問い合わせだったり、監視アラートによる検知から システムを調査することがあります。 ログとソースコードを見て、不具合を特定し改修する。 すぐできればカッコいいですが、 「本番環境に反映して別のエ …

rails
初心者がRailsで開発 – deviseでユーザー認証設定 -

こんにちは、2年目のYukaです。 開発部所属でありながら実は、、 実際に自分で手を動かして開発する機会がなかなかありませんでした。。 しかしついに、、、 開発初心者がRailsでWebアプリの開発に挑戦します!! 今回のゴールは社内でも使用しているGoogleアカウントで簡単にログインができるよう …

dockerlogo
自社サービスのDocker化(後編)

こんにちは。 インフラ開発部の上田です。 前回、前編としてDockerについて書き、早半年も経ちました。 前編はこちらです 今回は後編として、以下について書いてみたいと思います。 ■複数プロセス起動 前編で書いた通り、通常のOS起動時とは異なり、コンテナ上で個別にプロセスを起動する必要があります。 …

logomono-tableau-software-mono
Tableauを利用してMySQLとRedshiftのクロスDBジョインを実現する

はじめに RedshiftやTreasureDataなどのデータマート用のDBにはID単位の解析結果が格納され、ローカルのMySQLにはIDに紐づいた名称マスタが管理されている構成の場合、データマートのクロス集計結果に対してIDに紐づいた名称を付与したいことがあります。 データマート用に用意したDB …