Grafana LGTM & Alloy (2)
Ý kiến
0
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chào mừng bạn quay lại với series triển khai Observability. Ở bài trước, chúng ta đã setup xong hạ tầng cơ bản, network và chuẩn bị sẵn sàng các resource.
Hôm nay, với tư cách là một người thực chiến, mình sẽ hướng dẫn bạn bước vào phần lõi của kiến trúc mới này: Bước 1 - Deploy Grafana Alloy.
Chúng ta sẽ bỏ qua những rườm rà không cần thiết và tập trung thẳng vào stack của Grafana.
Trong mô hình LGTM (Loki, Grafana, Tempo, Mimir/Prometheus), Alloy đóng vai trò là "người vận chuyển" (Collector) duy nhất. Thay vì trước đây bạn phải cài Promtail (để lấy logs), Telegraf hoặc Node Exporter (để lấy metrics), và OpenTelemetry Collector (để lấy traces), thì bây giờ Alloy làm tất cả.
Nếu không có Alloy, các component như Loki, Tempo hay Prometheus sẽ không có data để ingest. Do đó, nguyên tắc là: Collector phải sống và sẵn sàng nhận/kéo data trước khi các thành phần lưu trữ được khởi chạy.
Vì chúng ta đang chạy trên Docker Swarm, Alloy cần được deploy dưới dạng global service. Điều này đảm bảo mỗi node trong cụm (manager hay worker) đều có đúng một container Alloy chạy để thu thập logs và metrics của chính node đó.
Tạo file alloy-compose.yml:
YAML
services:
alloy:
image: grafana/alloy:v1.15.1 # Luôn cập nhật bản mới nhất
environment:
- HOSTNAME={{.Node.Hostname}}
volumes:
- ./config/config.alloy:/etc/alloy/config.alloy:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
# Dùng để lấy metrics hệ thống
- /:/host/root:ro,rslave
- /sys:/host/sys:ro
- /proc:/host/proc:ro
command:
- run
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
networks:
- observability-net
deploy:
mode: global
resources:
limits:
memory: 512M
update_config:
parallelism: 1
delay: 10s
order: stop-first
networks:
observability-net:
external: true
config.alloy (Target: Mimir)Điểm khác biệt lớn nhất ở đây là component prometheus.remote_write. Khi dùng Mimir, chúng ta thường quan tâm đến tenant_id (để phân quyền hoặc chia dự án sau này).
Tạo file config/config.alloy:
Code snippet
// ==========================================
// 1. ĐỊA CHỈ GỬI DATA (DESTINATIONS)
// ==========================================
// Forward Metrics tới Grafana Mimir
prometheus.remote_write "mimir_distributor" {
endpoint {
url = "http://mimir:8080/api/v1/push"
// Mimir mặc định hỗ trợ multi-tenancy.
// "anonymous" là tenant mặc định nếu bạn chưa bật auth.
headers = {
"X-Scope-OrgID" = "primary_cluster",
}
}
}
// Forward Logs tới Loki
loki.write "loki_ingester" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
// Forward Traces tới Tempo (OTLP)
otelcol.exporter.otlp "tempo_ingester" {
client {
endpoint = "tempo:4317"
tls {
insecure = true
}
}
}
// ==========================================
// 2. THU THẬP METRICS (INTERNAL & EXTERNAL)
// ==========================================
// Metrics của chính hệ thống (Node Exporter mode)
prometheus.exporter.unix "node_metrics" {
rootfs_path = "/host/root"
sysfs_path = "/host/sys"
procfs_path = "/host/proc"
}
prometheus.scrape "node_exporter" {
targets = prometheus.exporter.unix.node_metrics.targets
forward_to = [prometheus.remote_write.mimir_distributor.receiver]
}
// Nếu bạn có các server chạy node_exporter v1.10.2 bên ngoài
prometheus.scrape "external_legacy_nodes" {
targets = [
{"__address__" = "10.0.0.50:9100", "instance" = "old-db-server"},
]
forward_to = [prometheus.remote_write.mimir_distributor.receiver]
}
// ==========================================
// 3. THU THẬP LOGS (DOCKER SWARM)
// ==========================================
discovery.docker "swarm_containers" {
host = "unix:///var/run/docker.sock"
}
loki.source.docker "logs_from_containers" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.swarm_containers.targets
forward_to = [loki.process.relabel_logs.receiver]
}
loki.process "relabel_logs" {
forward_to = [loki.write.loki_ingester.receiver]
stage.docker { }
stage.labels {
values = {
stack = "__meta_docker_swarm_service_label_com_docker_stack_namespace",
service = "__meta_docker_swarm_service_name",
node = "__meta_docker_host",
}
}
}
// ==========================================
// 4. RECEIVER CHO APP (OTLP)
// ==========================================
otelcol.receiver.otlp "app_receiver" {
grpc { endpoint = "0.0.0.0:4317" }
http { endpoint = "0.0.0.0:4318" }
output {
metrics = [otelcol.processor.batch.default.input]
traces = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
output {
metrics = [otelcol.exporter.prometheus.mimir.input]
traces = [otelcol.exporter.otlp.tempo_ingester.input]
}
}
// Chuyển đổi OTLP metrics sang Prometheus format để Mimir hiểu được
otelcol.exporter.prometheus "mimir" {
forward_to = [prometheus.remote_write.mimir_distributor.receiver]
}
Sử dụng lệnh quen thuộc để cập nhật stack:
Bash
docker stack deploy -c alloy-compose.yml obs
Kinh nghiệm cho Senior:
X-Scope-OrgID: Khi dùng Mimir, hãy luôn đặt header này trong Alloy. Sau này khi bạn có nhiều khách hàng hoặc nhiều môi trường (Dev/Staging/Prod) chung một stack, bạn chỉ cần đổi giá trị này để tách biệt data hoàn toàn trên Grafana mà không cần dựng thêm Mimir mới.
Alloy UI: Truy cập http://<node-ip>:12345/graph. Nếu bạn thấy các ô prometheus.remote_write hiện màu xanh lá cây nhưng có thông báo lỗi HTTP, đó là vì Mimir chưa được deploy. Đừng lo lắng, Alloy có cơ chế Retry & Buffering (lưu tạm vào RAM/Disk) để chờ Mimir sống dậy.
Alloy hiện đã sẵn sàng đóng vai trò:
Node Exporter: Lấy metrics server.
Promtail: Lấy logs container.
OTLP Collector: Nhận trace và metrics từ ứng dụng.
Tiếp theo, chúng ta sẽ bắt tay vào dựng Bước 2: Deploy Loki.