Docker Log Driver & Fluent-bit: Giải pháp ‘cứu cánh’ cho hệ thống Microservices

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Đừng để việc quản lý log trở thành gánh nặng

Cảnh tượng SSH vào server rồi gõ mỏi tay lệnh docker logs -f cho 20-30 microservices mỗi khi hệ thống “hắt hơi sổ mũi” thực sự là một cực hình. Nếu bạn chỉ chạy 1-2 container trên VPS cỏ, cách này vẫn ổn. Nhưng khi quy mô phình to, việc lục lọi từng file log để tìm lỗi chẳng khác nào mò kim đáy bể.

Mặc định, Docker sử dụng json-file log driver. Cơ chế này ghi toàn bộ stdout/stderr vào một file JSON trên ổ cứng host. Mình từng chứng kiến một server sập nguồn chỉ sau 4 tiếng vì log file phình lên tới 50GB do quên cấu hình log-rotate.

Trong một dự án e-commerce trước đây, mình mất trắng 2 ngày chỉ để tìm nguyên nhân memory leak. Container bị crash liên tục, Docker tự khởi động lại và thế là log cũ bốc hơi sạch sẽ. Sau cú vấp đó, mình nhận ra: Muốn chuyên nghiệp, nhất định phải dùng Fluent-bit để gom log tập trung.

Fluent-bit: Kẻ hủy diệt Logstash trong phân khúc nhẹ cân

Nhiều anh em thường nghĩ ngay đến ELK Stack khi nói về logging. Tuy nhiên, Logstash chạy trên JVM và cực kỳ ngốn tài nguyên. Nó thường “ăn” ít nhất 500MB RAM chỉ để khởi động. Với các server cấu hình vừa phải, việc dành ra 1GB RAM chỉ để chạy một con bot thu thập log là quá xa xỉ.

Fluent-bit là một câu chuyện khác. Viết bằng ngôn ngữ C, nó chỉ tiêu tốn khoảng 15-20MB RAM nhưng đủ sức xử lý hàng nghìn log events mỗi giây. Trong kiến trúc này, Docker Fluentd Log Driver sẽ đẩy log sang Fluent-bit. Từ đó, Fluent-bit sẽ điều phối dữ liệu đến Elasticsearch, Loki hoặc đơn giản là lưu vào một file tập trung.

3 bước triển khai hệ thống Logging tập trung

Bước 1: Thiết lập file cấu hình Fluent-bit

Đầu tiên, hãy tạo file fluent-bit.conf. File này đóng vai trò bộ não, chỉ định nơi nhận và nơi gửi log:

[SERVICE]
    Flush        1
    Daemon       Off
    Log_Level    info
    Parsers_File parsers.conf

[INPUT]
    Name   forward
    Listen 0.0.0.0
    Port   24224

[OUTPUT]
    Name   stdout
    Match  *

Mình sử dụng input forward để lắng nghe qua port 24224. Output tạm thời để là stdout. Cách này giúp chúng ta dễ dàng debug và thấy log hiện ngay trên console của Fluent-bit.

Bước 2: Triển khai Fluent-bit với Docker Compose

Sử dụng Docker Compose giúp việc quản lý “máy hút log” này trở nên nhàn hạ hơn. Bạn tạo file docker-compose.yml như sau:

services:
  fluent-bit:
    image: fluent/fluent-bit:latest
    container_name: fluent-bit
    volumes:
      - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
    ports:
      - "24224:24224"
      - "24224:24224/udp"
    restart: always

Chỉ cần gõ docker-compose up -d, hệ thống thu thập log đã sẵn sàng hoạt động.

Bước 3: Cấu hình ứng dụng để đẩy log

Thay vì để Docker tự ghi log vào file JSON, chúng ta sẽ hướng dòng dữ liệu sang Fluent-bit. Có hai cách thực hiện:

Cách 1: Dùng lệnh Run trực tiếp

docker run --log-driver=fluentd \
           --log-opt fluentd-address=localhost:24224 \
           --log-opt tag="web-app-production" \
           nginx

Cách 2: Cấu hình trong Docker Compose (Khuyên dùng)

services:
  web-app:
    image: nginx:latest
    logging:
      driver: fluentd
      options:
        fluentd-address: "localhost:24224"
        tag: "nginx.logs"
        fluentd-async: "true"

Tin mình đi, option fluentd-async: "true" là cứu cánh đấy. Nếu Fluent-bit bị sập mà không bật async, container ứng dụng của bạn có thể bị treo (blocking I/O). Chế độ không đồng bộ giúp ứng dụng vẫn chạy mượt mà dù hệ thống log gặp sự cố.

Kiểm tra và vận hành thực tế

Sau khi khởi chạy, hãy truy cập ứng dụng để tạo ra vài dòng log. Kiểm tra kết quả bằng lệnh:

docker logs -f fluent-bit

Nếu thấy log Nginx hiện ra dưới dạng JSON kèm tag nginx.logs, bạn đã thành công. Để chuyên nghiệp hơn, hãy đổi phần [OUTPUT] để đẩy log về Grafana Loki:

[OUTPUT]
    Name        loki
    Match       *
    Host        loki-server-address
    Port        3100
    Labels      job=docker_logs

Những bài học “xương máu” khi vận hành

Để hệ thống logging không trở thành gánh nặng, bạn cần lưu ý 3 điểm then chốt:

  • Cấu hình Buffer: Nếu Elasticsearch phản hồi chậm, Fluent-bit sẽ tích log vào RAM. Khi RAM đầy, log sẽ bị drop. Hãy cấu hình storage.type filesystem để đệm log xuống ổ cứng khi cần thiết.
  • Tagging thông minh: Đừng đặt tag chung chung. Sử dụng các biến như {{.Name}} để phân biệt log giữa các instance khác nhau của cùng một service.
  • Bảo mật: Port 24224 mặc định không có password. Đừng bao giờ mở public port này trên VPS nếu không muốn kẻ xấu spam log làm đầy ổ cứng của bạn.

Việc setup Fluent-bit ban đầu có thể tốn thêm 15-20 phút. Tuy nhiên, sự yên tâm khi hệ thống vận hành ổn định là phần thưởng hoàn toàn xứng đáng.

Share: