Ghi nhật ký tập trung cho HomeLab của bạn: Giám sát mọi thứ với Grafana Loki

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Mê cung giám sát HomeLab: Một vấn đề thực tế

Trong nhiều năm, việc quản lý HomeLab của tôi giống như một trò chơi trốn tìm liên tục với các tệp nhật ký. Tôi chạy kết hợp nhiều dịch vụ, chẳng hạn như các vùng chứa Docker cho máy chủ truyền thông như Jellyfin, máy ảo cho môi trường phát triển và thậm chí một số thiết bị IoT xuất ra dữ liệu. Mỗi dịch vụ và thiết bị tạo ra luồng nhật ký riêng biệt. Những nhật ký này thường được cất giữ trong các thư mục khác nhau, định dạng tệp đa dạng hoặc chỉ có thể truy cập thông qua các lệnh cụ thể.

Khi có sự cố xảy ra – một vùng chứa bị lỗi, một ứng dụng hoạt động thất thường hoặc các vấn đề về mạng – quá trình chẩn đoán là một công việc thủ công đầy khó khăn trên hàng chục tệp nhật ký. Tôi sẽ SSH vào các máy khác nhau, `tail -f` một tệp nhật ký ở đây, `grep` tìm lỗi ở đó, cố gắng ghép nối một bức tranh mạch lạc. Cách tiếp cận phân mảnh này không chỉ kém hiệu quả; nó thường có nghĩa là tôi phản ứng chậm, khắc phục sự cố rất lâu sau khi chúng bắt đầu gây ra các vấn đề đáng chú ý. Đó là một dấu hiệu rõ ràng cho thấy tôi cần một giải pháp tốt hơn.

Phân tích nguyên nhân gốc rễ: Tại sao nhật ký phân tán lại gây đau đầu

Vấn đề cốt lõi với các tệp nhật ký phân tán nằm ở việc thiếu khả năng hiển thị và tương quan tập trung. Khi mỗi thành phần hoạt động trong silo riêng, các tệp nhật ký của nó sẽ bị cô lập một cách tự nhiên. Hãy xem xét các vấn đề chính sau:

  • Không có chế độ xem thống nhất: Không có giao diện duy nhất để xem tất cả dữ liệu vận hành đồng thời. Việc chuyển đổi giữa các thiết bị đầu cuối hoặc giao diện web khác nhau chỉ để xem nhật ký rất mệt mỏi và tốn thời gian.
  • Khắc phục sự cố kém hiệu quả: Việc xác định nguyên nhân gốc rễ của một sự cố trở thành một cuộc điều tra pháp y đầy thách thức. Máy chủ web chậm có phải do cơ sở dữ liệu bị chậm hay dịch vụ lưu vào bộ nhớ đệm bị lỗi? Nếu không có cách nào để xem tất cả các mục nhật ký liên quan từ các hệ thống khác nhau cạnh nhau, việc tương quan các sự kiện giữa các dịch vụ là vô cùng khó khăn.
  • Bỏ lỡ các sự bất thường: Các mẫu tinh tế hoặc lỗi không thường xuyên dễ dàng bị bỏ qua khi sàng lọc thủ công hàng gigabyte văn bản. Một dấu hiệu cảnh báo sớm trong một tệp nhật ký có thể bị bỏ lỡ hoàn toàn nếu bạn tập trung vào nơi khác.
  • Không có giám sát chủ động: Nếu không có hệ thống tập trung để tổng hợp và phân tích nhật ký, việc thiết lập cảnh báo cho các sự kiện quan trọng là thực tế không thể. Bạn chỉ phát hiện ra các vấn đề khi chúng làm hỏng thứ gì đó một cách rõ ràng, thay vì được thông báo khi hoạt động bất thường bắt đầu.

Kinh nghiệm cá nhân của tôi đã nhiều lần nhấn mạnh những điểm này. Ví dụ, rò rỉ bộ nhớ trong một vùng chứa có thể gây ra việc sử dụng CPU cao ở một vùng chứa khác do tăng số lần thử lại. Việc theo dõi hiệu ứng xếp tầng này thông qua các tệp nhật ký khác nhau là một cơn ác mộng, thường mất hàng giờ.

So sánh các giải pháp: ELK Stack so với Grafana Loki

Nhận thấy cần một cách tốt hơn, tôi bắt đầu tìm hiểu các giải pháp ghi nhật ký tập trung. Hai ứng cử viên chính nổi bật là ELK Stack và Grafana Loki.

ELK Stack (Elasticsearch, Logstash, Kibana)

ELK Stack là một lão làng trong lĩnh vực này, cung cấp một bộ công cụ mạnh mẽ và giàu tính năng:

  • Elasticsearch: Công cụ tìm kiếm có khả năng mở rộng cao này xử lý tất cả các loại dữ liệu, đặc biệt xuất sắc trong tìm kiếm toàn văn bản và tổng hợp phức tạp.
  • Logstash: Một đường ống xử lý dữ liệu thu thập nhật ký từ nhiều nguồn khác nhau, chuyển đổi chúng, sau đó gửi chúng đến Elasticsearch.
  • Kibana: Lớp trực quan hóa này nằm trên Elasticsearch, cung cấp các bảng điều khiển phong phú, khả năng tìm kiếm mạnh mẽ và báo cáo chi tiết.

Ưu điểm: ELK rất mạnh mẽ để phân tích nhật ký chuyên sâu. Nó cung cấp khả năng tìm kiếm đặc biệt và một bộ sưu tập plugin khổng lồ. Đối với các hoạt động cấp doanh nghiệp với các loại dữ liệu đa dạng và nhu cầu truy vấn phức tạp, đây là một lựa chọn vững chắc. Nhiều tổ chức lớn dựa vào nó vì lý do chính đáng.

Nhược điểm: Đối với môi trường HomeLab, dấu chân tài nguyên của ELK có thể đáng kể. Đặc biệt, Elasticsearch là một ứng dụng dựa trên Java yêu cầu lượng RAM và CPU đáng kể.

Việc thiết lập và duy trì cả ba thành phần, cấu hình đường ống Logstash và tối ưu hóa chỉ mục Elasticsearch có thể liên quan đến một đường cong học tập dốc và một khoản đầu tư thời gian đáng kể. Tôi đã xem xét ELK ban đầu, nhưng chi phí cho HomeLab tương đối khiêm tốn của tôi (ví dụ: Raspberry Pi 4 hoặc NUC công suất thấp) cảm thấy không cân xứng với lợi ích. Tôi muốn một cái gì đó hiệu quả mà không tiêu tốn một nửa tài nguyên của HomeLab của tôi chỉ để giám sát nửa còn lại.

Grafana Loki

Ngược lại, Grafana Loki áp dụng một triết lý khác. Nó thường được mô tả là “Prometheus cho nhật ký,” nhấn mạnh hiệu quả và sự đơn giản:

  • Promtail: Tác nhân nhẹ này thu thập nhật ký từ nhiều nguồn khác nhau (tệp, vùng chứa Docker, nhật ký systemd) và gửi chúng một cách hiệu quả đến Loki.
  • Loki: Bản thân hệ thống tổng hợp nhật ký. Không giống như Elasticsearch, Loki không lập chỉ mục *toàn bộ nội dung* của nhật ký. Thay vào đó, nó chỉ lập chỉ mục siêu dữ liệu (nhãn) liên quan đến các luồng nhật ký. Nhật ký sau đó được nén và lưu trữ trong bộ lưu trữ đối tượng hoặc tệp cục bộ, tiết kiệm đáng kể không gian.
  • Grafana: Công cụ trực quan hóa và tạo bảng điều khiển được sử dụng rộng rãi này truy vấn Loki bằng ngôn ngữ truy vấn tùy chỉnh của nó, LogQL, giúp nhiều người dùng đã quen thuộc.

Ưu điểm: Loki đặc biệt tiết kiệm tài nguyên vì nó chỉ lập chỉ mục siêu dữ liệu, không phải toàn bộ nội dung nhật ký. Điều này làm cho nó nhẹ hơn nhiều về lưu trữ và CPU, thường chỉ yêu cầu vài trăm MB RAM, ngay cả với khối lượng nhật ký vừa phải.

Nó tích hợp liền mạch với Grafana, mà nhiều người dùng HomeLab đã sử dụng để giám sát số liệu. Việc thiết lập tương đối đơn giản và sự đơn giản trong vận hành là một điểm cộng lớn cho HomeLab. Đối với tôi, bản chất nhẹ và tích hợp với các bảng điều khiển Grafana hiện có là những điểm bán hàng chính.

Nhược điểm: Khả năng truy vấn của Loki (LogQL) rất mạnh mẽ để lọc và tổng hợp dựa trên nhãn. Tuy nhiên, chúng không cung cấp độ sâu tìm kiếm toàn văn bản tùy ý như Elasticsearch. Nếu bạn thường xuyên cần thực hiện các tìm kiếm toàn văn bản rất phức tạp, không được lập chỉ mục trên các tập dữ liệu lớn, ELK vẫn có thể phù hợp hơn. Tuy nhiên, để xác định các vấn đề và giám sát các mẫu nhật ký đã biết trong HomeLab, cách tiếp cận của Loki là quá đủ và thường nhanh hơn cho các truy vấn được nhắm mục tiêu.

Cách tiếp cận lý tưởng cho HomeLab: Ứng dụng Grafana Loki

Sau khi đánh giá cả hai lựa chọn, tôi tự tin quyết định chọn Grafana Loki cho HomeLab của mình. Thiết kế nhẹ, lưu trữ hiệu quả và tích hợp nguyên bản với Grafana đã khiến nó trở thành người chiến thắng rõ ràng cho nhu cầu của tôi. Nó đạt được sự cân bằng tuyệt vời giữa quản lý nhật ký mạnh mẽ và tiết kiệm tài nguyên, làm cho nó trở nên hoàn hảo cho các môi trường bị hạn chế.

Đây là cách tôi thiết lập hệ thống ghi nhật ký tập trung của mình bằng Docker Compose, kết hợp Loki, Promtail và Grafana trong một ngăn xếp gắn kết.

Hướng dẫn triển khai: Thiết lập Loki với Docker Compose


mkdir ~/loki-stack
cd ~/loki-stack
nano docker-compose.yaml

Dán nội dung sau vào `docker-compose.yaml`. Cấu hình này thiết lập Grafana, Loki và Promtail. Lưu ý cách Promtail được cấu hình để gắn ổ cắm Docker, cho phép nó tự động phát hiện và thu thập nhật ký từ các vùng chứa đang chạy khác.


version: "3.8"

networks:
  loki:

volumes:
  grafana_data:
  loki_data:

services:
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=your_secure_grafana_password
    networks:
      - loki
    restart: unless-stopped

  loki:
    image: grafana/loki:latest
    container_name: loki
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml # Đảm bảo đường dẫn này là chính xác
      - loki_data:/loki
    networks:
      - loki
    restart: unless-stopped

  promtail:
    image: grafana/promtail:latest
    container_name: promtail
    command: -config.file=/etc/promtail/config.yaml
    volumes:
      - ./promtail-config.yaml:/etc/promtail/config.yaml # Đảm bảo đường dẫn này là chính xác
      - /var/log:/var/log
      - /var/lib/docker/containers:/var/lib/docker/containers:ro # Đối với nhật ký vùng chứa Docker
      - /run/docker.sock:/run/docker.sock:ro # Để phát hiện các vùng chứa Docker
    networks:
      - loki
    restart: unless-stopped

Tiếp theo, tạo tệp cấu hình Loki, có tên `loki-config.yaml`, trong cùng thư mục:


nano loki-config.yaml

auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage_config:
    boltdb_shipper:
      active_index_directory: /loki/boltdb-shipper-active
      cache_location: /loki/boltdb-shipper-cache
    filesystem:
      directory: /loki/chunks
  replication_factor: 1
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory

query_range:
  # thời gian chờ truy vấn: 10 giây

schema_config:
  configs:
    - from: 2020-10-27
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      period: 24h

compactor:
  working_directory: /loki/boltdb-shipper-compactor
  shared_store: filesystem

Bây giờ, hãy tạo cấu hình của Promtail, `promtail-config.yaml`, trong đó chỉ định chính xác những nhật ký nào nó nên thu thập:


nano promtail-config.yaml

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          __path__:
            - /var/log/*.log
            - /var/log/*/*.log

  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 5s
        filters:
          - name: label
            values: ['logging=promtail']
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: container
      - source_labels: ['__meta_docker_container_id']
        target_label: container_id
      - source_labels: ['__meta_docker_image_name']
        target_label: image

Lưu ý về cấu hình Docker của Promtail: Phần `filters` trong công việc `docker` thực sự quan trọng. Nó đảm bảo Promtail sẽ *chỉ* thu thập nhật ký từ các vùng chứa Docker có nhãn `logging=promtail`. Điều này ngăn Promtail thu thập nhật ký từ mọi vùng chứa, điều này có thể dễ dàng làm quá tải hệ thống của bạn. Để bật ghi nhật ký cho một vùng chứa cụ thể, chỉ cần thêm một mục `labels:` vào cấu hình `docker-compose.yaml` của nó, như sau:


  my_app:
    image: my_image:latest
    labels:
      - logging=promtail
    # ... các cấu hình khác

Khi tất cả các tệp này đã được tạo, hãy khởi động ngăn xếp của bạn bằng Docker Compose:


docker-compose up -d

Cấu hình Grafana và Truy vấn nhật ký

Truy cập phiên bản Grafana của bạn (thường là `http://your-homelab-ip:3000`). Đăng nhập bằng thông tin xác thực mặc định: `admin` cho tên người dùng và `your_secure_grafana_password` (mà bạn đã đặt trong `docker-compose.yaml`) cho mật khẩu.

  1. Thêm Loki làm nguồn dữ liệu:
    • Chuyển đến Cấu hình (biểu tượng bánh răng ở bên trái) và chọn “Data Sources.”
    • Nhấp vào “Add data source” và sau đó chọn “Loki” từ danh sách.
    • Đối với URL, nhập `http://loki:3100`. Điều này hoạt động vì Grafana và Loki nằm trên cùng một mạng Docker.
    • Nhấp vào “Save & Test.” Bạn sẽ thấy thông báo xác nhận như “Data source is working.”
  2. Khám phá nhật ký của bạn:
    • Chuyển đến Khám phá (biểu tượng la bàn ở bên trái).
    • Chọn nguồn dữ liệu Loki mới được cấu hình của bạn.
    • Bây giờ bạn có thể sử dụng LogQL để truy vấn nhật ký của mình một cách hiệu quả.

Ví dụ LogQL cơ bản:

  • `{job=”docker”}`: Xem tất cả nhật ký vùng chứa Docker.
  • `{job=”docker”, container=”my_app”}`: Xem nhật ký cụ thể từ một vùng chứa có tên `my_app`.
  • `{job=”varlogs”, filename=”/var/log/syslog”} |= “error”`: Tìm kiếm từ “error” trong syslog của hệ thống của bạn.
  • `{job=”docker”, container=”jellyfin”} |~ “fail|error”`: Tìm các dòng chứa “fail” hoặc “error” trong nhật ký Jellyfin của bạn.

Những truy vấn đơn giản này chứng minh khả năng lọc mạnh mẽ theo nhãn. Bạn cũng có thể sử dụng các hàm để tổng hợp, chẳng hạn như `count_over_time({job=”docker”}[5m])`, để xem tốc độ nhật ký trong 5 phút qua.

Lợi ích sau sáu tháng: Sự ổn định và thông tin chi tiết rõ ràng

Tôi đã áp dụng cách tiếp cận này trong môi trường HomeLab giống như sản xuất và kết quả luôn ổn định và sáng tỏ. Sáu tháng trôi qua, trải nghiệm giám sát HomeLab của tôi đã cải thiện đáng kể. Dưới đây là những lợi ích tức thì tôi đã quan sát được:

  • Khắc phục sự cố nhanh chóng: Khi có vấn đề phát sinh, tôi đi thẳng đến trang Khám phá của Grafana. Một truy vấn LogQL nhanh chóng, lọc theo dịch vụ hoặc vùng chứa, thường xác định được vấn đề chỉ trong vài giây. Việc tương quan các sự kiện giữa các dịch vụ giờ đây trở nên tầm thường; tôi chỉ cần thêm một bộ lọc nhãn khác vào cùng một truy vấn. Điều này đã giảm thời gian khắc phục sự cố ước tính 70%.
  • Giám sát chủ động: Với nhật ký được tập trung hóa, tôi đã dễ dàng thiết lập cảnh báo Grafana cho các mẫu nhật ký quan trọng. Ví dụ, nếu một vùng chứa cụ thể ghi nhật ký hơn năm lỗi “failed connection” trong vòng một phút, tôi sẽ nhận được thông báo ngay lập tức qua Telegram. Điều này cho phép tôi giải quyết các vấn đề tiềm ẩn trước khi chúng leo thang thành các sự cố lớn.
  • Phân tích lịch sử: Việc hiểu các xu hướng dài hạn, chẳng hạn như thời gian hoạt động của dịch vụ, mức tiêu thụ tài nguyên dẫn đến lỗi hoặc tần suất của các sự kiện nhất định, giờ đây rất đơn giản. Tôi có thể dễ dàng quay ngược thời gian (ví dụ: truy xuất nhật ký từ 3 tháng trước) để điều tra các sự cố trong quá khứ hoặc phân tích các xu hướng hiệu suất trong nhiều tuần hoặc nhiều tháng.
  • Hiệu quả tài nguyên: Loki thực sự giữ đúng lời hứa của mình. Nó chạy trơn tru trên máy chủ HomeLab công suất thấp của tôi (một Intel NUC với 8GB RAM), tiêu thụ CPU và RAM tối thiểu (thường dưới 5% CPU và 200MB RAM), để lại nhiều tài nguyên cho các dịch vụ thực tế của tôi. Việc sử dụng lưu trữ cho nhật ký cũng rất hợp lý, nhờ vào việc lập chỉ mục dựa trên nhãn và nén hiệu quả, thường lưu trữ hàng gigabyte nhật ký trong hàng trăm megabyte không gian đĩa.

Nó thực sự đã thay đổi cách tôi tương tác và quản lý HomeLab của mình. Những ngày phải cuộn qua các tệp văn bản vô tận đã qua rồi. Bây giờ, tôi có một cái nhìn rõ ràng, có thể hành động vào mọi ngóc ngách trong cơ sở hạ tầng của mình, giúp tôi duy trì một môi trường gia đình đáng tin cậy và hiệu quả hơn.

Nhìn về phía trước

Việc thiết lập Grafana Loki để ghi nhật ký tập trung là một trong những quyết định tốt nhất tôi đã đưa ra cho HomeLab của mình. Nó làm sáng tỏ hành vi của hệ thống, trao quyền bảo trì chủ động và tiết kiệm vô số giờ khắc phục sự cố. Đối với bất kỳ ai đang chạy một HomeLab phức tạp vừa phải, một giải pháp ghi nhật ký tập trung không chỉ là một sự xa xỉ; đó là một sự cần thiết.

Với Loki, sự cần thiết đó vừa mạnh mẽ vừa có thể đạt được, ngay cả trên các tài nguyên hạn chế. Bước tiếp theo của tôi bao gồm tích hợp thêm các nhật ký ứng dụng tùy chỉnh và có thể khám phá định tuyến cảnh báo nâng cao với các công cụ như Alertmanager, nhưng hiện tại, sự ổn định và thông tin chi tiết tôi đã đạt được là rất lớn. Tôi thực sự khuyên dùng nó.

Share: