Sáu tháng trước, tôi bị gọi lúc 2 giờ sáng. Một API endpoint quan trọng đã âm thầm ngừng phản hồi — nhưng hệ thống giám sát của chúng tôi chỉ kiểm tra xem tiến trình có đang chạy không, chứ không kiểm tra xem dịch vụ có thực sự truy cập được từ bên ngoài hay không. Sự cố đó đã thúc đẩy tôi tìm hiểu về black-box monitoring đúng nghĩa, và Prometheus Blackbox Exporter đã được dùng trên production từ đó đến nay.
Khác với giám sát dựa trên agent (đo lường ứng dụng từ bên trong), Blackbox Exporter kiểm tra dịch vụ của bạn theo đúng cách người dùng truy cập — từ bên ngoài. Không cần thay đổi code. Không cần triển khai agent cho từng dịch vụ. Chỉ cần trỏ nó vào một URL, một TCP socket, một DNS resolver hoặc một host để ping, và nó sẽ báo cáo chính xác những gì một người quan sát bên ngoài thấy.
Khởi Động Nhanh: Chạy Được Trong 5 Phút
Cách nhanh nhất là dùng Docker:
docker run -d \
--name blackbox_exporter \
-p 9115:9115 \
prom/blackbox-exporter:latest
Bạn đã có một exporter hoạt động tại http://localhost:9115. Kiểm tra ngay:
# Thăm dò google.com qua HTTP
curl "http://localhost:9115/probe?target=https://google.com&module=http_2xx"
Phản hồi là các metric Prometheus thô — probe_success (1 = hoạt động, 0 = ngừng), thời gian phản hồi, thời hạn chứng chỉ TLS và mã trạng thái HTTP. Tất cả những gì bạn cần mà không cần đụng vào code ứng dụng.
Để chạy production, mount một file cấu hình:
# blackbox.yml
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: [200, 201, 204]
follow_redirects: true
preferred_ip_protocol: "ip4"
tcp_connect:
prober: tcp
timeout: 5s
icmp:
prober: icmp
timeout: 5s
dns_check:
prober: dns
timeout: 5s
dns:
query_name: "example.com"
query_type: "A"
docker run -d \
--name blackbox_exporter \
-p 9115:9115 \
-v ./blackbox.yml:/config/blackbox.yml \
prom/blackbox-exporter:latest \
--config.file=/config/blackbox.yml
Tìm Hiểu Sâu: Hiểu Từng Loại Probe
Blackbox Exporter hỗ trợ bốn loại probe. Biết khi nào nên dùng loại nào quan trọng hơn bạn nghĩ.
HTTP Probe
HTTP probe là nơi tôi dành khoảng 80% thời gian cấu hình. Nó làm được nhiều hơn nhiều so với chỉ kiểm tra xem cổng 80 có mở không — xác thực mã phản hồi, đo thời gian đến byte đầu tiên, xác minh chuỗi TLS và POST request với regex khớp nội dung đều trong tầm tay.
modules:
http_post_json:
prober: http
timeout: 10s
http:
method: POST
headers:
Content-Type: application/json
Authorization: "Bearer your_token_here"
body: '{"ping": "check"}'
valid_status_codes: [200]
fail_if_body_not_matches_regexp:
- '"status":"ok"'
Điều này phát hiện được những gì kiểm tra ở tầng TCP không bao giờ thấy được: một dịch vụ trả về HTTP 200 nhưng lại phục vụ trang lỗi trong nội dung. Tình huống đó xảy ra thường xuyên hơn bạn nghĩ — load balancer cấu hình sai, deploy bị lỗi nửa chừng, health endpoint cũ không còn chính xác.
Giám sát chứng chỉ TLS đáng được đề cập riêng. Metric probe_ssl_earliest_cert_expiry cung cấp Unix timestamp cho chứng chỉ sắp hết hạn gần nhất trong chuỗi. Một rule cảnh báo Prometheus là đủ:
groups:
- name: ssl_expiry
rules:
- alert: SSLCertExpiringSoon
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30
for: 1h
labels:
severity: warning
annotations:
summary: "Chứng chỉ SSL sắp hết hạn trong <30 ngày: {{ $labels.instance }}"
TCP Probe
TCP probe bao gồm các dịch vụ không phải HTTP — database, SMTP, LDAP, các giao thức binary tùy chỉnh. Theo dõi cả probe_success lẫn probe_duration_seconds sẽ phát hiện được các đợt tăng độ trễ ngay cả khi cổng về mặt kỹ thuật vẫn đang chấp nhận kết nối.
modules:
tcp_postgres:
prober: tcp
timeout: 5s
tcp:
preferred_ip_protocol: "ip4"
tcp_smtp_starttls:
prober: tcp
timeout: 10s
tcp:
query_response:
- expect: "^220 "
- send: "EHLO prober\r\n"
- expect: "^250-STARTTLS"
Tính năng query/response thực sự hữu ích — bạn có thể xác minh rằng SMTP server của bạn đang sử dụng đúng giao thức, chứ không chỉ đơn giản là cổng 25 đang chấp nhận kết nối.
ICMP Probe
Ping cổ điển, tích hợp vào Prometheus stack hiện có của bạn. Tôi dùng ICMP probe cho hạ tầng mạng — router, firewall, điểm cuối VPN tunnel. Trên Linux, binary cần quyền raw socket:
# Với cài đặt binary trực tiếp
sudo setcap cap_net_raw+ep blackbox_exporter
# Với Docker, dùng --privileged (hãy cẩn thận về phạm vi)
docker run -d --privileged \
-p 9115:9115 \
prom/blackbox-exporter:latest
DNS Probe
Giám sát DNS là thứ mà hầu hết các team bỏ qua cho đến khi một sự cố propagation CDN hoặc một record bị xóa nhầm gây ra downtime. DNS probe kiểm tra rằng các record cụ thể phân giải đúng như bạn mong đợi:
modules:
dns_a_record:
prober: dns
timeout: 5s
dns:
transport_protocol: "udp"
preferred_ip_protocol: "ip4"
query_name: "api.yourapp.com"
query_type: "A"
validate_answer_rrs:
fail_if_not_matches_regexp:
- "api.yourapp.com.\t.*\tIN\tA\t203.0.113."
Điều này xác nhận không chỉ là DNS phản hồi, mà còn trả về đúng dải IP — phát hiện cấu hình sai trước khi người dùng gặp phải vấn đề.
Sử Dụng Nâng Cao: Tích Hợp Vào Prometheus
Đứng một mình, Blackbox Exporter đã hữu ích. Tích hợp vào Prometheus với relabeling, nó trở nên mạnh mẽ hơn nhiều. Mẹo ở đây là truyền URL đích dưới dạng query parameter cho exporter thay vì dùng làm địa chỉ scrape:
# prometheus.yml
scrape_configs:
- job_name: "blackbox_http"
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://yourapp.com/health
- https://api.yourapp.com/v1/status
- https://yourapp.com/login
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox_exporter:9115
- job_name: "blackbox_tcp"
metrics_path: /probe
params:
module: [tcp_connect]
static_configs:
- targets:
- postgres-primary:5432
- redis-cluster:6379
- kafka-broker:9092
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox_exporter:9115
Block relabeling này làm hai việc: sao chép địa chỉ đích vào một query parameter, sau đó ghi đè địa chỉ scrape để trỏ tới exporter. Mỗi kết quả mang URL đích gốc làm nhãn instance — giữ cho dashboard của bạn dễ đọc.
Các Câu Truy Vấn PromQL Hữu Ích cho Grafana
Grafana dashboard cộng đồng ID 7587 là điểm khởi đầu vững chắc. Dưới đây là các câu truy vấn tôi luôn thêm thủ công:
# Phần trăm uptime trong 24h
avg_over_time(probe_success{job="blackbox_http"}[24h]) * 100
# Thời gian phản hồi HTTP ở phân vị 95
histogram_quantile(0.95, rate(probe_http_duration_seconds_bucket[5m]))
# Số ngày còn lại đến khi chứng chỉ SSL hết hạn
(probe_ssl_earliest_cert_expiry - time()) / 86400
Mẹo Thực Tế Từ Sáu Tháng Chạy Production
Chạy hệ thống này trên production sáu tháng đồng nghĩa với việc học được một số điều mà tài liệu không nói rõ. Đây là những gì tôi muốn nói với bản thân mình từ đầu.
Đặt timeout ngắn hơn scrape interval. Nếu cả hai đều là 30 giây, một đích chậm sẽ chặn toàn bộ chu kỳ scrape. Hãy giữ probe timeout ở mức 60–70% scrape interval của bạn.
Giám sát từ nhiều vị trí. Một instance Blackbox Exporter cho bạn biết liệu dịch vụ có vẻ ngừng hoạt động từ vị trí đó không. Hai hoặc ba instance ở các region khác nhau cho bạn biết đó là vấn đề routing, outage theo vùng hay lỗi dịch vụ thực sự. Thêm nhãn probe_location vào mỗi scrape config — từ đó, một label selector trong Grafana sẽ phân tách chúng gọn gàng.
Đừng probe quá thường xuyên. Ban đầu tôi dùng khoảng thời gian probe 10 giây cho 50 endpoint — đó là 300 HTTP request bên ngoài mỗi phút, chỉ từ tầng giám sát. Với hầu hết các endpoint, khoảng 30–60 giây là đủ.
Dùng debug endpoint khi cài đặt. Khi một probe hoạt động không như mong đợi, thêm &debug=true:
curl "http://localhost:9115/probe?target=https://yourapp.com&module=http_2xx&debug=true"
Điều này trả về log chi tiết từng bước — thời gian phân giải DNS, thời gian TCP handshake, đàm phán TLS, chuỗi redirect HTTP. Bạn sẽ giải quyết vấn đề trong vài phút thay vì vài giờ.
Cảnh báo theo thời gian probe, không chỉ probe_success. Trang đăng nhập phản hồi trong 8 giây về mặt kỹ thuật là “hoạt động” nhưng trên thực tế đã hỏng. Cảnh báo khi probe_duration_seconds > 3 sẽ phát hiện hiệu năng suy giảm trước khi trở thành sự cố được báo cáo.
Dùng cảnh báo hết hạn SSL hai giai đoạn. Cảnh báo ở mốc 30 ngày và lại ở mốc 7 ngày. Bỏ lỡ cảnh báo đầu tiên sẽ không trực tiếp gây ra sự cố, nhưng bỏ lỡ cảnh báo 7 ngày thì có thể.
Thêm một dịch vụ mới tốn chưa đến một phút: một dòng target trong Prometheus scrape config. Dịch vụ đó ngay lập tức được giám sát về tính khả dụng, thời gian phản hồi và hiệu lực chứng chỉ. Không cần cài đặt agent. Không cần thay đổi ứng dụng. Không cần phối hợp với team khác.

