ก่อนอื่น — คุณ "ต้องการ" Kubernetes มั้ย
มีหลายทีมขนาดเล็ก (3-5 คน) ที่ตัดสินใจใช้ Kubernetes เพราะ "ทุกคนใช้กัน" แล้วเสียเวลา 30% ไปกับการ debug k8s แทนเขียน feature
คุณอาจไม่ต้องการ k8s ถ้า:
- ทีม < 10 คน
- Service < 5 ตัว
- Traffic ไม่เกิน 100k req/วัน
- ไม่มีคนที่ดูแล k8s เป็น full-time
คุณอาจต้องการ k8s ถ้า:
- มี microservice เยอะ (10+ ตัว)
- Traffic สูง ต้อง auto-scale
- Multi-region deployment
- มี platform team ดูแลแยก
- Multi-tenant SaaS ที่ต้อง isolate
ส่วนใหญ่ — Docker Compose บน VPS เดียว หรือ Fly.io / Railway / Render ก็เพียงพอแล้ว
Kubernetes แก้ปัญหาอะไร
ถ้า scale ใหญ่จริงๆ k8s ช่วย:
- Self-healing — pod พังจะ start ใหม่อัตโนมัติ
- Rolling update — deploy ใหม่ไม่มี downtime
- Auto-scaling — เพิ่ม/ลด pod ตาม load
- Service discovery — service เรียกหากันด้วยชื่อ
- Secret/Config management — แยก config จาก code
- Multi-cloud — config เดียว run ได้ทุก cloud
ทั้งหมดนี้ Docker Compose ก็ทำได้ในระดับเครื่องเดียว k8s แค่ทำได้ใน scale หลายเครื่อง
Concept หลักที่ต้องรู้
Pod — หน่วยที่เล็กที่สุด
Pod = 1+ container ที่อยู่ด้วยกัน share network และ storage
ส่วนใหญ่ pod = 1 container (เหมือน docker container) แต่บางทีมี sidecar เช่น log collector
Deployment — รัน pod กี่ตัว
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3 # รัน 3 pod
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 3000
resources:
limits:
cpu: 500m
memory: 512Mi
replicas: 3 = k8s จะคุมให้มี 3 pod รันเสมอ ถ้าตายตัวหนึ่ง start ใหม่ทันที
Service — internal load balancer
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
Pod ตายและเกิดใหม่ IP เปลี่ยนตลอด — Service ให้ DNS name คงที่ (myapp:80 ใน cluster) กระจาย traffic ไปยัง pod ที่ match label
Ingress — entry point จากภายนอก
Ingress = layer 7 routing (HTTP/HTTPS) ส่ง request ไปยัง service ที่เกี่ยวข้อง:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts: [myapp.com]
secretName: myapp-tls
rules:
- host: myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
= Nginx ในรูป k8s + Let's Encrypt อัตโนมัติ
ConfigMap & Secret
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
NODE_ENV: production
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: myapp-secret
type: Opaque
stringData:
DATABASE_URL: postgresql://...
ใส่ใน Deployment:
spec:
template:
spec:
containers:
- name: app
image: myapp
envFrom:
- configMapRef:
name: myapp-config
- secretRef:
name: myapp-secret
Persistent Volume
storage ที่อยู่กับ pod:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pgdata
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 20Gi
แล้ว mount ใน pod — ข้อมูลคงอยู่ pod restart ก็ไม่หาย
คำสั่ง kubectl ที่ใช้บ่อย
# Apply manifest
kubectl apply -f deployment.yaml
# ดู resource
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get all # ทุกอย่าง
# describe — ดู detail (สำคัญสำหรับ debug)
kubectl describe pod myapp-abc123
# log
kubectl logs myapp-abc123
kubectl logs -f myapp-abc123 # ตาม realtime
kubectl logs --tail=100 -l app=myapp # 100 บรรทัดล่าสุด ของทุก pod ที่ label app=myapp
# exec เข้า pod
kubectl exec -it myapp-abc123 -- sh
# port forward (ทดสอบ local)
kubectl port-forward svc/myapp 8080:80
# rollout
kubectl rollout status deployment/myapp
kubectl rollout undo deployment/myapp # rollback
# scale
kubectl scale deployment/myapp --replicas=5
# ลบ
kubectl delete deployment myapp
Local ทดสอบ — Minikube / kind / k3d
ทดสอบบนเครื่องตัวเองก่อน production:
- Minikube — ดั้งเดิม รัน VM
- kind (Kubernetes IN Docker) — เร็ว เหมาะ CI
- k3d — k3s ใน Docker — light ที่สุด
# kind
kind create cluster
kubectl get nodes
Managed k8s — แทน self-host
ถ้าต้องการใช้ k8s จริง — อย่า self-host เลย ใช้ managed service:
| Provider | Service | ราคาเริ่มต้น | |---|---|---| | AWS | EKS | $0.10/hour control plane + EC2 | | GCP | GKE Autopilot | จ่ายตามใช้จริง pod | | DigitalOcean | DOKS | ฟรี control plane + droplet | | Linode | LKE | ฟรี control plane + linode |
Self-host k8s = full-time job ของวิศวกร 1+ คน — ค่าจ้างแพงกว่าค่า managed service เยอะ
k3s — k8s รุ่นเล็ก
ถ้าจริงจังจะ self-host แต่ scale เล็ก — k3s จาก Rancher:
- Binary เดียว 60MB
- ใส่ SQLite แทน etcd
- ตั้งใน 1 บรรทัด
- ใช้ใน edge / IoT / homelab ดี
curl -sfL https://get.k3s.io | sh -
# ใช้ kubectl
sudo k3s kubectl get nodes
แต่ถึงจะ light ก็ยังมี learning curve เท่า k8s ปกติ
Alternative — ถ้าทีมเล็กแต่อยาก feature ของ k8s
ถ้าอยาก:
- Auto-scale
- Rolling deploy ไม่มี downtime
- Multi-region
- Health check + restart
ลองพวกนี้ก่อน:
- Fly.io —
fly deployแล้วได้ทุกอย่าง - Railway / Render — ใส่ git URL แล้ว deploy
- DigitalOcean App Platform
- AWS ECS Fargate — container แต่ไม่ใช่ k8s
- Google Cloud Run — pay per request
ราคาอาจสูงกว่า VPS แต่เทียบกับเวลา devops ที่ประหยัด — คุ้มสำหรับทีมเล็ก
ตัวอย่าง full deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels: { app: myapp }
spec:
replicas: 3
selector:
matchLabels: { app: myapp }
template:
metadata:
labels: { app: myapp }
spec:
containers:
- name: app
image: ghcr.io/myorg/myapp:1.2.0
ports:
- containerPort: 3000
envFrom:
- secretRef: { name: myapp-secret }
resources:
limits: { cpu: 500m, memory: 512Mi }
livenessProbe:
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 3
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata: { name: myapp }
spec:
selector: { app: myapp }
ports:
- port: 80
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts: [myapp.com]
secretName: myapp-tls
rules:
- host: myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: { name: myapp, port: { number: 80 } }
kubectl apply -f deployment.yaml
สรุป
k8s ทรงพลัง — แต่จ่ายด้วย complexity เยอะ
คำแนะนำ:
- Project เล็ก → Compose + VPS เพียงพอ
- Project กลาง → Fly.io / Railway / managed PaaS
- Project ใหญ่ → managed k8s (EKS/GKE/DOKS)
- อย่า self-host k8s ถ้าไม่มีคนเป็น full-time
ถ้ารู้สึกว่าเร็วๆ นี้จะใช้แน่ — เรียน concept ไว้ก็ดี แต่อย่ายัด k8s เข้า project ที่ยังไม่ต้องการ