บทนำเกี่ยวกับ 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) เพื่อตรวจจับปัญหากระเร็วขึ้น
