DaemonSet

What is a DaemonSet?

DaemonSetはすべて(またはいくつかの)NodeでPodのコピーを実行することを保証します。 NodeがClusterに追加されると、Podはそれらに追加されます。 NodeがClusterから削除されると、PodはGarbage Collectionされます。 DaemonSetを削除すると作成されたPodも削除されます。

DaemonSetの典型的な用途は

  • glusterdcephなどのストレージデーモンを各ノードで実行
  • fluentdlogstashなどのログ収集デーモンを各ノードで実行
  • Prometheus Node Exporter、collectd、Datadog agent、New Relic agent、Gangliaのgmondなどのモニタリングデーモンを各ノードで実行

単純なケースでは全てのノードをカバーするひとつのDaemonSetがそれぞれのタイプのデーモンに使用されます。 より複雑な設定では1つの種類のデーモンに複数のDaemonSetを使用できますが、ハードウェアの種類によって異なるフラグや異なるメモリ、CPU要求と共に用いることになるかもしれません。

Writing a DaemonSet Spec

Create a DaemonSet

DaemonSetはYAMLで記述できます。 例えば、下のdaemonset.yamlfluentd-elasticsearchのDockerイメージを実行するDaemonSetです。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: k8s.gcr.io/fluentd-elasticsearch:1.20
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
  • YAMLファイルに基いてDaemonSetを作成します: kubectl create -f daemonset.yaml

Required Fields

他のすべてのKubernetesの設定のように、DaemonSetにapiVersionkindmetadataフィールドは必要です。 設定ファイルが動作するための一般的な情報です。 deploying applicationsconfiguring containersobject management using kubectlを見てください。

DaemonSetは.specセクションも必要です。

Pod Template

.spec.template.specの必須項目です。

.spec.templatePodテンプレートです。 これはapiVersionkindを持たずネストされていることを除きPodのスキーマと同一です。

Podに必要なフィールドに加えて、DaemonSetのPodテンプレートは適切なlabelを指定する必要があります。 (pod selectorを見てください。)

DaemonSetのPodテンプレートはRestartPolicyAlwaysである必要があります。 指定がなかった場合はデフォルトでAlwaysになります。

Pod Selector

.spec.selectorフィールドはPodのセレクタです。 Job.spec.selectorと同様です。

Kubernetes 1.8から.spec.templateのラベルと一致するPodセレクタを指定する必要があります。 値が設定されないときにデフォルト値は設定されません。 セレクタのデフォルト値設定はkubectl applyと互換性がありませんでした。 また、一度DaemonSetが作成されるとその.spec.selectorは変更できません。 Podセレクタの変更は意図しないPodの孤立を引き起こし、ユーザを混乱させることがわかりました。

.spec.selectorは2つのフィールドを持つオブジェクトです。

  • matchLabels - ReplicationController.spec.selectorと同様です。
  • matchExpressions - キーの指定によりより洗練されたセレクタの構築を許可します。値一覧とキーと値に紐づくオペレータになります。

両方指定されたときはANDで処理されます。

.spec.selectorが指定されたとき、必ず.spec.template.metadata.labelsと一致していなければなりません。 一致していないコンフィグはAPIに拒否されます。

また、通常は直接、他のDaemonSet経由、ReplicaSetのような他のController経由に関わらず、このセレクタと一致するlabelを持つPodを作るべきではありません。 さもなければ、DaemonSetコントローラはそれらのPodがそのDaemonSetによって作られたものと考えます。 Kubernetesはユーザがそうすることを防ぎません。 これをしたくなる1つのケースとしては、違う設定値をもつPodをテストのためにあるノードに手動で作るときです。

How Daemon Pods are Scheduled

通常はPodが実行されるマシンはKubernetesスケジューラに選択されます。 しかし、DaemonSetコントローラによって作られたPodは既にマシンが選択されています。 (Pod作成時に.spec.nodeNameが指定されていて、スケジューラに無視されます) それにより、

  • DaemonSetコントローラではNodeのunschedulableフィールドは尊重されません
  • DaemonSetコントローラはスケジューラが起動していなくてもPodを作成することができるので、クラスタの起動の助けになります

DaemonSetのPodはtaintsとtolerationsを尊重しますが、Podは次のtaintsのためのNoExecute tolerationsを持ち、tolerationSecondsを持たず作成されます。

  • node.kubernetes.io/not-ready
  • node.alpha.kubernetes.io/unreachable

これはTaintBasedEvictions機能(alpha)が有効なとき、ネットワーク分断のようなNode障害があったときにPodが追い出されないことを保証します。 (TaintBasedEvictionsが無効のときも追い出されませんが、tolerationsよりもNodeコントローラにハードコードされた振る舞いをします。)

次のtaintsも有効です。

  • node.kubernetes.io/memory-pressure
  • node.kubernetes.io/disk-pressure

critical podが有効でDaemonSetのPodがcriticalとラベル付けされているとき、Daemon Podはnode.kubernetes.io/out-of-diskのためのNoSchedule tolerationとともに作成されます。

以上すべてのNoSchedule taintは1.8以降でTaintNodesByCondition機能(alpha)が有効のときに作成されます。

node-role.kubernetes.io/masterNoSchedule tolerationは1.6以降ではデフォルトではないためmaster nodeにスケジュールするために必要です。

Communicating with Daemon Pods

DaemonSetのPodと通信するためにはいくつか可能な方法があります。

  • Push: DaemonSetのPodをデータベースのような他のサービスにデータを送信するように設定します。クライアントがありません。
  • NodeIP and Known Port: DaemonSetのPodはhostPortを使えるので、NodeのIPで到達できます。クライアントは何らかの方法でNodeのIPを知り、慣習によりポートをしっています。
  • DNS: 同じPod selectorでheadless serviceを作り、endpointsリソースを使うかDNSのAレコードでDaemonSetを発見します。
  • Service: 同じPod selectorでServiceを作り、Serviceを使ってランダムなNodeのDaemonに到達できます。(特定のNodeに到達する方法はありません)

Updating a DaemonSet

Nodeのラベルが変更されると、DaemonSetはただちに新しくマッチするNodeにPodを追加して、新しくマッチしないNodeからPodを削除します。

DaemonSetが作成したPodは変更できます。 しかし、すべてのPodのフィールドを変更できるわけではありません。 また、DaemonSetコントローラは次回Nodeが作成されたとき(同じ名前であっても)元のテンプレートを使います。

DaemonSetを削除できます。 もしkubeclt--cascade=falseを指定したら、PodはNodeに残されます。 そして別のテンプレートを使って新しいDaemonSetを作成できます。 別のテンプレートの新しいDaemonSetはラベルがマッチするすべての既存のPodを認識します。 Podテンプレートに不一致があっても修正も削除もしません。 Nodeの削除かPodの削除によって新しいPodを作る必要があるでしょう。

Kubernetes 1.6以降ではDaemonSetのローリングアップデートができます。

Alternatives to DaemonSet

Init Scripts

直接Daemonプロセスをノード上で起動することでDaemonプロセスを実行できます。 (initupstartdsystemdを使って) これは完璧です。 ただし、それらに比べてDaemonSetはいくつかメリットがあります。

  • アプリケーションと同じ方法でDaemonの監視とログ管理が可能
  • アプリケーションと同様の設定とツール(Pod Templateやkubectl)
  • Resource limitが設定されたDaemonを実行することでアプリケーションのコンテナとの分離を強化できます。ただし、これはPodではないコンテナを実行することでも達成できます(例えばDockerで直接起動する)

Bare Pods

特定のノード上に直接Podを作成して実現できます。 ただし、DaemonSetはNode障害や破壊的なNodeメンテナンスやカーネルアップグレードなどの何らかの理由で終了したり削除されたPodを交換します。 この理由により、個別のPodよりDaemonSetを使うべきです。

Static Pods

Kubeletが監視しているディレクトリにファイルを書くことでPodを作成できます。 これはstatic podsと呼ばれています。 DaemonSetと違ってstatic Podはkubectlや他のKubernetes APIクライアントから管理できません。 Static Podはapiserverに依存しないので、クラスタの起動時に必要な場合に便利です。 また、Static Podは将来非推奨になるでしょう。

Deployments

DaemonSetはPodを作成し、Podが終了を想定しないプロセス(例えばWebサーバやストレージサーバ)を持つという意味でDeploymentに似ています。

フロントエンドのようなPodが実行されるホストを正確にコントロールするよりも、ローリングアップデートやレプリカ数のスケールアップ/ダウンが重要なステートレスサービスにはDeploymentを使って下さい。 DaemonSetはすべてあるいは一定のホストで1つのPodのコピーが常に実行されていることや、他のPodの前に起動していることが重要な場合に使って下さい。

results matching ""

    No results matching ""