DaemonSets sind eine spezialisierte Controller-Ressource zur Verwaltung von Services, die auf jedem Node im Cluster laufen müssen. Während Deployments und StatefulSets eine bestimmte Anzahl von Replikas verwalten, stellt ein DaemonSet sicher, dass genau ein Pod pro Node (oder einer Teilmenge von Nodes) ausgeführt wird.
Ein DaemonSet verwaltet Pods, die auf jedem Node des Clusters laufen und typischerweise infrastrukturelle Services bereitstellen. Diese Services benötigen direkten Zugriff auf Node-Ressourcen und müssen auf jedem Node verfügbar sein, um clusterweit zu funktionieren.
Kernmerkmale: - Ein Pod pro Node: Automatische Bereitstellung auf allen verfügbaren Nodes - Automatische Node-Integration: Neue Nodes erhalten automatisch einen Pod - Node-lokale Services: Direkter Zugriff auf Host-Ressourcen und Node-spezifische Daten - Cluster-weite Abdeckung: Gewährleistung konsistenter Services auf allen Nodes
| Merkmal | Deployment | StatefulSet | DaemonSet |
|---|---|---|---|
| Pod-Anzahl | Benutzer-definiert | Benutzer-definiert | Ein Pod pro Node |
| Pod-Verteilung | Scheduler-entschieden | Sequenziell | Node-basiert |
| Speicher | Shared/Ephemeral | Persistent pro Pod | Host-Volumes/Ephemeral |
| Skalierung | Manuell/automatisch | Manuell | Automatisch bei Node-Änderungen |
| Node-Zugriff | Eingeschränkt | Eingeschränkt | Vollzugriff möglich |
| Typische Anwendungen | Web-Services | Datenbanken | Monitoring, Logging, Networking |
DaemonSets überwachen kontinuierlich den Cluster-Zustand: - Neue Nodes erhalten automatisch einen DaemonSet-Pod - Entfernte Nodes führen zur automatischen Pod-Löschung - Node-Labels und Selectors bestimmen die Ziel-Nodes
DaemonSet-Pods haben typischerweise erweiterte Berechtigungen: - Zugriff auf Host-Dateisystem über Volume-Mounts - Host-Netzwerk-Zugriff für Netzwerk-Services - Privilegierte Container für System-Level-Operationen - Direct-Access auf Node-Metriken und Logs
Flexible Steuerung der Pod-Platzierung: - Node Selectors für spezifische Node-Typen - Node Affinity für komplexe Placement-Regeln - Tolerations für Tainted Nodes - Field Selectors für Node-Eigenschaften
Hier ist ein vollständiges Beispiel für ein Node Exporter DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
labels:
app: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
hostPID: true
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
containers:
- name: node-exporter
image: prom/node-exporter:v1.6.1
args:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/host/root'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
- '--web.listen-address=:9100'
ports:
- containerPort: 9100
protocol: TCP
name: metrics
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
- name: root
mountPath: /host/root
mountPropagation: HostToContainer
readOnly: true
securityContext:
runAsNonRoot: true
runAsUser: 65534
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: root
hostPath:
path: /
---
apiVersion: v1
kind: Service
metadata:
name: node-exporter
namespace: monitoring
labels:
app: node-exporter
spec:
type: ClusterIP
ports:
- port: 9100
targetPort: 9100
name: metrics
selector:
app: node-exporterapiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
endpoints:
- port: metrics
interval: 30s
path: /metricsspec:
template:
spec:
nodeSelector:
disktype: ssd
node-type: workerspec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
- key: node-role.kubernetes.io/worker
operator: Exists
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-zone
operator: In
values:
- zone-aspec:
template:
spec:
tolerations:
# Master/Control-Plane Nodes
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
# Custom Taints
- key: dedicated
operator: Equal
value: logging
effect: NoSchedule
# Tolerations für Node-Probleme
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
tolerationSeconds: 300spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1Verhalten: - Updates erfolgen Node für Node -
maxUnavailable begrenzt gleichzeitige Updates -
Gewährleistet kontinuierliche Service-Verfügbarkeit
spec:
updateStrategy:
type: OnDeleteAnwendung: - Manuelle Kontrolle über Update-Timing - Kritische Services mit speziellen Update-Anforderungen - Koordinierte Updates mit externen Systemen
spec:
template:
spec:
containers:
- name: system-collector
securityContext:
privileged: true
runAsUser: 0
volumeMounts:
- name: host-var-log
mountPath: /var/log
readOnly: true
- name: host-dev
mountPath: /dev
readOnly: true
volumes:
- name: host-var-log
hostPath:
path: /var/log
- name: host-dev
hostPath:
path: /devspec:
template:
spec:
hostNetwork: true
hostPID: true
dnsPolicy: ClusterFirstWithHostNetHinweis: Host-Network ermöglicht direkten Zugriff auf Node-Netzwerk, erfordert aber sorgfältige Port-Verwaltung.
kubectl get daemonset -n monitoring
kubectl describe daemonset node-exporter -n monitoringkubectl get pods -o wide -l app=node-exporter
kubectl get nodes --show-labels# Alle Nodes
kubectl get nodes --no-headers | wc -l
# DaemonSet Pods
kubectl get pods -l app=node-exporter --no-headers | wc -l
# Fehlende Pods identifizieren
kubectl get pods -l app=node-exporter -o wide | \
awk '{print $7}' | sort | uniq > /tmp/nodes-with-pods
kubectl get nodes --no-headers | \
awk '{print $1}' | sort > /tmp/all-nodes
diff /tmp/all-nodes /tmp/nodes-with-podsresources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100MiWichtig: Resource Limits verhindern, dass ein DaemonSet-Pod einen Node destabilisiert.
livenessProbe:
httpGet:
path: /metrics
port: 9100
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /metrics
port: 9100
initialDelaySeconds: 5
periodSeconds: 5securityContext:
runAsNonRoot: true
runAsUser: 65534
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE # Nur wenn erforderlichapiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: node-exporter-pdb
spec:
minAvailable: 80%
selector:
matchLabels:
app: node-exporterHinweis: PDBs sind für DaemonSets besonders wichtig, da sie kritische Node-Services schützen.
Symptom: DaemonSet-Pods fehlen auf einzelnen Nodes
Diagnose:
kubectl describe node <node-name>
kubectl get events --field-selector involvedObject.name=<pod-name>Häufige Ursachen und Lösungen: - Node Taints: Tolerations hinzufügen oder Node un-tainting - Resource Constraints: Node-Kapazitäten und Resource Requests prüfen - Node Selectors: Label-Matching überprüfen - Image Pull Issues: Registry-Zugriff und Image-Verfügbarkeit validieren
Symptom: Node-Performance degradiert nach DaemonSet-Deployment
Diagnose:
kubectl top nodes
kubectl top pods -l app=<daemonset-name>Lösungsansätze: - Resource Limits reduzieren - CPU/Memory Requests optimieren - Sampling-Intervalle anpassen - I/O-intensive Operationen begrenzen
Symptom: Rolling Update hängt oder schlägt fehl
Diagnose:
kubectl rollout status daemonset/<name>
kubectl describe daemonset <name>Troubleshooting: - Pod-Readiness überprüfen - Health
Check Timeouts anpassen - maxUnavailable Parameter
optimieren - Node-Kapazitäten während Updates überwachen
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: node-exporter-netpol
spec:
podSelector:
matchLabels:
app: node-exporter
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9100
egress:
- {} # Ausgehender Traffic erlaubtapiVersion: v1
kind: SecurityContext
metadata:
name: restricted-scc
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALLapiVersion: v1
kind: ServiceAccount
metadata:
name: node-exporter
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-exporter
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/metrics"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-exporter
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: node-exporter
subjects:
- kind: ServiceAccount
name: node-exporter
namespace: monitoringspec:
template:
spec:
initContainers:
- name: node-setup
image: alpine:3.18
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
securityContext:
privileged: true
volumeMounts:
- name: host-sys
mountPath: /host/sys
containers:
- name: main-app
# ... Hauptcontainer-Konfigurationspec:
template:
spec:
containers:
- name: log-collector
image: fluentd:v1.16
volumeMounts:
- name: host-logs
mountPath: /var/log
- name: metrics-exporter
image: node-exporter:latest
ports:
- containerPort: 9100
volumes:
- name: host-logs
hostPath:
path: /var/logapiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
format json
</source>
---
spec:
template:
spec:
containers:
- name: fluentd
volumeMounts:
- name: config
mountPath: /fluentd/etc
volumes:
- name: config
configMap:
name: fluentd-configresources:
requests:
cpu: 50m # Niedrige Baseline
memory: 64Mi
limits:
cpu: 200m # Burst-Kapazität
memory: 128MivolumeMounts:
- name: host-logs
mountPath: /var/log
readOnly: true # Read-only wenn möglich
- name: tmp-storage
mountPath: /tmp
volumes:
- name: tmp-storage
emptyDir:
sizeLimit: 1Gi # Begrenzte temporäre Speicherspec:
template:
spec:
hostNetwork: false # Vermeiden wenn nicht erforderlich
dnsPolicy: ClusterFirst # Optimierte DNS-Auflösung