บทนำ
หนึ่งในความท้าทายที่ใหญ่ที่สุดของการบริหารจัดการ Container คือการรักษาให้ Container ทำงานอยู่เสมอ แม้จะเกิดข้อผิดพลาดหรือมัลแวร์เข้ามาโจมตีก็ตาม Docker และ Kubernetes มีเครื่องมือที่ทรงพลังที่เรียกว่า Health Checks และ Restart Policies ที่ช่วยให้ Container ดูแลตัวเองได้
Health Checks
ตรวจสอบสุขภาพของ Container อย่างต่อเนื่อง ว่าบริการยังทำงานปกติหรือไม่ และสามารถรีสตาร์ทอัตโนมัติเมื่อพบว่าไม่พร้อมใช้งาน
Restart Policies
กำหนดพฤติกรรมการรีสตาร์ท Container เมื่อทำงานเสร็จหรือหยุดทำงาน พร้อมจำนวนครั้งที่จะพยายามรีสตาร์ท
โครงสร้างระบบ: Container Lifecycle
การเข้าใจ Container Lifecycle คือหัวใจสำคัญของการตั้งค่า Health Checks และ Restart Policies โครงสร้างด้านล่างแสดงให้เห็นว่า Container ทำงานอย่างไรตั้งแต่เริ่มต้นจนถึงการรีสตาร์ทอัตโนมัติ
สิ่งที่ต้องเตรียม
Software Requirements
- Docker Engine เวอร์ชัน 20.10 หรือใหม่กว่า
- Docker Compose เวอร์ชัน 2.0 หรือใหม่กว่า
- Docker Desktop (สำหรับ Windows/Mac)
- ระบบปฏิบัติการ: Ubuntu 20.04+, Debian 11+, CentOS 8+
Hardware & Network
- RAM อย่างน้อย 4GB (แนะนำ 8GB สำหรับ Multiple Containers)
- CPU 2 cores ขึ้นไป
- เชื่อมต่ออินเทอร์เน็ตสำหรับ pull Docker images
- สิทธิ์การเข้าถึง sudo หรือ root
ตรวจสอบเวอร์ชัน Docker ที่ติดตั้ง
docker-compose --version
docker info
ส่วนที่ 1: Docker Health Checks
Health Check คืออะไร?
Health Check หรือการตรวจสอบสุขภาพ Container เป็นกลไกที่ทำให้ Docker สามารถตรวจสอบว่าบริการภายใน Container ยังทำงานปกติหรือไม่ โดยจะส่งคำสั่งทดสอบ (healthcheck command) ไปยัง Container เป็นระยะๆ
Docker จะบันทึกสถานะของ Container เป็น 1 ใน 3 สถานะ:
healthy
Container ทำงานปกติ
starting
กำลังเริ่มต้น
unhealthy
Container ไม่ทำงาน
รูปแบบคำสั่ง Health Check
| คำสั่ง | คำอธิบาย |
|---|---|
HEALTHCHECK |
ส่วนแรกของคำสั่ง - ระบุว่าจะมีการตรวจสอบสุขภาพ |
--interval=30s |
ช่วงเวลาที่จะตรวจสอบสุขภาพ (default: 30 วินาที) |
--timeout=10s |
เวลาที่จะรอให้คำสั่งสิ้นสุด (default: 30 วินาที) |
--start-period=40s |
ระยะเวลาก่อนเริ่มตรวจสอบ (default: 0) |
--retries=3 |
จำนวนครั้งที่จะลองก่อนถือว่า unhealthy (default: 3) |
CMD |
คำสั่งที่จะรันในการตรวจสอบ (ต้องเป็น JSON array หรือ string) |
วิธีการใช้งานใน Dockerfile
เขียนคำสั่ง HEALTHCHECK ใน Dockerfile
โดยสามารถใช้หลักการ "Start Period"
เพื่อป้องกันไม่ให้ Docker ถือว่า Container ไม่healthy ขณะกำลังเริ่มต้น
ตัวอย่างที่ 1: Basic Health Check
ตรวจสอบว่า service ยังทำงานอยู่โดยการเรียก endpoint
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s \\
--start-period=40s --retries=3 \\
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "server.js"]
ตัวอย่างที่ 2: HTTP Health Check (Recommended)
ตรวจสอบ HTTP endpoint โดยใช้ curl หรือ wget
COPY nginx.conf /etc/nginx/nginx.conf
HEALTHCHECK --interval=30s --timeout=10s \\
--start-period=5s --retries=3 \\
CMD wget --quiet --tries=1 --spider http://localhost:80/ || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
ตัวอย่างที่ 3: Custom Script Health Check
ใช้ custom script สำหรับการตรวจสอบที่ซับซ้อน
WORKDIR /app
COPY app.py ./
COPY healthcheck.sh ./
RUN chmod +x healthcheck.sh
HEALTHCHECK --interval=30s --timeout=10s \\
--start-period=40s --retries=3 \\
CMD ["./healthcheck.sh"]
CMD ["python", "app.py"]
curl -f http://localhost:5000/health || exit 1
ตัวเลือกเพิ่มเติมของ Health Check
NONE
ปิดการใช้งาน Health Check ทั้งหมด ใช้เมื่อไม่ต้องการตรวจสอบสุขภาพ
TEST
ใช้สำหรับการตรวจสอบแบบง่าย โดยใช้คำสั่ง bash -c
CMD TEST -f /tmp/healthy || exit 1
คำแนะนำสำคัญ
- อย่าใช้คำสั่งที่หนัก - ใช้คำสั่งที่เบาและรวดเร็ว เช่น curl, wget หรือ nc
- ตั้ง start-period ให้เหมาะสม - อย่าทำให้ Container ถูกถือว่า unhealthy ในช่วงเริ่มต้น
- ใช้ endpoint สำหรับตรวจสอบสุขภาพ - สร้าง endpoint /health ที่ไม่ใช้ฐานข้อมูลหรือ external service
- อย่าตรวจสอบบ่อยเกินไป - interval ที่แนะนำคือ 30-60 วินาที
ส่วนที่ 2: Docker Restart Policies
Restart Policy คืออะไร?
Restart Policy หรือนโยบายการรีสตาร์ท คือการกำหนดพฤติกรรมของ Docker ว่าจะรีสตาร์ท Container เมื่อใด เช่น เมื่อ Container หยุดทำงาน หรือเมื่อ Docker daemon รีสตาร์ท
ประเภทของ Restart Policies
no
เป็นค่าเริ่มต้น
always
รีสตาร์ททุกครั้งเมื่อหยุดหรือล้มเหลว
on-failure
รีสตาร์ทเฉพาะเมื่อ exit code ไม่ใช่ 0
unless-stopped
รีสตาร์ทเสมอเว้นแต่ถูกหยุดโดยผู้ใช้
วิธีการใช้งาน
ตัวอย่างที่ 1: Docker Run
--name myapp \\
--restart unless-stopped \\
-d \\
myapp:latest
ตัวอย่างที่ 2: Docker Compose
web:
image: nginx:latest
restart: unless-stopped
ports:
- "80:80"
db:
image: postgres:15
restart: always
environment:
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
ตัวอย่างที่ 3: Restart along with Health Check
ใช้ทั้ง Health Check และ Restart Policy ร่วมกันเพื่อให้ Container ดูแลตัวเองได้สมบูรณ์
app:
image: myapp:latest
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
ports:
- "3000:3000"
การเลือก Restart Policy ที่เหมาะสม
| Use Case | Recommended Policy | เหตุผล |
|---|---|---|
| Web Applications |
unless-stopped
|
รีสตาร์ทเสมอเว้นแต่หยุดด้วยตนเอง - เหมาะกับบริการที่ต้องพร้อมใช้งานตลอดเวลา |
| Databases |
always
|
ต้องให้บริการตลอดเวลา - รีสตาร์ทแม้จะหยุดด้วยตนเอง |
| Batch Jobs |
no
|
ไม่ต้องรีสตาร์ท - ทำงานเพียงครั้งเดียวเท่านั้น |
| Tasks with Failures |
on-failure
|
รีสตาร์ทเฉพาะเมื่อมีข้อผิดพลาด - ป้องกันวงจรของข้อผิดพลาด |
| Development |
no
|
ไม่ต้องรีสตาร์ท - ต้องการควบคุมด้วยตนเองระหว่างพัฒนา |
Best Practice: ค่า Default ที่แนะนำ
สำหรับ most production workloads เราแนะนำให้ใช้
unless-stopped ซึ่งให้ความสมดุลระหว่าง
availability และการควบคุม
ข้อดี: • รีสตาร์ทเมื่อ Docker restart • รีสตาร์ทเมื่อ Container crash • ไม่รีสตาร์ทเมื่อหยุดด้วยคำสั่ง docker stop
ส่วนที่ 3: Resource Limits (เพิ่มเติม)
ทำไมต้องตั้งค่า Resource Limits?
โดยไม่มีการจำกัดทรัพยากร Container หนึ่งๆ อาจกินทรัพยากรของเครื่องทั้งหมด ทำให้ Container อื่นๆ ไม่สามารถทำงานได้ หรือแม้แต่ทำให้ Host System ล่ม
Memory Limits
จำกัดปริมาณ RAM ที่ Container สามารถใช้ได้
--memory "512m" \\
myapp:latest
CPU Limits
จำกัด CPU ที่ Container สามารถใช้ได้
--cpus "0.5" \\
myapp:latest
ตัวอย่างใน Docker Compose
web:
image: nginx:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
คำอธิบาย
- limits: ค่าสูงสุดที่ Container สามารถใช้ได้
- reservations: ค่าที่จองไว้ให้ Container - Docker จะรับประกันว่าจะมีทรัพยากรนี้ให้เสมอ
- cpus: จำนวน CPU cores (0.5 = ครึ่งแกน, 2 = 2 แกน)
- memory: ปริมาณ RAM (512M = 512 MB, 1G = 1 GB)
ส่วนที่ 4: Kubernetes Probes (เพิ่มเติม)
Kubernetes Health Checks
Kubernetes มีระบบ Health Checks ที่ทรงพลังกว่า Docker คือ Probes ซึ่งมีอยู่ 3 ประเภทหลัก
Liveness Probe
ตรวจสอบว่า Container ยังทำงานอยู่ ถ้าล้มเหลว Container จะถูก kill และรีสตาร์ท
Readiness Probe
ตรวจสอบว่า Container พร้อมรับ traffic หรือไม่ ถ้าไม่พร้อมจะถูกลบออกจากรอบโหลดบาลานซ์
Startup Probe
ตรวจสอบว่า Container ยังคงเริ่มต้นหรือไม่ ใช้สำหรับ Container ที่ใช้เวลานานในการเริ่มต้น
ตัวอย่าง Kubernetes Pod Configuration
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
คำอธิบายพารามิเตอร์
| Parameter | Description |
|---|---|
initialDelaySeconds |
จำนวนวินาทีก่อนเริ่มตรวจสอบ (หลัง Container เริ่มทำงาน) |
periodSeconds |
ความถี่ของการตรวจสอบ (ทุกกี่วินาที) |
timeoutSeconds |
เวลารอคำสั่งสิ้นสุดก่อนถือว่าล้มเหลว |
failureThreshold |
จำนวนครั้งที่ล้มเหลวก่อนถือว่า Container ไม่ดี |
Best Practices
Health Checks
-
สร้าง lightweight endpoints: Health check endpoint ควรไม่ใช้ database หรือ external service
-
ตั้งค่า start-period: ให้เหมาะสมกับเวลาที่ Container ต้องใช้ในการเริ่มต้น
-
อย่าตรวจสอบบ่อยเกินไป: Interval ที่แนะนำคือ 30-60 วินาที ไม่ใช่ทุก 5 วินาที
-
ใช้ endpoint สำหรับตรวจสอบสุขภาพ: สร้าง /health endpoint แยกต่างหาก ไม่ใช้ root / endpoint
Restart Policies
-
ใช้ unless-stopped: เป็นค่า default ที่ดีที่สุดสำหรับ production workloads
-
หลีกเลี่ยง always: เว้นแต่เป็น services สำคัญที่ต้องพร้อมเสมอ เช่น database
-
ใช้ health check กับ restart: Health check จะช่วยให้รีสตาร์ทเฉพาะ Container ที่ไม่ดี
-
ติดตาม restart count: ใช้ docker stats หรือ metrics to monitoring restart frequency
Resource Management
-
ตั้งค่า limits เสมอ: ป้องกัน Containter หนึ่งจากกินทรัพยากรทั้งหมด
-
ปรับค่าตาม real usage: ใช้ docker stats หรือ cAdvisor เพื่อดูการใช้งานจริง
-
ใช้ reservations สำหรับ critical services: รับประกันว่าจะมีทรัพยากรเพียงพอเสมอ
-
_monitor resource usage: ติดตามและปรับค่าเป็นระยะๆ เพื่อให้เหมาะสม
Troubleshooting
คำถามที่พบบ่อย
ทำไม Container ถูกถือว่า unhealthy แม้จะทำงานได้ปกติ?
ตรวจสอบว่า: • Health check endpoint ทำงานได้หรือไม่ • start-period มีค่ามากพอหรือไม่ • Network connectivity เป็นปกติหรือไม่
Container รีสตาร์ทบ่อยเกินไป ต้องทำอย่างไร?
ตรวจสอบ:
• Logs ด้วย docker logs [container]
• สังเกต restart count ด้วย docker inspect
• ปรับ restart policy เป็น on-failure
Health check endpoint ควรใช้อะไร?
เทคนิคที่ดีที่สุดคือ: • ** Lightweight check:** ตรวจสอบแค่ service ทำงานหรือไม่ • **Avoid database calls:** ไม่ใช้ database calls ใน health check • **Fast response:** ต้องตอบกลับภายในไม่กี่ millisecond
ตรวจสอบ Health Check status อย่างไร?
docker inspect --format '{{.State.Health.Status}}' myapp
docker events --filter event=health_status
คำสั่งที่ใช้บ่อย
ตรวจสอบ Container Status
docker ps
docker inspect [container]
ดู Logs
docker logs [container]
docker logs -f [container]
ดู Resource Usage
docker stats
docker stats --no-stream
รีสตาร์ท Container
docker restart [container]
docker stop [container] && docker start [container]
สรุป
การตั้งค่า Health Checks และ Restart Policies ถือเป็นพื้นฐานที่สำคัญที่สุด สำหรับการบริหารจัดการ Container ที่มีความทนทานและเชื่อถือได้
Health Checks
ตรวจสอบสุขภาพ Container อย่างต่อเนื่อง
Restart Policies
รีสตาร์ท Container อัตโนมัติเมื่อจำเป็น
Resource Limits
จำกัดทรัพยากรเพื่อป้องกัน noisy neighbor
Key Takeaways
- Health Checks ตรวจสอบว่าบริการยังทำงานอยู่หรือไม่
- Restart Policies รีสตาร์ท Container อัตโนมัติเมื่อจำเป็น
- Resource Limits ป้องกัน Container จากกินทรัพยากรทั้งหมด
- Monitoring ติดตาม status และ restart count เป็นระยะๆ