Quản lý Log tập trung với Grafana Loki: Hướng dẫn tiết kiệm chi phí cho Kubernetes và Linux

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

Tại sao Loki được gọi là ‘Prometheus cho Logs’

Quản lý log trong một môi trường phân tán thường buộc chúng ta phải đưa ra lựa chọn khó khăn: trả phí đắt đỏ cho các nền tảng SaaS hoặc tự vận hành một stack ELK (Elasticsearch, Logstash, Kibana) tiêu tốn nhiều tài nguyên. Nếu bạn đã từng thử chạy Elasticsearch trên một cluster nhỏ, bạn sẽ biết nó ngốn RAM khủng khiếp như thế nào. Một node Elasticsearch cơ bản cho môi trường production thường yêu cầu ít nhất 8GB RAM chỉ để duy trì sự ổn định. Trong khi đó, Loki có thể xử lý tốc độ nạp dữ liệu tương đương chỉ với chưa đầy 512MB RAM.

Loki thay đổi hoàn toàn cách tiếp cận logging truyền thống. Thay vì đánh chỉ mục (index) mọi từ trong tệp log, nó chỉ đánh chỉ mục metadata — các nhãn (labels) — đi kèm với luồng dữ liệu. Đây chính là chiến lược mà Prometheus sử dụng cho các metrics. Bằng cách tránh đánh chỉ mục toàn văn (full-text indexing), tôi đã cắt giảm được tới 90% chi phí lưu trữ mà vẫn duy trì tốc độ tra cứu cực nhanh. Nó gọn nhẹ, tốc độ và hoàn toàn phù hợp với quy trình DevOps hiện đại.

Bắt đầu nhanh: Vận hành chỉ trong vài phút

Cách tốt nhất để thấy được hiệu quả của Loki là chạy nó ở môi trường local. Cấu hình Docker Compose này sẽ khởi chạy toàn bộ stack: Loki để lưu trữ, Promtail để thu thập log, và Grafana để hiển thị dashboard.

Tạo một tệp docker-compose.yaml:

version: "3"

services:
  loki:
    image: grafana/loki:2.9.0
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:2.9.0
    volumes:
      - /var/log:/var/log
    command: -config.file=/etc/promtail/config.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

Khởi chạy bằng lệnh docker-compose up -d. Sau khi các container đã hoạt động, hãy mở localhost:3000 và đăng nhập bằng thông tin admin mặc định. Thêm Loki làm data source với URL http://loki:3100. Bây giờ bạn đã có thể truy vấn log hệ thống local ngay lập tức.

Tìm hiểu kiến trúc cốt lõi

Loki hoạt động như một hệ sinh thái được phối hợp nhịp nhàng thay vì là một ứng dụng nguyên khối (monolithic). Để tận dụng tối đa, bạn cần hiểu cách ba thành phần này tương tác với nhau.

1. Promtail: Trình thu thập (Collector)

Promtail là agent chạy trên các server của bạn. Trong Kubernetes, nó thường chạy dưới dạng một DaemonSet. Công việc chính của nó là phát hiện các tệp log, gán nhãn như env=prod, và gửi chúng đến Loki. Nó mô phỏng logic service discovery của Prometheus, giúp nó trở nên cực kỳ phù hợp cho các thiết lập cloud-native.

2. Loki: Công cụ lưu trữ (Storage Engine)

Loki là bộ não của cả hệ thống. Nó tiếp nhận các luồng log gửi đến, nhóm chúng theo nhãn và nén thành các chunk. Vì nội dung log thực tế không được đánh chỉ mục, bạn có thể lưu trữ các chunk này trên các dịch vụ lưu trữ đối tượng (object storage) giá rẻ. Các hệ thống như AWS S3 hoặc Google Cloud Storage hoạt động hoàn hảo ở đây, giúp chi phí lưu trữ dài hạn của bạn gần như bằng không.

3. LogQL: Ngôn ngữ truy vấn

Nếu bạn đã từng sử dụng PromQL, LogQL sẽ cảm thấy rất quen thuộc. Nó sử dụng cách tiếp cận hàm để lọc log. Bạn bắt đầu với một bộ chọn nhãn (label selector) và sau đó áp dụng các bộ lọc hoặc regex. Ví dụ:

{job="varlogs"} |= "error" != "timeout"

Lệnh này quét log từ job ‘varlogs’, tìm các dòng chứa từ “error” và bỏ qua bất kỳ dòng nào có chứa “timeout”. Nó đơn giản nhưng cực kỳ mạnh mẽ khi cần xử lý sự cố.

Mở rộng: Triển khai trên Kubernetes

Đối với môi trường Kubernetes, Helm là phương thức triển khai đáng tin cậy nhất. Chart loki-stack giúp đơn giản hóa quy trình bằng cách đóng gói mọi thứ vào một lệnh duy nhất.

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

# Cài đặt Loki stack cùng với Promtail và Grafana
helm install loki-stack grafana/loki-stack \
  --set grafana.enabled=true \
  --set prometheus.enabled=false \
  --set promtail.enabled=true

Promtail tự động phát hiện tất cả các container trong cluster của bạn. Nó lấy metadata từ Kubernetes API, tự động thêm namespace, pod, và tên container dưới dạng nhãn. Khi một dịch vụ gặp lỗi, bạn không còn cần phải lục tìm trong kubectl logs nữa. Chỉ cần lọc theo nhãn pod trong Grafana để thấy chính xác chuyện gì đã xảy ra.

Xử lý log JSON tức thời

Các ứng dụng hiện đại thường ghi log dưới dạng JSON. Loki xử lý việc này bằng cách phân tích cấu trúc trong giai đoạn truy vấn thay vì lúc nạp vào. Điều này giúp cơ sở dữ liệu luôn nhỏ gọn trong khi vẫn mang lại sự linh hoạt của dữ liệu có cấu trúc.

{app="api-gateway"} | json | status_code > 499

Truy vấn này trích xuất trường status_code từ thân JSON và lọc các lỗi phía server. Nó nhanh, hiệu quả và không yêu cầu cấu hình schema trước.

Những bài học xương máu từ thực tế vận hành

Việc vận hành Loki trong môi trường lưu lượng truy cập cao đã dạy cho tôi một vài bài học quan trọng về hiệu năng và quản lý chi phí.

Nguy cơ từ High Cardinality (Độ đa dạng nhãn cao)

Đây là sai lầm phổ biến nhất mà người dùng mới thường mắc phải. Đừng bao giờ sử dụng các dữ liệu động như User ID hoặc địa chỉ IP làm nhãn. Mỗi tổ hợp nhãn duy nhất sẽ tạo ra một “stream” mới trong Loki. Nếu bạn tạo ra 100.000 stream, index sẽ bị phình to và hiệu suất truy vấn sẽ giảm sút nghiêm trọng. Hãy giữ cho các nhãn ở dạng tĩnh (app, env, region) và sử dụng các biểu thức lọc cho dữ liệu động như IP.

Tự động hóa việc dọn dẹp log (Retention)

Mặc dù lưu trữ Loki rẻ, nhưng nó không vô hạn. Hãy định nghĩa chính sách lưu giữ (retention policy) trong limits_config để giữ cho kho lưu trữ của bạn gọn gàng. Với hầu hết các môi trường dev, 7 ngày là quá đủ:

limits_config:
  retention_period: 168h

Đối với production, tôi khuyên bạn nên sử dụng S3 lifecycle policies để chuyển log sang các tầng lưu trữ rẻ hơn như Glacier sau 30 ngày.

Cảnh báo dựa trên mẫu log

Loki không chỉ để xem lại lịch sử; nó còn là một công cụ giám sát chủ động. Bạn có thể tạo các recording rule để kích hoạt cảnh báo khi các mẫu cụ thể xuất hiện. Ví dụ: nếu cụm từ “Connection refused” xuất hiện hơn 20 lần trong 1 phút, Loki có thể gửi thông báo đến Alertmanager. Điều này giúp bạn phát hiện các lỗi hạ tầng trước cả khi khách hàng nhận ra.

Lời kết

Loki không phải là sự thay thế hoàn toàn cho Elasticsearch nếu bạn cần tìm kiếm toàn văn phức tạp và nặng nề trên dữ liệu của nhiều năm. Tuy nhiên, đối với 90% các tác vụ kỹ thuật hàng ngày — debug pod, giám sát tỷ lệ lỗi và kiểm tra truy cập — nó vượt trội hơn hẳn. Nó giúp hạ tầng của bạn nhẹ nhàng và đảm bảo hóa đơn cloud không vượt quá tầm kiểm soát.

Share: