Docker & Container Orchestration

Docker Health Checks

-container ดูแลตัวเองได้ ด้วย Health Checks & Restart Policies

คู่มือสอนวิธีตั้งค่า Health Checks, Restart Policies, Resource Limits และ Best Practices สำหรับ Container ที่ทนทานและเชื่อถือได้ในปี 2025

Docker
Compose
Kubernetes

บทนำ

หนึ่งในความท้าทายที่ใหญ่ที่สุดของการบริหารจัดการ Container คือการรักษาให้ Container ทำงานอยู่เสมอ แม้จะเกิดข้อผิดพลาดหรือมัลแวร์เข้ามาโจมตีก็ตาม Docker และ Kubernetes มีเครื่องมือที่ทรงพลังที่เรียกว่า Health Checks และ Restart Policies ที่ช่วยให้ Container ดูแลตัวเองได้

Health Checks

ตรวจสอบสุขภาพของ Container อย่างต่อเนื่อง ว่าบริการยังทำงานปกติหรือไม่ และสามารถรีสตาร์ทอัตโนมัติเมื่อพบว่าไม่พร้อมใช้งาน

Restart Policies

กำหนดพฤติกรรมการรีสตาร์ท Container เมื่อทำงานเสร็จหรือหยุดทำงาน พร้อมจำนวนครั้งที่จะพยายามรีสตาร์ท

โครงสร้างระบบ: Container Lifecycle

การเข้าใจ Container Lifecycle คือหัวใจสำคัญของการตั้งค่า Health Checks และ Restart Policies โครงสร้างด้านล่างแสดงให้เห็นว่า Container ทำงานอย่างไรตั้งแต่เริ่มต้นจนถึงการรีสตาร์ทอัตโนมัติ

Start Running Starting... Health Check Interval: 30s Timeout: 10s healthy unhealthy starting Healthy Running normally Unhealthy Restarting... Restart Unless-stopped

สิ่งที่ต้องเตรียม

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 ที่ติดตั้ง

bash
docker --version
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

Dockerfile
FROM node:18-alpine
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

Dockerfile
FROM nginx:alpine
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 สำหรับการตรวจสอบที่ซับซ้อน

Dockerfile
FROM python:3.11-slim
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"]
healthcheck.sh
#!/bin/bash
curl -f http://localhost:5000/health || exit 1

ตัวเลือกเพิ่มเติมของ Health Check

NONE

ปิดการใช้งาน Health Check ทั้งหมด ใช้เมื่อไม่ต้องการตรวจสอบสุขภาพ

HEALTHCHECK NONE

TEST

ใช้สำหรับการตรวจสอบแบบง่าย โดยใช้คำสั่ง bash -c

HEALTHCHECK --interval=30s \\
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
รีสตาร์ทเว้นแต่หยุด

รีสตาร์ทเสมอเว้นแต่ถูกหยุดโดยผู้ใช้

no Never always Always on-failure On fail unless-stopped Unless S Container exits normally Docker restarts On error only Unless manually Recommended: unless-stopped

วิธีการใช้งาน

ตัวอย่างที่ 1: Docker Run

bash
docker run \\
--name myapp \\
--restart unless-stopped \\
-d \\
myapp:latest

ตัวอย่างที่ 2: Docker Compose

docker-compose.yml
services:
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 ดูแลตัวเองได้สมบูรณ์

docker-compose.yml
services:
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 สามารถใช้ได้

docker run \\
--memory "512m" \\
myapp:latest

CPU Limits

จำกัด CPU ที่ Container สามารถใช้ได้

docker run \\
--cpus "0.5" \\
myapp:latest

ตัวอย่างใน Docker Compose

docker-compose.yml
services:
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

pod.yaml
apiVersion: v1
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 ps --format "table {{.Names}}\t{{.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 เป็นระยะๆ