1. 導入:なぜDaemonSetが重要なのか
Kubernetesでクラスタを運用する際、「全ノードで必ず特定のプロセスを動かしたい」という要件は頻繁に発生します。例えば、ログ転送エージェントのFluentdや、ノードの負荷を監視するDatadogエージェントなどが代表例です。もしこれを通常のDeploymentで行うと、ノードの増減に伴うPodのスケジューリング制御が非常に困難になります。DaemonSetを使うことで、ノードの追加・削除に合わせて自動的にエージェントが追従・配置されるため、インフラの運用負荷を劇的に下げることが可能です。
2. 基礎知識:DaemonSetの仕組み
DaemonSetは、Kubernetesのコントローラーの一種です。クラスタ内の各ノードを監視し、そのノード上でPodが未稼働であれば自動的にPodを生成します。
重要ポイントは、通常のDeploymentと異なり、スケジューラーを介さず「各ノードに1つ」という制約を優先してPodを配置する点です。また、nodeSelectorやnodeAffinityを併用することで、特定のスペックを持つノードだけにエージェントを配置するような柔軟な制御も行えます。
3. 実装と論理的解決策
DaemonSetを導入する際は、以下のステップが重要です。
1. リソース要件の明確化:各ノードで常駐するため、CPU/メモリのリミットを適切に設定し、ノード全体の安定性を損なわないようにします。
2. 配置戦略の選択:全ノードに展開するのか、特定のラベルが付与されたノードのみに展開するのかをyamlで定義します。
3. 更新戦略の設定:RollingUpdateを指定することで、全ノードで一斉にエージェントが停止する事故を防ぎ、安全にアップデートできます。
4. サンプルプログラム:汎用的なDaemonSetの定義
以下は、ログ収集エージェントを想定した基本的なDaemonSetの構成例です。
<daemonset-example.yaml>
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector-agent
labels:
k8s-app: log-collector
spec:
selector:
matchLabels:
name: log-collector
template:
metadata:
labels:
name: log-collector
spec:
# 特定のラベルを持つノードにのみ配置する場合に使用
# nodeSelector:
# disktype: ssd
containers:
- name: agent
image: fluent/fluentd:latest
resources:
# リソース制限をかけてノードのメモリ枯渇を防ぐ
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
# ローリングアップデートの戦略:古いPodを先に削除してから新しいPodを起動
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
5. 応用・注意点:現場での運用Tips
現場でDaemonSetを扱う際に陥りやすい罠と対策を紹介します。
・ノードテイント(Taints)への対応:DaemonSetはデフォルトでTaintsを無視できない場合があります。特定のノードに配置したい場合や、マスターノードでも動かしたい場合は、tolerationsを設定する必要があります。
・リソースの競合:全ノードで動く性質上、DaemonSetのメモリリークはクラスタ全体に影響します。必ずリソース制限(Resource Quotas)を厳格に設定してください。
・デバッグの難しさ:ノード単位で動くため、ログが膨大になりがちです。kubectl logs -n [namespace] [pod-name] で個別のPodのログを確認するだけでなく、集約基盤(ElasticsearchやCloudWatchなど)との連携が前提となります。
これらを意識することで、堅牢なインフラ監視・収集基盤を構築できるようになります。ぜひ、ご自身の環境で試してみてください。

コメント