API server ทำหน้าที่อะไร
API server = gateway เดียว ของทุกการสื่อสารใน K8s
ทุก action — kubectl, controller, kubelet, scheduler — ส่ง request ผ่าน API server และ API server เขียนเข้า etcd
kubectl ─→ API server ─→ etcd (data store)
↑
kubelet ─┘
controller-manager
scheduler
ถ้า API server ล่ม → ทุก component คุยกันไม่ได้
ผลกระทบเมื่อ API server ล่ม
✅ สิ่งที่ยังทำงานต่อ
- Pod ที่รันอยู่ — ยัง run ปกติ traffic ผ่าน Service ที่ kube-proxy ตั้ง iptables ไว้แล้ว
- Service routing — kube-proxy ใช้ rule ที่อยู่บน node ไม่ต้องถาม API server ทุก request
- Ingress controller — ไม่กระทบ ทำงานต่อ
- DNS resolution (CoreDNS) — ทำงานต่อด้วย config ที่ load ไว้
ผู้ใช้ปลายทางอาจไม่รู้สึกอะไร — ถ้า traffic ไปที่ pod ที่ healthy อยู่
❌ สิ่งที่หยุด
kubectlใช้ไม่ได้:Unable to connect to the server: dial tcp 10.0.0.1:6443: connect: connection refused- Deploy ใหม่ไม่ได้ — apply manifest ทำไม่ได้
- Auto-scale (HPA) — ไม่ทำงาน metric ส่งไม่ได้
- Pod ที่ตายไม่ replace — controller scaling ไม่ได้
- Liveness probe fail = restart pod — kubelet ตัดสินใจเอง (ทำงาน)
- แต่ — ถ้า node ตาย pod บน node ตายตามไปด้วย controller ไม่รู้ — ไม่ schedule pod ใหม่
- Secret/ConfigMap update — pod ใหม่อ่านไม่ได้
- kubelet renew lease — ถ้านานเกินไป — node ถูก mark NotReady
ตรวจสอบว่า API server ล่ม
$ kubectl get nodes
The connection to the server 10.0.0.1:6443 was refused
หรือ:
Error from server: etcdserver: request timed out
SSH เข้า master node:
sudo systemctl status kubelet
ps aux | grep kube-apiserver
sudo journalctl -u kubelet -n 100
ถ้า kube-apiserver เป็น static pod (kubeadm install):
sudo crictl ps -a | grep apiserver
sudo crictl logs <container-id>
สาเหตุที่เป็นไปได้
1. etcd ตอบไม่ทัน / ตาย
API server ต้อง เขียน etcd ทุก request — etcd ช้า/ตาย = API server hang
# บน master node
sudo systemctl status etcd # ถ้าเป็น systemd service
# หรือ
sudo crictl ps -a | grep etcd
sudo crictl logs <etcd-container>
ตรวจ etcd health:
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
endpoint health
ผลที่ดี:
https://127.0.0.1:2379 is healthy
ถ้า unhealthy — etcd มีปัญหา (disk เต็ม, quorum หาย ใน multi-master)
2. Disk เต็ม
API server / etcd ต้องเขียน disk
df -h /var/lib/etcd
df -h /var/log
ถ้าเต็ม:
# Compact etcd
sudo ETCDCTL_API=3 etcdctl ... compact <revision>
# Defrag
sudo ETCDCTL_API=3 etcdctl ... defrag
# ลบ log
sudo journalctl --vacuum-size=500M
3. Certificate หมดอายุ
sudo kubeadm certs check-expiration
ถ้า apiserver cert หมด — ดู K8s Cert Expired
4. Memory / CPU เต็มที่ master
free -h
top -b -n 1 | head -20
API server กิน RAM ตามจำนวน object — cluster ใหญ่ต้อง > 4GB
แก้: เพิ่ม RAM master, หรือเอา pod ของ workload ออกจาก master
5. Network problem
API server bind ที่ port 6443:
sudo ss -tlnp | grep 6443
ถ้าไม่มี — process ตาย ถ้ามี — firewall block
sudo ufw status
sudo iptables -L INPUT -n | grep 6443
6. Manifest ผิดของ static pod
API server เป็น static pod — kubelet load จาก /etc/kubernetes/manifests/kube-apiserver.yaml
ถ้าใครเผลอแก้ไฟล์นี้ผิด:
sudo journalctl -u kubelet -n 50 | grep -i apiserver
จะเห็น error ของ manifest
วิธีกู้
Step 1: ตรวจจุดที่พัง
ssh <master-node>
# ตรวจ kubelet
sudo systemctl status kubelet
# ตรวจ static pod
sudo crictl ps -a | grep -E "apiserver|etcd|controller|scheduler"
# ดู log
sudo crictl logs <apiserver-container-id>
Step 2: ลอง restart kubelet ก่อน
sudo systemctl restart kubelet
Kubelet จะ recreate static pod ที่หายไป
ดูว่า pod กลับมามั้ย:
sudo crictl ps | grep apiserver
Step 3: ถ้า manifest ผิด — restore
# ถ้ามี backup ก่อนหน้า
sudo cp /etc/kubernetes.bak/manifests/kube-apiserver.yaml \
/etc/kubernetes/manifests/kube-apiserver.yaml
# kubelet จะ apply อัตโนมัติ
Step 4: ถ้า etcd พัง — restore จาก backup
# stop apiserver static pod
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
# restore etcd
sudo ETCDCTL_API=3 etcdctl snapshot restore \
/var/lib/etcd-backup/snapshot.db \
--data-dir=/var/lib/etcd-restored
# stop etcd
sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/
# replace data
sudo mv /var/lib/etcd /var/lib/etcd.old
sudo mv /var/lib/etcd-restored /var/lib/etcd
# start back
sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
Multi-master HA — ป้องกัน single point of failure
cluster ที่ critical — 3 master นn HA:
Load Balancer (HAProxy / keepalived)
│
┌──────────────┼──────────────┐
▼ ▼ ▼
API server 1 API server 2 API server 3
etcd 1 etcd 2 etcd 3
LB ที่ port 6443 — ถ้า master 1 ตาย → traffic ไป 2 + 3
etcd cluster ต้อง majority alive (3 → ทน 1 ตาย) ถึงจะรับ write
Backup ที่จำเป็น
ทุก master ต้อง backup:
1. etcd snapshot
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /var/backups/etcd-$(date +%F).db
ตั้ง cron ทุกวัน:
0 2 * * * /usr/local/bin/backup-etcd.sh
2. /etc/kubernetes ทั้งหมด
sudo tar czf /var/backups/kubernetes-$(date +%F).tar.gz /etc/kubernetes
3. /var/lib/kubelet
sudo tar czf /var/backups/kubelet-$(date +%F).tar.gz /var/lib/kubelet
ส่งทั้งหมดไป S3 / B2 / external — อ่าน Database backup
Monitoring
ตั้ง alert:
# Prometheus alert
- alert: KubeAPIDown
expr: absent(up{job="apiserver"}) == 1
for: 5m
labels:
severity: critical
annotations:
summary: "API server down"
- alert: KubeAPIHighLatency
expr: histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m])) > 1
for: 10m
หรือ external monitor (ดูจากนอก cluster):
# Uptime Kuma — TCP check 6443
curl -k https://master-lb:6443/healthz
คำสั่ง ที่ใช้บ่อยตอน emergency
# 1. ดู health
kubectl get --raw /healthz
# 2. ดู component status
kubectl get componentstatuses
# 3. ดู events ทั้ง cluster
kubectl get events -A --sort-by='.lastTimestamp' | tail -30
# 4. ดู API server log
sudo crictl logs $(sudo crictl ps -q --name kube-apiserver) --tail=100
# 5. force restart kubelet (recreate static pod)
sudo systemctl restart kubelet
# 6. test etcd
sudo ETCDCTL_API=3 etcdctl ... endpoint status -w table
Lessons Learned
- API down ≠ workload down — pod ยังทำงาน user ส่วนใหญ่ไม่กระทบ
- etcd backup คือ insurance — ทำทุกวัน ทดสอบ restore เป็นระยะ
- HA = 3 master ไม่ใช่ 2 (quorum ของ 2 = 2 ตายไป 1 = หยุด)
- Monitor จากนอก — Prometheus ใน cluster ไม่ส่ง alert ถ้าทั้ง cluster ล่ม
- Cert expiration ป้องกันด้วย cron renew + alert
- เพิ่ม RAM master ตามจำนวน object — cluster ใหญ่ต้อง 8GB+
TLDR
API server ตาย:
- ✅ Pod ที่รันอยู่ทำงานต่อ
- ❌ Deploy / scale / kubectl หยุด
- ❌ Pod ใหม่ที่ควร schedule ไม่ขึ้น
- ❌ Auto-recovery ไม่ทำงาน
แก้:
- Restart kubelet
- ดู static pod log
- ตรวจ etcd, disk, cert, network
- ถ้าจริง ๆ พัง — restore จาก backup
สรุป
API server เป็น single point of failure ใน cluster แบบ single master — ทำให้ HA ตั้งแต่แรกถ้า cluster สำคัญ
ถ้าทำ HA ไม่ได้ — backup etcd รายวัน + monitor + รู้ขั้นตอนกู้ =พอ
อ่านต่อ: Troubleshooting K8s Step-by-Step — checklist สำหรับ debug