Docker Health Check: ตรวจสอบสุขภาพ Container อัตโนมัติ

Docker Health Check เป็นฟีเจอร์ที่สำคัญในการตรวจสอบสุขภาพของ Container อัตโนมัติ เพื่อให้มั่นใจว่า Application ของคุณทำงานได้อย่างปกติ บทความนี้จะอธิบายรายละเอียดเกี่ยวกับวิธีการใช้งาน HEALTHCHECK Instruction อย่างครบถ้วน และวิธีการนำไปประยุกต์ใช้ในโครงการจริง

Docker Health Check คืออะไร?

Docker Health Check เป็นกลไกในการติดตามสถานะของ Container โดยทำการทดสอบ Application ที่ทำงานภายในอย่างสม่ำเสมอ ตัวอย่างเช่น การส่ง HTTP Request ไปยัง Web Server หรือการเชื่อมต่อกับ Database เพื่อตรวจสอบว่า Service ยังทำงานอยู่หรือไม่

ก่อนที่จะมี Health Check, Docker จะรู้เพียงแค่ว่า Process ยังทำงานอยู่หรือไม่ แต่ Health Check ช่วยให้เราทราบว่า Application นั้นทำงานได้อย่างมีประสิทธิภาพหรือไม่

ทำไมเราต้องใช้ Docker Health Check?

  • ความเชื่อมั่นในการให้บริการ: รู้ได้ว่า Container นั้นสามารถให้บริการได้จริง ไม่ใช่แค่ Process ยังทำงานอยู่
  • การจัดการอัตโนมัติ: ใช้งานร่วมกับ Container Orchestration เช่น Docker Swarm เพื่อ Restart Container ที่มีปัญหาอัตโนมัติ
  • ลดเวลาหยุดทำงาน: ตรวจพบและแก้ไขปัญหาได้เร็วขึ้นก่อนที่ผู้ใช้จะสัมผัสปัญหา
  • Load Balancing ที่เหมาะสม: ในระบบ Orchestration สามารถหลีกเลี่ยงการส่ง Traffic ไปยัง Container ที่มีปัญหาได้

ไวยากรณ์ HEALTHCHECK ใน Dockerfile

ในการเพิ่ม Health Check ให้กับ Container เราใช้ HEALTHCHECK Instruction ในไฟล์ Dockerfile:

HEALTHCHECK [OPTIONS] CMD command

โดย OPTIONS ที่สำคัญคือ:

Option ค่าเริ่มต้น คำอธิบาย
–interval 30s ระยะเวลาระหว่างการทดสอบ
–timeout 30s ระยะเวลาสูงสุดที่รอให้คำสั่งเสร็จสิ้น
–start-period 0s เวลาที่รอให้ Container เริ่มทำงานเสร็จก่อนการตรวจสอบครั้งแรก
–retries 3 จำนวนครั้งที่ทดสอบล้มเหลว ก่อนถือว่า Unhealthy

สถานะของ Docker Health Check

Docker Health Check มีสามสถานะ:

  • healthy: Container ทำงานได้อย่างปกติ Health Check สำเร็จ
  • unhealthy: Container มีปัญหา Health Check ล้มเหลวเกินจำนวน Retries ที่กำหนด
  • starting: Container เพิ่งเริ่มทำงาน ยังอยู่ในช่วง –start-period

ตัวอย่าง Health Check สำหรับ Web Application

สำหรับ Web Application เช่น Node.js หรือ Python Flask เราสามารถทำ Health Check โดยการส่ง HTTP Request ไปยัง Server:

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 curl -f http://localhost:3000/health || exit 1

CMD ["node", "app.js"]

ในตัวอย่างนี้:

  • --interval=30s ทำการตรวจสอบทุกๆ 30 วินาที
  • --timeout=10s รอคำตอบได้มากที่สุด 10 วินาที
  • --start-period=40s รอให้ Application เริ่มทำงาน 40 วินาที ก่อนการตรวจสอบครั้งแรก
  • --retries=3 ทดสอบ 3 ครั้งก่อนถือว่า Unhealthy
  • curl -f http://localhost:3000/health คำสั่งตรวจสอบส่ง Request ไปยัง /health Endpoint

ตัวอย่าง Health Check สำหรับ Database

สำหรับ PostgreSQL ใช้คำสั่งเฉพาะของ Database ในการตรวจสอบ:

FROM postgres:15

HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=5 \
  CMD pg_isready -U postgres || exit 1

CMD ["postgres"]

สำหรับ MySQL:

FROM mysql:8.0

ENV MYSQL_ROOT_PASSWORD=example

HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD mysqladmin ping -h localhost -u root -pexample || exit 1

CMD ["mysqld"]

ตัวอย่าง Health Check สำหรับ API

สำหรับ API Server เราต้องแน่ใจว่าไม่ใช่แค่ Port เปิดอยู่ แต่ Endpoint ยังทำงานได้อย่างปกติ:

FROM golang:1.21-alpine

WORKDIR /app
COPY . .
RUN go build -o server .

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD wget --quiet --tries=1 --spider http://localhost:8080/api/health || exit 1

CMD ["./server"]

Health Check ด้วย Custom Script

สำหรับการตรวจสอบที่ซับซ้อนมากขึ้น สร้าง Script เพื่อทำ Health Check:

#!/bin/bash
# healthcheck.sh

# ตรวจสอบ HTTP Endpoint
if ! curl -f http://localhost:8000/status; then
  exit 1
fi

# ตรวจสอบการเชื่อมต่อ Database
if ! pg_isready -h localhost -p 5432 -U myuser; then
  exit 1
fi

exit 0
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

RUN chmod +x /app/healthcheck.sh

HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
  CMD /app/healthcheck.sh

CMD ["python", "app.py"]

Health Check ใน docker-compose.yml

นอกจากการกำหนดใน Dockerfile เราสามารถกำหนด Health Check ใน docker-compose.yml ได้เช่นกัน:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  database:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: example
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

การใช้ CMD-SHELL หมายถึงการรันคำสั่งผ่าน Shell เพื่อให้สามารถใช้ Pipeline และ Built-in Shell Commands ได้ แต่ CMD เรียกใช้คำสั่งโดยตรงไม่ผ่าน Shell

การติดตาม Health Status

ตรวจสอบสถานะ Health Check ของ Container โดยใช้คำสั่ง:

# แสดงสถานะ Health Check
docker ps

# ผลลัพธ์ตัวอย่าง
CONTAINER ID   IMAGE     COMMAND             STATUS
abc123def456   myapp:1   "node app.js"       Up 2 minutes (healthy)

# ดูรายละเอียดเพิ่มเติม
docker inspect --format='{{.State.Health.Status}}' abc123def456

# ดูประวัติการทดสอบ
docker inspect --format='{{json .State.Health}}' abc123def456 | python3 -m json.tool

Health Check กับ Docker Swarm

เมื่อใช้ Docker Swarm เราสามารถใช้ Health Check ร่วมกับ Restart Policy เพื่อจัดการ Container ที่มีปัญหาโดยอัตโนมัติ:

version: '3.8'

services:
  web:
    image: myapp:latest
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      update_config:
        parallelism: 1
        delay: 10s
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Best Practices สำหรับ Health Check

  • ใช้ –start-period ที่เหมาะสม: ให้ Application มีเวลาเพียงพอในการเริ่มต้น
  • ตั้งค่า –interval อย่างสมเหตุสมผล: ไม่ควรสั้นเกินไป เพราะจะเป็นภาระบน Container
  • ทำให้ Health Check Endpoint เบา: Health Check ควรทำงานอย่างรวดเร็ว ไม่ควรใช้ Resources มาก
  • ตั้งค่า –retries เหมาะสม: สมดุลระหว่างความเร็วในการตรวจพบปัญหา และการหลีกเลี่ยง False Positive
  • ตรวจสอบ Dependency ด้วย: ให้ Health Check ตรวจสอบที่ Database Connection และ External Service ด้วย ไม่ใช่แค่เช็ค HTTP Status Code
  • บันทึก Health Check Log: ช่วยในการ Debug เมื่อมีปัญหา

ปัญหาทั่วไปและวิธีแก้ไข

ปัญหา: Health Check ล้มเหลวตลอด

  • ตรวจสอบว่า Application ทำงานอยู่จริงด้วย docker exec container_id curl http://localhost:3000/health
  • ตรวจสอบ Port ที่ใช้ถูกต้องหรือไม่
  • เพิ่มค่า –timeout หาก Network ช้า

ปัญหา: Health Check สลับระหว่าง Healthy และ Unhealthy

  • เพิ่มค่า –timeout
  • ตรวจสอบว่า Application ใช้ Resources มากเกินไปหรือไม่
  • เพิ่มค่า –retries หากเป็น False Positive

สรุป

Docker Health Check เป็นเครื่องมือที่ทรงคุณค่าสำหรับการตรวจสอบสุขภาพของ Container อัตโนมัติ การใช้งาน Health Check อย่างถูกต้องจะช่วยให้ Application ทำงานได้อย่างเสถียร ลดเวลาหยุดทำงาน และตรวจพบปัญหาได้อัตโนมัติ ซึ่งเป็นสิ่งสำคัญอย่างยิ่งในการจัดการ Container ในสภาพแวดล้อม Production

หากคุณต้องการ Infrastructure ที่เหมาะสำหรับการรัน Docker Application ใน Production แนะนำให้ลองใช้ Dot Enterprise Cloud VPS ที่ https://de.co.th/cloud-vps มี Infrastructure ที่เหมาะสำหรับ Docker และความเสถียรภาพสูงในการให้บริการ