[CKAD] DaemonSet: ノードレベルのインフラエージェントの確実なデプロイと管理

こんにちは!今日は、Kubernetesでワークロードを管理する主要な4つの要素のうち、少し特別な役割を果たすものについて学ぶ時間です。ウェブサーバーやAPIサーバーのようにトラフィックに応じて増減するものではありません。黙々とすべてのノード(サーバー)に1つずつ存在しなければならないインフラレベルの番人、それがDaemonSetです。🛡️

CKAD試験でも、「特定のノードにのみログ収集器をデプロイしなさい」といった形で出題されることがあるので、今日15分だけ投資して、しっかりと概念を掴みましょう!


###

1. はじめに: なぜすべてのノードにPodが必要なのでしょうか? 🤔

私たちが一般的に使用するDeploymentは、「サービスPodを3つ起動して!」と要求すると、スケジューラーが自動的にリソースが残っているノードに適切に配置します。1つのノードに2つ起動することもあれば、3つすべてが異なるノードに起動することもあります。

しかし、状況を変えてみましょう。

100台のサーバー(ノード)で構成されたKubernetesクラスターがあるとします。この100台のサーバーで発生するシステムログをすべて収集する必要があると仮定してみましょう。

  • Deploymentで`replicas: 100`を設定すれば良いでしょうか?
  • 👉 いいえ! 運が悪ければ、あるノードにはログ収集器が2つ起動し、別のノードには1つも起動しない可能性があります。

このような場合に必要となるのが、「クラスターのすべてのノード(または特定の条件を満たすノード)にPodのコピーが正確に1つずつ実行されることを保証」するコントローラー、DaemonSetです。

2. DaemonSetの主な役割 (Use Cases) 🛠️

DaemonSetは通常、アプリケーションロジックよりもインフラストラクチャレベルの作業を実行するために使用されます。ノード自体を管理または監視する「エージェント」の役割が主な任務です。

代表的な使用例は以下の通りです:

  1. 📝 ログ収集デーモンの実行:
    • 各ノードで発生するコンテナログやシステムログを収集し、中央ログストレージ(Elasticsearch、Lokiなど)に送信します。
    • 例: Fluentd、Fluent Bit、Filebeat
    1. 📊 監視デーモンの実行:
      • 各ノードのCPU、メモリ、ディスク使用量など、ノード自体の状態情報を収集します。
      • 例: Prometheus Node Exporter、Datadog Agent
      1. 🌐 クラスターストレージデーモンおよびネットワークプラグイン:
        • 各ノードでストレージをマウントできるように支援したり、ノード間のネットワーク通信を担当するCNIプラグインを実行します。
        • 例: Glusterd、Ceph、Calico、Flannel

        💡 要点まとめ: ノードがクラスターに新しく追加されると、DaemonSetが自動的にPodを作成し、ノードが削除されるとPodも一緒にクリーンアップしてくれます。本当に頼りになる番人ですね?

        3. CKAD実践!YAMLで出会うDaemonSet 📄

        百聞は一見に如かず!実際のコードを見ながら、Deploymentとどのような点が異なるのか見てみましょう。

        最大の違いは、`replicas`フィールドがないことです。数はノードの数が決定するからです!

        以下は、すべてのノードにfluentdというログ収集器をデプロイする簡単なDaemonSetの例です。

        apiVersion: apps/v1
        kind: DaemonSet  # 👈 種類はDaemonSetです。
        metadata:
          name: fluentd-elasticsearch
          namespace: kube-system # 通常、インフラ関連はkube-systemにデプロイします。
          labels:
            k8s-app: fluentd-logging
        spec:
          # replicas: 3 👈 Deploymentとは異なり、このフィールドはありません!
          selector:
            matchLabels:
              name: fluentd-elasticsearch
          template: # ここからはPodテンプレートと同じです。
            metadata:
              labels:
                name: fluentd-elasticsearch
            spec:
              # ノードのシステムログパスをPodにマウントする設定(例)
              volumes:
              - name: varlog
                hostPath:
                  path: /var/log
              containers:
              - name: fluentd-elasticsearch
                image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
                volumeMounts:
                - name: varlog
                  mountPath: /var/log
                resources:
                  limits:
                    memory: 200Mi
                  requests:
                    cpu: 100m
                    memory: 200Mi
              # マスターノード(コントロールプレーン)にもデプロイするには、テイントの容認が必要になる場合があります。
              tolerations:
              - key: node-role.kubernetes.io/control-plane
                operator: Exists
                effect: NoSchedule
              - key: node-role.kubernetes.io/master
                operator: Exists
                effect: NoSchedule

        4. CKAD深化: 「特定のノードにのみデプロイしたい!」 (Node Selector) 🎯

        CKAD試験では、単にDaemonSetを作成するだけでなく、条件を与える場合が多くあります。

        「GPUが搭載されているノードにのみ監視エージェントをDaemonSetとしてデプロイしなさい。」

        基本的にDaemonSetはすべてのノードにデプロイされますが、`nodeSelector`や`affinity`を使用すると、特定のラベルを持つノードにのみPodを起動できます。

        シナリオ例: ノードのうち`type=gpu-node`というラベルが付いたノードにのみデプロイしたい場合は?

        apiVersion: apps/v1
        kind: DaemonSet
        metadata:
          name: gpu-monitor
        spec:
          selector:
            matchLabels:
              app: gpu-monitor
          template:
            metadata:
              labels:
                app: gpu-monitor
            spec:
              # 👇 この部分が重要です!
              nodeSelector:
                type: gpu-node
              containers:
              - name: nvidia-gpu-exporter
                image: nvidia/gpu-monitoring-tools
                # ... 省略 ...

        このように設定すると、DaemonSetコントローラーはクラスターのノードの中から`type=gpu-node`ラベルを持つノードだけを選んで、Podを1つずつ作成してくれます。とてもスマートですね? 🧠

        5. DaemonSetの更新戦略 (RollingUpdate vs OnDelete) 🔄

        DaemonSetでデプロイされたPodのイメージを変更するとどうなるでしょうか?Deploymentと同様に、DaemonSetも更新戦略を持っています。

        • RollingUpdate (デフォルト値):
        • 最も推奨される方式です。Deploymentのように一度にすべてのPodを停止させるのではなく、ノードごとに順次、旧バージョンのPodを削除し、新バージョンのPodを作成します。サービス中断なしにインフラエージェントを更新できます。
        • `maxUnavailable`設定により、同時にいくつのノードまで更新を進めるか(Podが一時的に存在しなくても良いか)を制御できます(デフォルト値は1)。
        • OnDelete:
        • 名前の通り「削除された時」に更新します。テンプレートを修正しても、すでに実行中のPodは変更されません。
        • オペレーターが手動で該当ノードのPodを`kubectl delete pod …`で削除して初めて、DaemonSetコントローラーが新しいバージョンのPodを作成します。更新のタイミングを完全に手動で制御したい場合に使用します。

        6. まとめ: CKAD試験対策のヒント 🍯

        DaemonSetは、概念さえしっかり掴めばDeploymentと同じくらい簡単です。

        1. 目的を覚える: 「サービス拡張(スケーリング)」ではなく、「ノードごとに1つずつインフラ管理」が目的です。
        2. YAML構造: `replicas`がないことを必ず覚えてください。
        3. ノード選択: 試験で「特定のノードにのみデプロイせよ」という要件が出たら、慌てずにPodテンプレート(`spec.template.spec`)内に`nodeSelector`を追加してください。
        4. Toleration: もしマスターノードにもデプロイする必要がある場合は、マスターノードのTaintを許容する`tolerations`設定が必要になる可能性があることを念頭に置いてください。(最新バージョンでは自動的に追加されることもありますが、明示的に設定するのが良いでしょう。)

        今日学んだDaemonSet、いかがでしたか?クラスターを安定的に維持するために、目に見えないところで一生懸命働いている頼もしい支援者のようではありませんか? 👮‍♂️

        CKAD試験の準備中に何か質問があれば、いつでもお気軽にお尋ねください。皆さんの合格を心から応援しています!頑張ってください! 💪



Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です