Home > Blog > tech

Kubernetes Resource Management คืออะไร? สอนจัดการ CPU Memory Requests Limits 2026

kubernetes resource management guide
Kubernetes Resource Management Guide 2026
2026-04-16 | tech | 3600 words

ใน Kubernetes การจัดการ Resource (CPU และ Memory) เป็นหนึ่งในสิ่งที่สำคัญที่สุดแต่มักถูกมองข้าม การตั้ง Requests/Limits ที่ไม่ถูกต้องอาจทำให้ Pod ถูก OOMKilled, CPU Throttled, Scheduling ล้มเหลว หรือเสีย Cloud Cost มากเกินจำเป็น

ทำไม Resource Management ถึงสำคัญ?

Requests vs Limits

คุณสมบัติRequestsLimits
ความหมายจำนวน Resource ขั้นต่ำที่ Pod ต้องการจำนวน Resource สูงสุดที่ Pod ใช้ได้
Schedulingใช้ตัดสินใจว่า Pod ไปรันบน Node ไหนไม่ใช้ในการ Scheduling
ถ้าเกินPod ยังใช้ได้มากกว่า Requests (ถ้า Node มี Resource ว่าง)CPU: Throttled, Memory: OOMKilled
แนะนำตั้งเสมอ!ตั้ง Memory Limit เสมอ, CPU Limit ขึ้นอยู่กับกรณี
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:v1
    resources:
      requests:          # ขั้นต่ำที่ต้องการ (Scheduling)
        cpu: "250m"      # 250 millicores = 0.25 CPU core
        memory: "256Mi"  # 256 Mebibytes
      limits:            # สูงสุดที่ใช้ได้
        cpu: "500m"      # 500 millicores = 0.5 CPU core
        memory: "512Mi"  # 512 Mebibytes

CPU Units — Millicores

# CPU Units ใน Kubernetes
# 1 CPU = 1 vCPU = 1 Core = 1000m (millicores)
#
# ตัวอย่าง:
# "100m" = 0.1 CPU = 10% ของ 1 Core
# "250m" = 0.25 CPU = 25% ของ 1 Core
# "500m" = 0.5 CPU = 50% ของ 1 Core
# "1" = 1 CPU = 100% ของ 1 Core
# "2" = 2 CPU = 200% (ใช้ 2 Cores)
#
# ⚡ CPU เป็น Compressible Resource:
# ถ้า Pod ใช้ CPU เกิน Limit → Throttled (ช้าลง แต่ไม่ตาย)
# ถ้า Pod ใช้ CPU เกิน Requests แต่ไม่เกิน Limit → ใช้ได้ถ้า Node มี CPU ว่าง

Memory Units — Mi/Gi

# Memory Units ใน Kubernetes
# Ki = Kibibyte (1024 bytes)
# Mi = Mebibyte (1024 Ki = 1,048,576 bytes)
# Gi = Gibibyte (1024 Mi = 1,073,741,824 bytes)
#
# ตัวอย่าง:
# "128Mi" = 128 MB = เหมาะ Sidecar/Init Container
# "256Mi" = 256 MB = App เล็ก
# "512Mi" = 512 MB = App ปานกลาง
# "1Gi" = 1 GB = App ใหญ่
# "4Gi" = 4 GB = Database/Cache
#
# ⚠️ Memory เป็น Incompressible Resource:
# ถ้า Pod ใช้ Memory เกิน Limit → OOMKilled ทันที!
# ไม่มีการ Throttle สำหรับ Memory

QoS Classes — ระดับคุณภาพบริการ

Kubernetes กำหนด QoS Class โดยอัตโนมัติจาก Requests/Limits ที่คุณตั้ง:

QoS Classเงื่อนไขถูก Evict ลำดับเหมาะกับ
Guaranteedทุก Container: Requests = Limits (ทั้ง CPU + Memory)สุดท้าย (ปลอดภัยที่สุด)Production Critical Apps
Burstableมี Requests แต่ Requests != LimitsกลางApp ทั่วไป
BestEffortไม่มี Requests และ Limits เลยแรก (ถูกไล่ก่อน)ไม่ควรใช้ใน Production
# Guaranteed (ปลอดภัยสุด)
resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
  limits:
    cpu: "500m"       # เท่ากับ Requests
    memory: "512Mi"   # เท่ากับ Requests

# Burstable (ยืดหยุ่น)
resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    cpu: "500m"       # สูงกว่า Requests
    memory: "512Mi"   # สูงกว่า Requests

# BestEffort (ไม่แนะนำ)
# ไม่ตั้ง resources เลย

LimitRange — Default per Namespace

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: production
spec:
  limits:
  - type: Container
    default:          # Default Limits (ถ้า Pod ไม่ได้ตั้ง)
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:   # Default Requests (ถ้า Pod ไม่ได้ตั้ง)
      cpu: "100m"
      memory: "128Mi"
    max:              # Limit สูงสุดที่ตั้งได้
      cpu: "2"
      memory: "4Gi"
    min:              # Limit ต่ำสุดที่ตั้งได้
      cpu: "50m"
      memory: "64Mi"
  - type: Pod
    max:
      cpu: "4"
      memory: "8Gi"

ResourceQuota — Total per Namespace

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"         # รวม CPU Requests ทั้ง Namespace ไม่เกิน 10 Cores
    requests.memory: "20Gi"    # รวม Memory Requests ไม่เกิน 20 Gi
    limits.cpu: "20"           # รวม CPU Limits ไม่เกิน 20 Cores
    limits.memory: "40Gi"      # รวม Memory Limits ไม่เกิน 40 Gi
    pods: "50"                 # จำนวน Pod สูงสุด 50

# ดู Quota Usage
# kubectl describe resourcequota compute-quota -n production

VPA — Vertical Pod Autoscaler

VPA ปรับ Requests/Limits ของ Pod อัตโนมัติตามการใช้งานจริง ช่วย Right-sizing ไม่ต้องเดาเอง

# ติดตั้ง VPA
# kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/.../vpa.yaml

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Auto"    # Auto = ปรับอัตโนมัติ, Off = แค่ Recommend
  resourcePolicy:
    containerPolicies:
    - containerName: '*'
      minAllowed:
        cpu: "50m"
        memory: "64Mi"
      maxAllowed:
        cpu: "2"
        memory: "4Gi"
      controlledResources: ["cpu", "memory"]

# ดู Recommendations
# kubectl describe vpa my-app-vpa

Goldilocks — Right-Sizing Recommendations

# Goldilocks = VPA + Dashboard
# ติดตั้งด้วย Helm:
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install goldilocks fairwinds-stable/goldilocks --namespace goldilocks --create-namespace

# Enable ใน Namespace ที่ต้องการ
kubectl label namespace production goldilocks.fairwinds.com/enabled=true

# เปิด Dashboard
kubectl port-forward svc/goldilocks-dashboard -n goldilocks 8080:80
# → http://localhost:8080
# ดู Recommended Requests/Limits สำหรับทุก Deployment

Monitoring Resource Usage

# kubectl top — ดูการใช้ Resource แบบ Real-time
kubectl top nodes                          # ดู Resource Usage ของ Nodes
kubectl top pods -n production             # ดู Resource Usage ของ Pods
kubectl top pods --sort-by=memory          # Sort by Memory Usage
kubectl top pods --sort-by=cpu             # Sort by CPU Usage

# ดู Resource ที่ตั้งไว้
kubectl describe pod my-app-pod | grep -A 5 "Requests\|Limits"

# ดู Node Resources
kubectl describe node worker-1 | grep -A 10 "Allocated resources"

# Prometheus Queries (PromQL)
# CPU Usage vs Requests:
# container_cpu_usage_seconds_total / container_spec_cpu_quota
#
# Memory Usage vs Limits:
# container_memory_working_set_bytes / container_spec_memory_limit_bytes
#
# OOMKilled Events:
# kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}

OOMKilled Troubleshooting

สาเหตุอาการวิธีแก้
Memory Limit ต่ำเกินไปPod Restart บ่อย, Exit Code 137เพิ่ม Memory Limit (ดูจาก Monitoring)
Memory Leak ใน AppMemory ค่อย ๆ สูงขึ้นจน OOMKilledFix Memory Leak ใน App Code
Java Heap SizeJVM ใช้ Memory เกิน Container Limitตั้ง -Xmx ให้น้อยกว่า Container Limit 20-30%
ไม่ตั้ง LimitPod ใช้ Memory จน Node OOMตั้ง Memory Limit ทุก Pod
# ตรวจสอบ OOMKilled
kubectl get pods | grep -i oomkill
kubectl describe pod my-app-pod | grep -i oom
kubectl get events --field-selector reason=OOMKilling

# ดู Exit Code
kubectl get pod my-app-pod -o jsonpath='{.status.containerStatuses[0].lastState}'
# Exit Code 137 = OOMKilled

CPU Throttling Detection

# CPU Throttling เกิดเมื่อ Pod ใช้ CPU เกิน Limit
# อาการ: App ช้าลง, Latency สูงขึ้น, แต่ Pod ไม่ Restart

# ตรวจด้วย cAdvisor Metrics (Prometheus):
# container_cpu_cfs_throttled_seconds_total
# container_cpu_cfs_throttled_periods_total / container_cpu_cfs_periods_total

# ถ้า Throttle Rate > 25% = มีปัญหา
# วิธีแก้:
# 1. เพิ่ม CPU Limit
# 2. ลบ CPU Limit ออก (ใช้แค่ Requests) — บาง Best Practice แนะนำ
# 3. Optimize App ให้ใช้ CPU น้อยลง

Resource Management Best Practices

Practiceทำไม
ตั้ง Requests ทุก ContainerScheduler ต้องใช้ข้อมูลนี้ ไม่มี = Scheduling ไม่มีประสิทธิภาพ
ตั้ง Memory Limits ทุก Containerป้องกัน Memory Leak ทำ Node OOM
CPU Limits: พิจารณาเป็นกรณีบาง Workload ดีกว่าไม่ตั้ง CPU Limit (หลีกเลี่ยง Throttling)
ใช้ LimitRangeกันไม่ให้ Pod deploy โดยไม่ตั้ง Resources
ใช้ ResourceQuotaจำกัด Resource รวมต่อ Namespace ป้องกัน Namespace หนึ่งกิน Resource หมด
ใช้ VPA หรือ GoldilocksRight-sizing อัตโนมัติ ไม่ต้องเดา
Monitor อย่างต่อเนื่องkubectl top, Prometheus + Grafana Dashboard
Requests = Usage + Buffer 20-30%ให้ Room สำหรับ Spike แต่ไม่สูงเกินไป

Cost Optimization — ลดค่า Cloud ด้วย Right-Sizing

# ปัญหาที่พบบ่อย:
# Requests สูงเกินจริง → จอง Resource เปลือง → Cloud Bill สูง
#
# ตัวอย่าง:
# Deployment: 10 Pods, Requests: CPU 1000m, Memory 2Gi
# จอง: 10 CPU + 20Gi Memory
#
# การใช้จริง (จาก Monitoring):
# CPU เฉลี่ย: 200m, Memory เฉลี่ย: 500Mi
# จอง: 10 x 200m = 2 CPU + 10 x 500Mi = 5Gi
#
# สิ้นเปลือง: 8 CPU + 15Gi Memory!
# ถ้า Cloud ราคา $0.05/CPU/hr + $0.007/GB/hr:
# สิ้นเปลือง/เดือน = (8 x 0.05 + 15 x 0.007) x 720 = $363.6/เดือน!
#
# Right-Sizing:
# Requests: CPU 300m (usage + 50% buffer), Memory 750Mi
# ประหยัด ~70% ของ Resource จอง!
เคล็ดลับ: ใช้ Goldilocks ดู Recommended Requests/Limits สำหรับทุก Deployment แล้ว Right-size ทั้ง Cluster สามารถลดค่า Cloud ได้ 30-70%

สรุป: Resource Management Checklist

ลำดับงาน
1ตั้ง Requests + Limits ทุก Container (อย่างน้อย Memory Limit)
2สร้าง LimitRange ทุก Namespace (Default Resources)
3สร้าง ResourceQuota สำหรับ Production Namespace
4ติดตั้ง Metrics Server + Prometheus + Grafana
5Monitor Resource Usage อย่างสม่ำเสมอ
6ติดตั้ง VPA หรือ Goldilocks เพื่อ Right-sizing
7ตรวจ OOMKilled + CPU Throttling Events
8Right-size ทุก Quarter เพื่อ Cost Optimization

Kubernetes Resource Management ไม่ซับซ้อน แต่ต้องทำอย่างจริงจัง ตั้ง Requests/Limits ให้ถูกต้อง Monitor อย่างต่อเนื่อง Right-size เป็นประจำ แค่นี้ Cluster ของคุณจะเสถียร ประหยัด และ Scale ได้อย่างมีประสิทธิภาพ


Back to Blog | iCafe Forex | SiamLanCard | Siam2R