Triển khai Loki và Promtail trên Kubernetes
Cài đặt Loki qua Helm
Chúng ta sẽ sử dụng Helm chart chính thức của Grafana để deploy Loki. Mục tiêu là thiết lập một cụm Loki đơn giản (Single-binary) cho môi trường Hybrid Cloud, đủ để xử lý log từ cả on-premise và cloud.
Tại sao: Helm là tiêu chuẩn công nghiệp để quản lý lifecycle của ứng dụng trên Kubernetes, giúp việc upgrade và rollback trở nên đơn giản hơn so với YAML thuần.
Kết quả mong đợi: Namespace 'logging' được tạo và Loki chạy với 3 pod (gateway, backend, index-gateway) hoặc 1 pod tùy cấu hình.
Trước tiên, thêm repository của Grafana và cài đặt Loki với cấu hình mặc định tối ưu cho môi trường demo/hybrid.
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install loki grafana/loki-stack --namespace logging --create-namespace --set loki.enabled=true --set loki.persistence.enabled=false --set promtail.enabled=false --set grafana.enabled=false --set loki.storage.type=boltdb-shipper
Verify: Kiểm tra trạng thái pod của Loki.
kubectl get pods -n logging | grep loki
Cấu hình Promtail để thu thập Log từ Container
Promtail đóng vai trò là agent thu thập log từ các container và gửi về Loki. Chúng ta sẽ cấu hình nó để đọc file log của Docker container (`/var/log/containers/*.log`) và thêm label dựa trên namespace và pod name.
Tại sao: Đọc file log container trực tiếp là cách an toàn và hiệu quả nhất trong Kubernetes mà không cần xâm phạm vào runtime của container (sidecar pattern).
Kết quả mong đợi: Promtail chạy trên mọi node (hoặc daemonset) và bắt đầu forward log về Loki.
Tạo file cấu hình `promtail.yaml` với content hoàn chỉnh dưới đây. Lưu ý đường dẫn file log và cấu trúc label.
cat > /tmp/promtail-config.yaml
Deploy Promtail dưới dạng DaemonSet để đảm bảo mỗi node đều có agent thu thập log.
cat > /tmp/promtail-deploy.yaml
Áp dụng cấu hình và deployment.
kubectl apply -f /tmp/promtail-deploy.yaml
Verify: Kiểm tra pod Promtail và xem log của chính nó để đảm bảo nó đang kết nối được với Loki.
kubectl get pods -n logging | grep promtail
kubectl logs -n logging -l app=promtail --tail=20
Cấu hình Log Forwarding cho môi trường Hybrid
Tích hợp Grafana Agent cho môi trường On-Premise (Node cũ)
Đối với các node on-premise không chạy Kubernetes hoặc chạy container engine khác (như Docker standalone), chúng ta sẽ dùng Grafana Agent để forward log về Loki.
Tại sao: Grafana Agent cung cấp khả năng cấu hình linh hoạt hơn cho các môi trường hybrid, cho phép scrape log từ file system trực tiếp mà không cần Kubernetes SD.
Kết quả mong đợi: Log từ server on-premise được gộp chung vào stream log của Loki.
Tạo file cấu hình `agent.yaml` trên server on-premise.
cat > /etc/grafana/agent/config.yaml
Chạy Grafana Agent trên on-premise (giả sử đã cài đặt binary).
grafana-agent run -config.file=/etc/grafana/agent/config.yaml
Verify: Kiểm tra xem log từ on-premise có xuất hiện trong Loki hay không bằng cách query trực tiếp.
curl -X POST http://loki-gateway.logging.svc.cluster.local:3100/loki/api/v1/query_range \
-d '{
"query": "{environment=\"on-premise\"}",
"start": "2023-01-01T00:00:00Z",
"end": "2023-12-31T23:59:59Z",
"limit": 10
}'
Triển khai Log Retention Policy và Nén dữ liệu
Cấu hình Retention Policy để tiết kiệm chi phí
Để tránh tốn phí lưu trữ, chúng ta cần cấu hình Loki để tự động xóa log cũ. Với Loki (boltdb-shipper), điều này được thực hiện qua tham số `retention_period`.
Tại sao: Dữ liệu log tăng theo cấp số nhân. Việc xóa log cũ (ví dụ > 30 ngày) giúp giảm đáng kể chi phí S3 hoặc EBS.
Kết quả mong đợi: Log cũ hơn 30 ngày sẽ bị xóa tự động vào mỗi chu kỳ compaction.
Cập nhật Helm release của Loki với tham số retention. Lưu ý: Cần scale lại hoặc restart Loki để áp dụng cấu hình mới nếu đang dùng persistent volume, hoặc chỉnh trực tiếp vào values.yaml trước khi install.
helm upgrade loki grafana/loki-stack --namespace logging --set loki.retention_period=720h --set loki.storage.type=boltdb-shipper --set loki.storage.boltdb-shipper.retention_period=720h
Verify: Kiểm tra cấu hình của Loki.
kubectl get deployment loki -n logging -o jsonpath='{.spec.template.spec.containers[0].command}' | grep retention
Bật tính năng nén (Compression) cho dữ liệu Log
Loki hỗ trợ nén dữ liệu trước khi lưu vào backend storage (S3/GCS/Azure) hoặc boltdb-shipper. Chúng ta sẽ bật gzip để giảm dung lượng lưu trữ.
Tại sao: Nén gzip giảm kích thước file log từ 50-70%, tiết kiệm băng thông và chi phí lưu trữ.
Kết quả mong đợi: File log được lưu dưới dạng `.gz`.
Cập nhật cấu hình Loki để bật compression.
helm upgrade loki grafana/loki-stack --namespace logging --set loki.storage.boltdb-shipper.compression_type=gzip
Cấu hình Query Log trong Grafana
Thêm Data Source Loki vào Grafana
Để xem log, chúng ta cần cấu hình Grafana kết nối với Loki. Grafana đã có sẵn plugin Loki, chỉ cần thêm URL đúng.
Tại sao: Grafana là giao diện trực quan hóa duy nhất cần thiết cho cả Metrics (Prometheus) và Logs (Loki), tạo nên hệ thống Observability thống nhất.
Kết quả mong đợi: Data source "Loki" xuất hiện trong danh sách của Grafana và có thể query được.
Truy cập vào Grafana (IP:Port), vào Configuration -> Data Sources -> Add data source -> Chọn Loki.
Cấu hình URL và Access Mode:
- URL:
http://loki-gateway.logging.svc.cluster.local:3100 (nếu truy cập từ bên ngoài cluster, dùng public IP hoặc NodePort)
- Access:
Proxy
- Tick "Save & Test" để verify kết nối.
Verify: Sau khi save, bạn sẽ thấy thông báo "Data source is working".
Sử dụng syntax PromQL cho Log Query
Loki sử dụng LogQL, một ngôn ngữ query tương tự PromQL. Chúng ta sẽ thực hiện các query cơ bản để lọc và phân tích log.
Tại sao: Hiểu syntax LogQL giúp bạn khai thác tối đa dữ liệu log, tương tự như cách bạn dùng PromQL cho metrics.
Kết quả mong đợi: Hiển thị dòng log cụ thể theo label và nội dung.
Mở tab "Explore" trong Grafana, chọn Data Source "Loki". Nhập các query sau:
{job="kubernetes-pods"} |= "error"
Query này lọc tất cả log từ job kubernetes-pods có chứa từ "error".
{environment="on-premise"} |= "connection refused" | json | __error__ != ""
Query này lọc log từ môi trường on-premise, tìm từ "connection refused", parse JSON và lọc các dòng lỗi.
count_over_time({app="myapp"}[1h])
Query này đếm số lượng dòng log của app "myapp" trong 1 giờ qua, chuyển đổi log thành dạng metric (count).
Verify: Bạn sẽ thấy bảng kết quả hoặc biểu đồ (nếu chuyển sang dạng Time series) trong phần Explore của Grafana.
Điều hướng series:
Mục lục: Series: Series: Xây dựng hệ thống observability toàn diện (Logging, Metrics, Tracing) cho môi trường Hybrid Cloud với Prometheus, Grafana và OpenTelemetry
« Phần 2: Triển khai nền tảng Metrics: Cài đặt Prometheus trong môi trường Hybrid
Phần 4: Triển khai nền tảng Tracing: Tích hợp OpenTelemetry Collector »