Đừng trả tiền cho PagerDuty nữa: Cách tự triển khai Grafana OnCall trên VPS giá 5$

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Khởi động nhanh trong 5 phút: Chạy Grafana OnCall với Docker

Loại bỏ hóa đơn PagerDuty 21$ mỗi người dùng hàng tháng không đòi hỏi một quá trình chuyển đổi kéo dài cả cuối tuần. Nếu bạn đã sẵn sàng Docker và Docker Compose, bạn có thể dựng một instance Grafana OnCall cục bộ ngay trước khi tách cà phê kịp nguội. Kiểm tra cục bộ là cách thông minh nhất để xem giao diện có phù hợp với thói quen của nhóm bạn hay không trước khi chuyển sang môi trường production.

Bắt đầu bằng cách clone repository chính thức và truy cập vào thư mục deployment:

git clone https://github.com/grafana/oncall.git
cd oncall/deploy/docker

Bạn sẽ thấy một file .env.example. Hãy sao chép nó thành .env. Mặc dù các giá trị mặc định có thể dùng cho việc kiểm tra cục bộ, bạn phải thiết lập một SECRET_KEY duy nhất và trỏ DOMAIN_NAME về IP cục bộ hoặc localhost để tránh vòng lặp chuyển hướng.

cp .env.example .env
# Chỉnh sửa .env và thiết lập DOMAIN_NAME=http://localhost:8080

Khởi chạy stack:

docker-compose up -d

Khi các container hiển thị trạng thái healthy, hãy mở Grafana tại http://localhost:3000. Bạn sẽ cần kích hoạt plugin OnCall và trỏ nó tới http://oncall-engine:8080. Địa chỉ nội bộ Docker này sẽ kết nối giao diện UI với logic engine ngay lập tức.

Các thành phần vận hành: Kiến trúc và các thành phần cốt lõi

Tôi đã chuyển đổi một đội ngũ gồm 12 kỹ sư từ PagerDuty sang thiết lập này vào năm ngoái. Nỗi sợ lớn nhất của tôi là một công cụ tự lưu trữ (self-hosted) sẽ bị sập đúng lúc chúng tôi cần nó nhất. Nhưng điều đó đã không xảy ra. Trong 14 tháng sử dụng thực tế, hệ thống vẫn hoạt động cực kỳ ổn định vì nó được xây dựng trên các công nghệ tiêu chuẩn và đáng tin cậy.

Grafana OnCall không phải là một khối monolith cồng kềnh. Nó là một tập hợp các dịch vụ chuyên biệt mà bạn có thể mở rộng độc lập:

  • The Engine (Django): Đóng vai trò là bộ não. Nó quản lý lịch trình, logic leo thang (escalation) và các yêu cầu API.
  • Celery Workers: Đây là những “ngựa thồ”. Chúng xử lý các công việc nặng nhọc như gửi tin nhắn Telegram hoặc xử lý các webhook gửi đến từ Prometheus.
  • Redis: Đóng vai trò vừa là cache tốc độ cao, vừa là message broker cho các Celery worker.
  • PostgreSQL: Nguồn dữ liệu tin cậy duy nhất (source of truth). Mọi người dùng, lịch trình và nhật ký sự cố đều được lưu trữ tại đây.

Đối với môi trường production, tôi khuyên bạn nên chuyển database và Redis sang các dịch vụ quản trị (managed services) như AWS RDS. Tuy nhiên, một VPS 2vCPU đơn lẻ với 4GB RAM là quá đủ để xử lý cảnh báo cho một startup quy mô vừa. Thiết lập này đảm bảo dữ liệu sự cố nhạy cảm của bạn nằm trên phần cứng của riêng bạn, chứ không phải trên máy chủ của bên thứ ba.

Chuỗi leo thang và ChatOps cho phản ứng thực tế

Một công cụ thông báo sẽ trở nên vô dụng nếu nhóm của bạn phớt lờ nó. Sau khi instance của bạn đi vào hoạt động, bạn cần xác định cách hệ thống xử lý khi xảy ra sự cố database lúc 2 giờ sáng. Đây là lúc Chuỗi leo thang (Escalation Chains) biến những tiếng ồn ào thành các nhiệm vụ có thể thực thi.

Hãy tránh cái bẫy “thông báo cho tất cả mọi người”. Nó gây ra sự kiệt sức. Thay vào đó, hãy thử chiến lược phân tầng sau:

  1. Cấp độ 1 (Tức thì): Gửi ping cho kỹ sư trực chính qua tin nhắn Telegram hoặc push notification ứng dụng di động.
  2. Cấp độ 2 (Trễ 5 phút): Nếu cảnh báo vẫn chưa được xác nhận (acknowledge), hãy kích hoạt cuộc gọi điện thoại tự động đến kỹ sư trực chính.
  3. Cấp độ 3 (Trễ 10 phút): Nếu vẫn im lặng, hãy leo thang lên kỹ sư dự phòng hoặc quản lý kỹ thuật.

Tích hợp Telegram là một điểm cộng lớn về tốc độ. Các kỹ sư trẻ thường thích nó vì họ có thể xác nhận, giải quyết hoặc chuyển định tuyến cảnh báo trực tiếp từ cửa sổ chat. Để thiết lập, hãy lấy bot token từ @BotFather và thêm nó vào file .env của bạn:

# Bên trong file .env của bạn
TELEGRAM_TOKEN=your_bot_token_here
TELEGRAM_WEBHOOK_HOST=https://your-oncall-domain.com

Khởi động lại các dịch vụ, sau đó liên kết tài khoản Telegram của bạn trong giao diện OnCall UI. Điều này biến một cảnh báo đơn giản thành một luồng thảo luận chung, nơi cả nhóm có thể thấy quá trình khắc phục lỗi diễn ra trong thời gian thực.

Tối ưu vận hành: Giữ cho hệ thống cảnh báo luôn sống

Khi bạn tự lưu trữ hệ thống cảnh báo riêng, bạn là người chịu trách nhiệm nếu nó im lặng khi xảy ra sự cố. Đây là cách tôi giữ cho các instance của mình ổn định:

1. Giám sát trình giám sát

Đừng bao giờ để hệ thống giám sát của bạn trở thành điểm yếu duy nhất (single point of failure). Hãy sử dụng một dịch vụ bên ngoài miễn phí như UptimeRobot để ping vào endpoint sức khỏe của OnCall mỗi 60 giây. Nếu giao diện OnCall bị sập, bạn cần một cảnh báo dự phòng qua một kênh hoàn toàn khác.

2. Sao lưu thông minh

Các bản cập nhật Docker đôi khi có thể làm hỏng schema của database. Luôn dump dữ liệu PostgreSQL trước khi kéo (pull) các image mới. Tôi chạy một cron job lưu bản pg_dump vào một S3 bucket bên ngoài mỗi đêm.

# Kiểm tra sao lưu thủ công
docker exec oncall-postgres pg_dump -U admin oncall_db > backup_$(date +%F).sql

3. Rào chắn tài nguyên

Những “cơn bão cảnh báo” — khi 50 dịch vụ cùng lỗi một lúc — có thể làm tăng vọt mức sử dụng bộ nhớ. Các Celery worker có thể rất tốn tài nguyên. Tôi cấp ít nhất 2GB RAM riêng cho stack OnCall để ngăn trình Linux OOM killer tắt hệ thống trong lúc khủng hoảng.

4. Xác thực tập trung

Đừng quản lý người dùng thủ công. Nếu nhóm của bạn sử dụng GitHub hoặc Google Workspace, hãy kết nối nó với Grafana qua OAuth. OnCall sẽ tự động đồng bộ hóa những người dùng đó, giúp việc đưa nhân viên mới vào lịch trực dễ dàng hơn mà không cần nhập dữ liệu thủ công.

Tự lưu trữ hệ thống quản lý sự cố có vẻ là một bước tiến lớn, nhưng sự kiểm soát mà bạn có được là hoàn toàn xứng đáng với công sức bỏ ra. Bạn có được các công cụ phản ứng chuyên nghiệp và không tốn phí cấp phép cho mỗi người dùng, đồng thời giữ cho dữ liệu hạ tầng của mình luôn nằm dưới sự kiểm soát an toàn.

Share: