Home > Blog > tech

DaemonSet และ StatefulSet คืออะไร? K8s Workloads นอกจาก Deployment 2026

kubernetes daemonset statefulset guide
DaemonSet StatefulSet Kubernetes Guide 2026
2026-04-16 | tech | 3500 words

เมื่อพูดถึง Kubernetes Workloads คนส่วนใหญ่คิดถึง Deployment เท่านั้น แต่ Kubernetes มี Workload Controllers อีกหลายตัวที่ออกแบบมาสำหรับ Use Cases ที่ต่างกัน โดยเฉพาะ DaemonSet และ StatefulSet ที่เป็น Workloads สำคัญที่ทุก K8s Admin ต้องรู้

K8s Workload Types ทั้งหมด

Workload TypeUse Caseตัวอย่าง
DeploymentStateless apps ที่ Scale ได้Web Server, API Server, Microservices
DaemonSetรัน 1 Pod ต่อ 1 NodeLog Collector, Monitoring Agent, Network Plugin
StatefulSetStateful apps ที่ต้องการ Persistent IdentityDatabase, Kafka, ZooKeeper, Redis Cluster
Jobรันงานครั้งเดียวแล้วจบBatch Processing, Migration, Backup
CronJobรันงานตาม ScheduleDaily Report, Cleanup, Scheduled Backup
ReplicaSet(ใช้ผ่าน Deployment)ไม่ค่อยสร้างตรงๆ

DaemonSet — 1 Pod ต่อ 1 Node

DaemonSet คืออะไร?

DaemonSet คือ Workload Controller ที่รับประกันว่าจะมี Pod รันอยู่บน ทุก Node (หรือ Subset ของ Node) เมื่อมี Node ใหม่เข้ามาใน Cluster จะถูกสร้าง Pod ให้อัตโนมัติ เมื่อ Node ถูกลบออก Pod จะถูกลบด้วย

DaemonSet Use Cases

Use Caseตัวอย่าง Softwareทำไมต้อง DaemonSet
Log CollectionFluentd, Fluent Bit, Filebeatต้องจับ Log จากทุก Node
MonitoringNode Exporter, Datadog Agentต้องเก็บ Metrics จากทุก Node
NetworkingCilium, Calico, kube-proxyNetwork Plugin ต้องรันบนทุก Node
StorageCSI Node DriverStorage Driver ต้องรันบนทุก Node
SecurityFalco, Aqua, TwistlockSecurity Agent ต้อง Monitor ทุก Node

DaemonSet YAML ตัวอย่าง: Fluentd

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.16
        resources:
          limits:
            memory: 200Mi
            cpu: 100m
          requests:
            memory: 100Mi
            cpu: 50m
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers

DaemonSet Update Strategy

Strategyพฤติกรรมเมื่อไรใช้
RollingUpdate (Default)ลบ Pod เก่าแล้วสร้างใหม่ทีละ Nodeทั่วไป ปลอดภัย
OnDeleteอัพเดทเมื่อ Pod ถูกลบด้วยตนเองต้องการควบคุม Rollout เอง
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1  # อัพเดททีละ 1 Node

Tolerations — รัน DaemonSet บน Control Plane

ปกติ K8s จะไม่ Schedule Pod บน Control Plane Node (Master) ถ้าต้องการให้ DaemonSet รันบน Master ด้วย ต้องเพิ่ม Tolerations:

spec:
  template:
    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule

StatefulSet — Ordered, Persistent Identity

StatefulSet คืออะไร?

StatefulSet คือ Workload Controller สำหรับ Applications ที่ต้องการ:

StatefulSet Use Cases

Use Caseตัวอย่างทำไมต้อง StatefulSet
DatabasesPostgreSQL, MySQL, MongoDBต้องการ Persistent Storage + Stable Identity
Message QueuesKafka, RabbitMQต้องการ Ordered Deployment + Persistent Data
Coordination ServicesZooKeeper, etcdต้องรู้ว่าใครคือ Leader ใครคือ Follower
Cache ClustersRedis Clusterแต่ละ Node เก็บ Shard ต่างกัน
Search EnginesElasticsearchแต่ละ Node เก็บ Index Shard ต่างกัน

StatefulSet YAML ตัวอย่าง: PostgreSQL

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres-headless  # ต้องชี้ไป Headless Service
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: postgres-data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:   # แต่ละ Pod ได้ PVC ของตัวเอง!
  - metadata:
      name: postgres-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard
      resources:
        requests:
          storage: 10Gi

Headless Service สำหรับ StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: postgres-headless
spec:
  clusterIP: None  # Headless! ไม่มี ClusterIP
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

# DNS Records ที่ได้:
# postgres-0.postgres-headless.default.svc.cluster.local
# postgres-1.postgres-headless.default.svc.cluster.local
# postgres-2.postgres-headless.default.svc.cluster.local
Headless Service: ตั้ง clusterIP: None ทำให้แต่ละ Pod มี DNS Record ของตัวเอง Application สามารถเชื่อมต่อหา Pod ที่ต้องการโดยตรง เช่น Primary Database ที่ pod-0

volumeClaimTemplates — PVC อัตโนมัติ

เมื่อ StatefulSet สร้าง Pod ใหม่ จะสร้าง PersistentVolumeClaim (PVC) ให้อัตโนมัติตาม Template:

เมื่อ Pod ถูก Restart หรือ Reschedule ไป Node อื่น PVC ยังคงอยู่ ข้อมูลไม่หาย

Ordered Pod Management

# สร้างตามลำดับ:
# postgres-0 → Ready → postgres-1 → Ready → postgres-2
# ลบย้อนกลับ:
# postgres-2 → Terminated → postgres-1 → Terminated → postgres-0

# ถ้าต้องการ Parallel (ไม่รอลำดับ):
spec:
  podManagementPolicy: Parallel  # Default คือ OrderedReady

StatefulSet Scaling

# Scale Up (เพิ่ม Pod ตามลำดับ)
kubectl scale statefulset postgres --replicas=5

# Scale Down (ลบ Pod จากท้ายก่อน)
kubectl scale statefulset postgres --replicas=2
# ลบ postgres-4 → postgres-3 → postgres-2

# ⚠️ Scale Down ไม่ลบ PVC!
# ต้องลบ PVC ด้วยตนเองถ้าไม่ต้องการ
kubectl delete pvc postgres-data-postgres-4
kubectl delete pvc postgres-data-postgres-3
kubectl delete pvc postgres-data-postgres-2

StatefulSet vs Deployment สำหรับ Databases

เปรียบเทียบDeploymentStatefulSet
Pod NameRandom (app-7b4d6f-xyz)Ordered (app-0, app-1, app-2)
StorageShared หรือ Ephemeralแต่ละ Pod มี PVC ของตัวเอง
DNSผ่าน Service (Load Balanced)แต่ละ Pod มี DNS ของตัวเอง
ScalingScale Up/Down ไม่มีลำดับScale ตามลำดับ
Rolling Updateสร้างใหม่ก่อน ลบเก่าทีหลังลบเก่า → สร้างใหม่ ตามลำดับ (ย้อน)
เหมาะกับ DB?ไม่เหมาะ (ข้อมูลหาย)เหมาะ (ข้อมูลคงอยู่)

Operators — ทางเลือกที่ดีกว่า StatefulSet สำหรับ DB

ในปี 2026 การรัน Database บน K8s ด้วย StatefulSet ตรง ๆ ยังคงยุ่งยาก ทางเลือกที่ดีกว่าคือใช้ Operators ที่ออกแบบมาเฉพาะสำหรับแต่ละ Database:

DatabaseOperatorจัดการอะไรให้
PostgreSQLCloudNativePG, Zalando Postgres OperatorHA, Backup, Failover, Connection Pooling
MySQLMySQL Operator (Oracle), VitessInnoDB Cluster, Backup, Scaling
MongoDBMongoDB Community OperatorReplicaSet, Sharding, Backup
KafkaStrimziBroker Management, Topic, User, Connect
RedisRedis Operator (Spotahome)Sentinel, Cluster, Failover
ElasticsearchECK (Elastic Cloud on K8s)Cluster, Kibana, APM, Beats

สรุป: เลือก Workload Type ไหนดี?

ต้องการใช้
Stateless App ที่ Scale ได้Deployment
รัน Agent/Daemon บนทุก NodeDaemonSet
Database/Stateful App ที่ต้อง Persistent StorageStatefulSet (หรือ Operator)
งาน Batch ครั้งเดียวJob
งาน Batch ตาม ScheduleCronJob

DaemonSet และ StatefulSet เป็น Workload Controllers ที่สำคัญมากใน K8s ที่ช่วยแก้ปัญหาที่ Deployment ทำไม่ได้ ทำความเข้าใจทั้งสองตัวจะช่วยให้ออกแบบ K8s Architecture ได้ดีขึ้น และรันงานได้หลากหลายมากขึ้น


Back to Blog | iCafe Forex | SiamLanCard | Siam2R