Kubernetes Troubleshooting Guide แก้ปัญหาที่พบบ่อยบน Cloud VPS

บทนำเกี่ยวกับ Kubernetes Troubleshooting

Kubernetes (K8s) เป็นแพลตฟอร์มการแบ่งส่วนเก่า (Container Orchestration) ที่มีประสิทธิภาพสูง แต่เมื่อใช้งาน Pod และ Service อาจพบปัญหาต่างๆ เช่น CrashLoopBackOff, ImagePullBackOff, OOMKilled และอื่นๆ บทความนี้จะเป็นคู่มือสำหรับแก้ปัญหา K8s ที่พบบ่อยบน Cloud VPS ของ ผู้ให้บริการโฮสติ้ง พร้อมด้วย Debug Commands ที่สำคัญ

Debug Commands พื้นฐานสำหรับ Kubernetes Troubleshooting

ก่อนเริ่มแก้ปัญหา ต้องรู้จัก Kubectl Commands ที่สำคัญเพื่อดำเนินการ Debug:

# ดูสถานะของทุก Pods
kubectl get pods -A

# ดูรายละเอียด Pod ที่มีปัญหา
kubectl describe pod <pod-name> -n <namespace>

# ดูค่า Logs ของ Pod
kubectl logs <pod-name> -n <namespace>

# ติดตามการเปลี่ยนแปลง Logs แบบ Real-time
kubectl logs -f <pod-name> -n <namespace>

# เข้าสู่ Container เพื่อ Debug
kubectl exec -it <pod-name> -n <namespace> -- /bin/bash

# ดูเหตุการณ์ในคลัสเตอร์
kubectl get events -n <namespace>

# ดูทรัพยากรการใช้งาน
kubectl top nodes
kubectl top pods -n <namespace>

CrashLoopBackOff: Pod เริ่มต้นแล้วหยุด ซ้ำๆ

CrashLoopBackOff เกิดขึ้นเมื่อ Container ไม่สามารถเริ่มต้นหรือหยุดทำงานอย่างผิดพลาด

สาเหตุทั่วไป:

  • Application Crash เนื่องจากข้อผิดพลาด Code
  • Dependency ที่ขาดหาย (Library, Database)
  • Environment Variables ไม่ถูกต้อง
  • File Permissions หรือ Volume Issues

วิธีแก้ปัญหา:

# ดูเหตุการณ์และ Error Log
kubectl describe pod <pod-name> -n <namespace>

# ดู Logs เพื่อหา Error Message
kubectl logs <pod-name> -n <namespace>

# ดู Previous Logs ก่อนที่จะ Crash
kubectl logs <pod-name> -n <namespace> --previous

# แก้ไข Deployment YAML และใช้ Apply
kubectl apply -f deployment.yaml

# Rollback ถ้าหากแก้ไขล่าสุดมีปัญหา
kubectl rollout undo deployment/<deployment-name> -n <namespace>

ImagePullBackOff / ErrImagePull: ปัญหาการดึง Image

ข้อผิดพลาดนี้เกิดขึ้นเมื่อ Kubelet ไม่สามารถดึง Container Image จาก Registry

สาเหตุทั่วไป:

  • Image ไม่มีอยู่ใน Registry
  • Image Tag ไม่ถูกต้อง
  • ไม่มี Authentication สำหรับ Private Registry
  • Network Issues ไปยัง Registry

วิธีแก้ปัญหา:

# ตรวจสอบ Image ที่ใช้งาน
kubectl describe pod <pod-name> -n <namespace> | grep -i image

# สร้าง Secret สำหรับ Private Registry
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=<username> \
  --docker-password=<password> \
  [email protected] \
  -n <namespace>

# ใส่ imagePullSecrets ใน Pod Spec
# imagePullSecrets:
# - name: regcred

# Test Image Pulling
docker pull <image-name>:<tag>

Pending Pod: Pod ยังค่อยรอตั้งแต่เดิม

Pod ที่มีสถานะ Pending หมายถึง Pod ยังไม่ได้ถูก Schedule ไปยัง Node

สาเหตุทั่วไป:

  • Insufficient Resources (CPU, Memory) บน Node
  • Node Selector ไม่ตรงกับ Node ใด
  • Resource Quota เกินจำนวนที่กำหนด
  • Pod Affinity หรือ Anti-affinity ไม่ตรงกัน

วิธีแก้ปัญหา:

# ดูรายละเอียดเหตุที่ Pending
kubectl describe pod <pod-name> -n <namespace>

# ดูทรัพยากรที่มีอยู่บน Node
kubectl describe node <node-name>

# ดูทรัพยากรที่ใช้ไป
kubectl top nodes
kubectl top pods -n <namespace>

# ปรับลด Resource Request/Limit
# resources:
#   requests:
#     memory: "64Mi"
#     cpu: "100m"
#   limits:
#     memory: "128Mi"
#     cpu: "200m"

# Scale up Node หรือเพิ่ม Node ใหม่
kubectl scale node --replicas=3 <node-pool>

OOMKilled: Out of Memory Killed

Pod ถูกยุติเพราะใช้ Memory มากเกินจำนวน Memory Limit ที่กำหนด

สาเหตุทั่วไป:

  • Application Memory Leak
  • Memory Limit ต่ำเกินไป
  • Data Processing ขนาดใหญ่
  • Cache ที่ไม่ถูกปล่อยออก

วิธีแก้ปัญหา:

# ตรวจสอบทรัพยากร Memory
kubectl describe pod <pod-name> -n <namespace>

# ดู Memory Usage ของ Pod
kubectl top pods -n <namespace>

# เพิ่ม Memory Limit
# resources:
#   limits:
#     memory: "512Mi"
#   requests:
#     memory: "256Mi"

# ดู Memory Leak ผ่าน Logs
kubectl logs <pod-name> -n <namespace> | grep -i memory

# ใช้ JVM Options สำหรับ Java Applications
# env:
# - name: JAVA_OPTS
#   value: "-Xmx256m -Xms128m"

Pod Network Issues: ปัญหาการเชื่อมต่อ Network

Pod ไม่สามารถติดต่อกับ Pod อื่นหรือ External Services

สาเหตุทั่วไป:

  • Network Policy ขัดขวาง Traffic
  • DNS Resolution ล้มเหลว
  • Service Ports ไม่ถูกต้อง
  • Pod IP ที่ขัดแย้ง

วิธีแก้ปัญหา:

# ทดสอบ DNS Resolution
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <service-name>.<namespace>.svc.cluster.local

# ทดสอบ Connectivity
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -O- http://<service-name>:<port>

# ตรวจสอบ Network Policy
kubectl get networkpolicies -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>

# ลบ Network Policy ถ้ารบกวน
kubectl delete networkpolicy <policy-name> -n <namespace>

# เข้าสู่ Pod และ Test Connection
kubectl exec -it <pod-name> -n <namespace> -- sh
# curl http://<service>:<port>

Service ไม่ตอบสนอง

Service ที่สร้างไว้ไม่สามารถเข้าถึงได้ หรือ Port ไม่เปิด

วิธีแก้ปัญหา:

# ตรวจสอบ Service
kubectl get svc -n <namespace>
kubectl describe svc <service-name> -n <namespace>

# ตรวจสอบ Endpoints ของ Service
kubectl get endpoints -n <namespace>

# Test Service ผ่าน Port Forward
kubectl port-forward svc/<service-name> 8080:80 -n <namespace>

# ตรวจสอบ Labels บน Pod
kubectl get pods --show-labels -n <namespace>

# Selector ของ Service ต้องตรงกับ Labels ของ Pod

PVC Pending: Persistent Volume Claim ไม่ได้รับการผูกมัด

PVC ไม่สามารถผูกมัดกับ PV (Persistent Volume)

วิธีแก้ปัญหา:

# ตรวจสอบ PVC
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>

# ตรวจสอบ PV ที่มีอยู่
kubectl get pv
kubectl describe pv <pv-name>

# สร้าง PV ใหม่ถ้าจำเป็น
kubectl apply -f pv.yaml

# ตรวจสอบ Storage Class
kubectl get storageclass
kubectl describe storageclass <storage-class>

Node Not Ready

Node ไม่สามารถใช้งานได้ (Not Ready Status)

วิธีแก้ปัญหา:

# ตรวจสอบสถานะ Node
kubectl get nodes
kubectl describe node <node-name>

# ดู Kubelet Logs
sudo journalctl -u kubelet -n 50

# ตรวจสอบ Disk Space
df -h /var/lib/kubelet

# Drain Node เพื่อ Evict Pods
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# ปรับใช้ Node ใหม่ (Uncordon)
kubectl uncordon <node-name>

# Restart Kubelet
sudo systemctl restart kubelet

Ingress ไม่ทำงาน

Ingress ไม่สามารถส่งต่อ Traffic ไปยัง Backend Services

วิธีแก้ปัญหา:

# ตรวจสอบ Ingress
kubectl get ingress -n <namespace>
kubectl describe ingress <ingress-name> -n <namespace>

# ตรวจสอบ Ingress Controller
kubectl get pods -n ingress-nginx

# ดู Ingress Logs
kubectl logs -n ingress-nginx <ingress-pod>

# ตรวจสอบ DNS Lookup
nslookup <hostname>

# Test Backend Service ก่อน Ingress
kubectl exec -it <pod> -n <namespace> -- curl -I http://<service>:<port>

Quick Reference Troubleshooting Table

ปัญหา สาเหตุหลัก วิธีแก้ (Debug Command)
CrashLoopBackOff Application Error kubectl logs --previous, kubectl logs -f
ImagePullBackOff Image Not Found / Auth kubectl describe pod, Create Secret
Pending Insufficient Resources kubectl top nodes/pods, Adjust Resources
OOMKilled Memory Limit Exceeded kubectl top pods, Increase Memory Limit
Network Error Network Policy / DNS nslookup, kubectl exec -- curl
Node Not Ready Kubelet Issues kubectl describe node, Restart Kubelet

สรุป

การแก้ปัญหา Kubernetes ต้องอาศัยการสังเกตอย่างรอบคอบและการใช้ Kubectl Commands ที่ถูกต้อง บทความนี้ได้นำเสนอวิธีแก้ปัญหาที่พบบ่อยบน Cloud VPS รวมถึง CrashLoopBackOff, ImagePullBackOff, Pending, OOMKilled และ Network Issues

หากต้องการใช้บริการ Cloud VPS ของ ผู้ให้บริการโฮสติ้ง ที่มี Kubernetes Support พร้อมด้วย Technical Support ที่ดี ลองติดต่อเราได้เลย เทีมงานของเรายินดีช่วยเหลือ

เคล็ดลับสำคัญ: ให้สร้าง Monitoring และ Logging System (ELK Stack, Prometheus, Grafana) เพื่อตรวจจับปัญหากระเร็วขึ้น