Giám sát Docker Swarm: ‘Bắt bệnh’ Replicas và Rolling Update bằng Prometheus & cAdvisor

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

Nỗi ám ảnh khi vận hành Docker Swarm mà không có dữ liệu

Hồi mới triển khai Docker Swarm cho dự án, mình từng thức trắng đêm chỉ vì một lỗi ngớ ngẩn. Lúc đó mình nghĩ Swarm tự điều phối (orchestration) rất tốt, service chết thì nó tự hồi sinh nên không cần lo lắng. Thực tế khắc nghiệt hơn nhiều. Một service bị lỗi CrashLoopBackOff do sai cấu hình, khiến Swarm liên tục khởi chạy lại rồi sập. CPU server nhảy vọt lên 95%, log tràn ngập ổ cứng mà mình chẳng hay biết cho đến khi khách hàng gọi điện phàn nàn.

Quản lý cluster 10-15 node mà không có monitoring giống như lái xe trong sương mù. Mình từng phải SSH vào từng Manager Node, gõ mỏi tay lệnh docker service ls chỉ để kiểm tra trạng thái. Cách làm thủ công này cực kỳ tốn thời gian và dễ sai sót. Giờ đây, chỉ cần nhìn vào dashboard, mình biết ngay service nào đang thiếu replicas hay node nào đang quá tải.

Bộ ba công cụ: Prometheus, cAdvisor và Docker Swarm

Để giám sát hiệu quả, chúng ta cần một cơ chế thu thập dữ liệu tự động thay vì cài đặt rời rạc. Mình chọn cách tận dụng chính sức mạnh của Swarm để triển khai stack giám sát.

  • cAdvisor (Container Advisor): Đây là “điệp viên” nằm vùng trên từng node. Nó soi vào từng container để trích xuất thông số CPU, RAM và Network. Trong Swarm, mình chạy cAdvisor ở mode: global để đảm bảo không bỏ sót bất kỳ node nào.
  • Prometheus: Đóng vai trò bộ não trung tâm. Nó định kỳ gõ cửa cAdvisor để lấy dữ liệu (pull mechanism) và lưu vào database dạng time-series.
  • Docker Engine Metrics: Từ phiên bản 17.05, Docker đã có thể xuất metrics chuẩn Prometheus. Kích hoạt tính năng này giúp bạn theo dõi được trạng thái thực của toàn bộ cluster.

Cấu hình Docker Engine để xuất dữ liệu

Mặc định, Docker khóa cổng metrics. Để Prometheus đọc được dữ liệu về số lượng replicas, bạn cần sửa file /etc/docker/daemon.json trên tất cả các node.

{
  "metrics-addr" : "0.0.0.0:9323",
  "experimental" : true
}

Sau khi sửa, hãy restart Docker bằng lệnh:

sudo systemctl restart docker

Một lưu ý quan trọng: Việc mở cổng 0.0.0.0:9323 có thể gây rủi ro bảo mật nếu server có IP public. Bạn nên dùng tường lửa (UFW/Iptables) để chỉ cho phép các IP nội bộ trong cluster truy cập vào cổng này.

Triển khai Monitoring Stack

Thay vì chạy lệnh đơn lẻ, mình gộp tất cả vào file monitoring-stack.yml. Điểm hay của cách này là tính nhất quán cao. Dưới đây là cấu hình rút gọn để bạn dễ hình dung:

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "9090:9090"
    networks:
      - monitor-net
    deploy:
      placement:
        constraints: [node.role == manager]

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    networks:
      - monitor-net
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    deploy:
      mode: global
      resources:
        limits:
          memory: 128M

networks:
  monitor-net:
    driver: overlay

Sức mạnh của Service Discovery trong Prometheus

Trong môi trường Swarm, container thường xuyên nhảy giữa các node. Bạn không thể điền IP tĩnh vào file cấu hình vì nó sẽ thay đổi liên tục. Prometheus giải quyết vấn đề này bằng tính năng dockerswarm_sd_configs.

Dưới đây là cách mình cấu hình để Prometheus tự động tìm thấy các node:

scrape_configs:
  - job_name: 'docker-swarm'
    dockerswarm_sd_configs:
      - host: unix:///var/run/docker.sock
        role: nodes
    relabel_configs:
      - target_label: __address__
        replacement: 127.0.0.1:9323

Đừng quên mount file docker.sock vào container Prometheus. Nếu thiếu bước này, Prometheus sẽ bị “cấm cửa” và không thể hỏi Docker Swarm về danh sách các node đang hoạt động.

Giám sát Rolling Update và Replicas trong thực tế

Khi dữ liệu đã đổ về, mình thường tập trung vào 3 kịch bản thực tế sau:

1. Cảnh báo thiếu Replicas

Nếu bạn yêu cầu 5 replicas nhưng chỉ có 3 cái chạy, hệ thống đang gặp nguy hiểm. Query sau giúp bạn tìm ra các service đang bị thiếu hụt:

engine_daemon_swarm_service_tasks_total{state="running"}

2. Kiểm soát Rolling Update

Khi chạy docker service update, đôi khi version mới bị lỗi khiến quá trình cập nhật bị treo. Mình theo dõi metric engine_daemon_container_states_containers. Nếu thấy trạng thái restarting tăng vọt sau khi update, mình sẽ tiến hành rollback ngay lập tức để tránh gián đoạn dịch vụ.

3. Kiểm tra sức khỏe Node

Metric dockerswarm_node_status cực kỳ hữu ích. Có lần một node của mình bị mất kết nối mạng nhưng Swarm vẫn điều hướng traffic vào đó, gây lỗi 502 liên tục. Nhờ có cảnh báo từ Prometheus, mình đã phát hiện và xử lý chỉ trong chưa đầy 2 phút.

Lời kết

Thiết lập giám sát không chỉ để vẽ biểu đồ cho đẹp. Nó là công cụ giúp bạn ngủ ngon hơn mỗi đêm. Thay vì thấp thỏm lo âu, hãy để Prometheus canh gác hệ thống cho bạn. Nếu cluster của bạn đang chạy production mà thiếu cAdvisor và Prometheus, hãy dành 30 phút để cài đặt ngay hôm nay. Nó sẽ tiết kiệm cho bạn hàng giờ debug mệt mỏi sau này.

Share: