Kubernetes

รวม Log จากทุก Pod ด้วย EFK Stack บน K8s

เผยแพร่ · แก้ไขล่าสุด

ระบบเก็บบันทึก (Logging) แบบรวมศูนย์บน Kubernetes

เมื่อทำงานกับ Kubernetes ที่มี Pod จำนวนมาย การมองหาข้อมูล log จากแต่ละ Pod จะเป็นงานที่ยุ่งยากและใช้เวลานาน วิธีแก้ปัญหาคือการใช้ระบบเก็บบันทึกแบบรวมศูนย์ (Centralized Logging) โดยใช้ EFK Stack ซึ่งประกอบด้วย Elasticsearch, Fluentd, และ Kibana

ส่วนประกอบของ EFK Stack

Elasticsearch: เป็นฐานข้อมูล (Search Engine) ที่ใช้เก็บข้อมูล log และอนุญาตให้ค้นหาข้อมูล log ได้อย่างรวดเร็ว

Fluentd: เป็นระบบเก็บรวบรวมข้อมูล log จากทุก Pod บน Kubernetes และส่งต่อไปยัง Elasticsearch

Kibana: เป็น Web Interface ที่ใช้สำหรับมองหา วิเคราะห์ และแสดงผลข้อมูล log ที่เก็บไว้ใน Elasticsearch

การติดตั้ง Elasticsearch บน Kubernetes

ใช้ Helm Chart เพื่อติดตั้ง Elasticsearch:

helm repo add elastic https://helm.elastic.co
helm repo update
helm install elasticsearch elastic/elasticsearch \
  --namespace logging \
  --create-namespace \
  --set replicas=3 \
  --set resources.requests.memory="512Mi" \
  --set resources.requests.cpu="250m"

การติดตั้ง Fluentd บน Kubernetes

Fluentd ต้องทำงานบน Node ทั้งหมด เพื่อเก็บรวบรวม log จากทุก Pod ใช้ DaemonSet เพื่อให้ Fluentd ทำงานบน Node แต่ละตัว:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      serviceAccount: fluentd
      serviceAccountName: fluentd
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch.logging.svc.cluster.local"
        - name: FLUENT_ELASTICSEARCH_PORT
          value: "9200"
        - name: FLUENT_UID
          value: "0"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

สร้าง ServiceAccount สำหรับ Fluentd

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluentd
rules:
- apiGroups: [""]
  resources:
  - pods
  - namespaces
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fluentd
roleRef:
  kind: ClusterRole
  name: fluentd
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: fluentd
  namespace: logging

การติดตั้ง Kibana

helm install kibana elastic/kibana \
  --namespace logging \
  --set elasticsearch.hosts[0]=elasticsearch.logging.svc.cluster.local \
  --set elasticsearch.port=9200 \
  --set service.type=LoadBalancer

การเข้าถึง Kibana

kubectl port-forward -n logging svc/kibana 5601:5601
# เข้าไปที่ http://localhost:5601

ตรวจสอบสถานะของ Elasticsearch

kubectl get pods -n logging
kubectl logs -n logging -l app=elasticsearch
kubectl port-forward -n logging svc/elasticsearch 9200:9200
curl http://localhost:9200/_cluster/health

ตรวจสอบสถานะของ Fluentd

kubectl get daemonset -n logging
kubectl logs -n logging daemonset/fluentd
kubectl describe daemonset -n logging fluentd

การกำหนดค่า Index Pattern ใน Kibana

1. เข้าไปที่ Kibana UI (http://localhost:5601)

2. คลิก "Stack Management" → "Index Patterns"

3. คลิก "Create index pattern"

4. ใส่ชื่อ pattern เช่น "logstash-*" หรือ "fluent-*"

5. เลือกเวลา (Time field) เป็น "@timestamp"

6. คลิก "Create index pattern"

การค้นหา Log ใน Kibana

ใช้ Kibana Query Language (KQL) เพื่อค้นหา log:

kubernetes.pod_name:"nginx*"
kubernetes.namespace_name:"default"
level:"ERROR"
@timestamp:["2026-03-01" TO "2026-03-31"]

ทำให้ Elasticsearch ทำงานแบบ High Availability

helm install elasticsearch elastic/elasticsearch \
  --namespace logging \
  --set replicas=3 \
  --set nodeGroup="master" \
  --set roles.master=true \
  --set roles.data=true \
  --set roles.ingest=true \
  --set persistence.enabled=true \
  --set persistence.size=30Gi

การตั้งค่า Retention Policy

กำหนดให้ Elasticsearch ลบ index เก่าโดยอัตโนมัติ:

curl -X PUT http://localhost:9200/_ilm/policy/logs_policy -H 'Content-Type: application/json' -d '{
  "policy": "logs_policy",
  "phases": {
    "hot": {
      "min_age": "0d",
      "actions": {
        "rollover": {
          "max_primary_shard_size": "50GB"
        }
      }
    },
    "warm": {
      "min_age": "7d",
      "actions": {
        "set_priority": {
          "priority": 50
        }
      }
    },
    "delete": {
      "min_age": "30d",
      "actions": {
        "delete": {}
      }
    }
  }
}'
  • การติดตั้ง Kubernetes บน Cloud VPS
  • Pod และ Service ใน Kubernetes
  • Persistent Volume สำหรับเก็บข้อมูล
  • การตรวจสอบ Kubernetes ด้วย Prometheus