Docker 容器日誌收集與管理

Docker Container Logging Collection and Management

Docker 日誌概述

在容器化環境中,日誌管理是維運工作的核心環節。Docker 容器產生的日誌包含應用程式輸出、錯誤訊息及系統事件等重要資訊。有效的日誌收集與管理策略能幫助我們快速診斷問題、監控系統健康狀態,並滿足合規性要求。

Docker 預設會將容器的 stdoutstderr 輸出捕獲為日誌。這些日誌可以透過 docker logs 命令查看:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查看容器日誌
docker logs <container_id>

# 即時追蹤日誌輸出
docker logs -f <container_id>

# 顯示最後 100 行日誌
docker logs --tail 100 <container_id>

# 顯示帶時間戳的日誌
docker logs -t <container_id>

日誌驅動程式

Docker 支援多種日誌驅動程式(Logging Drivers),讓我們能夠將日誌發送到不同的目的地。常用的日誌驅動包括:

驅動程式描述
json-file預設驅動,將日誌儲存為 JSON 格式檔案
syslog將日誌發送到 syslog 伺服器
journald將日誌發送到 systemd journal
fluentd將日誌發送到 Fluentd 收集器
awslogs將日誌發送到 Amazon CloudWatch Logs
gcplogs將日誌發送到 Google Cloud Logging
loki將日誌發送到 Grafana Loki

json-file 驅動設定

json-file 是 Docker 的預設日誌驅動,日誌以 JSON 格式儲存在主機上。

全域設定

編輯 /etc/docker/daemon.json 檔案:

1
2
3
4
5
6
7
8
9
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "labels": "production_status",
    "env": "os,customer"
  }
}

容器層級設定

1
2
3
4
5
docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=5 \
  nginx:latest

日誌檔案預設儲存位置:/var/lib/docker/containers/<container_id>/<container_id>-json.log

syslog 驅動設定

syslog 驅動將容器日誌發送到 syslog 伺服器,適合與現有的日誌基礎設施整合。

基本設定

1
2
3
4
5
6
docker run -d \
  --log-driver syslog \
  --log-opt syslog-address=udp://192.168.1.100:514 \
  --log-opt syslog-facility=daemon \
  --log-opt tag="{{.Name}}/{{.ID}}" \
  nginx:latest

使用 TLS 加密

1
2
3
4
5
6
7
docker run -d \
  --log-driver syslog \
  --log-opt syslog-address=tcp+tls://logs.example.com:514 \
  --log-opt syslog-tls-ca-cert=/etc/ca-certificates/syslog-ca.crt \
  --log-opt syslog-tls-cert=/etc/ssl/certs/syslog.crt \
  --log-opt syslog-tls-key=/etc/ssl/private/syslog.key \
  nginx:latest

fluentd 驅動設定

Fluentd 是一款強大的開源日誌收集器,廣泛應用於雲原生環境。

啟動 Fluentd 容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# fluentd.conf
<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<match docker.**>
  @type file
  path /fluentd/log/docker
  append true
  <format>
    @type json
  </format>
</match>

設定容器使用 fluentd 驅動

1
2
3
4
5
6
7
docker run -d \
  --log-driver fluentd \
  --log-opt fluentd-address=localhost:24224 \
  --log-opt tag="docker.{{.Name}}" \
  --log-opt fluentd-async=true \
  --log-opt fluentd-buffer-limit=8MB \
  nginx:latest

使用 Loki 收集日誌

Grafana Loki 是一款輕量級的日誌聚合系統,與 Grafana 完美整合。

安裝 Loki Docker 驅動

1
docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions

設定容器使用 Loki 驅動

1
2
3
4
5
6
7
8
9
docker run -d \
  --log-driver loki \
  --log-opt loki-url="http://loki:3100/loki/api/v1/push" \
  --log-opt loki-batch-size=400 \
  --log-opt loki-retries=5 \
  --log-opt loki-max-backoff=800ms \
  --log-opt loki-timeout=1s \
  --log-opt loki-external-labels="job=docker,container_name={{.Name}}" \
  nginx:latest

全域 Loki 設定

編輯 /etc/docker/daemon.json

1
2
3
4
5
6
7
8
9
{
  "log-driver": "loki",
  "log-opts": {
    "loki-url": "http://loki:3100/loki/api/v1/push",
    "loki-batch-size": "400",
    "loki-retries": "5",
    "loki-external-labels": "job=docker"
  }
}

日誌輪替設定

為了防止日誌檔案無限增長,必須設定日誌輪替策略。

json-file 驅動的輪替設定

1
2
3
4
5
6
7
8
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "10",
    "compress": "true"
  }
}
  • max-size:單一日誌檔案的最大容量
  • max-file:保留的日誌檔案數量
  • compress:是否壓縮輪替後的日誌檔案

使用 logrotate 管理

建立 /etc/logrotate.d/docker-containers

1
2
3
4
5
6
7
8
9
/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}

Docker Compose 日誌設定

在 Docker Compose 中,可以為每個服務單獨設定日誌驅動。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: '3.8'

services:
  web:
    image: nginx:latest
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
        labels: "production_status,geo"
        env: "os,customer"

  api:
    image: my-api:latest
    logging:
      driver: fluentd
      options:
        fluentd-address: "localhost:24224"
        tag: "docker.{{.Name}}"
        fluentd-async: "true"

  worker:
    image: my-worker:latest
    logging:
      driver: loki
      options:
        loki-url: "http://loki:3100/loki/api/v1/push"
        loki-external-labels: "job=docker,service=worker"

使用 Compose 查看日誌

1
2
3
4
5
6
7
8
# 查看所有服務的日誌
docker-compose logs

# 追蹤特定服務的日誌
docker-compose logs -f web

# 顯示最後 50 行日誌
docker-compose logs --tail 50 api

最佳實踐

1. 應用程式日誌設計

  • 將日誌輸出到 stdoutstderr,而非寫入檔案
  • 使用結構化日誌格式(如 JSON)便於解析
  • 包含足夠的上下文資訊(時間戳、請求 ID、使用者 ID 等)

2. 日誌級別規劃

1
2
3
4
5
DEBUG  -> 開發除錯用,生產環境關閉
INFO   -> 正常運作資訊
WARN   -> 潛在問題警告
ERROR  -> 錯誤訊息
FATAL  -> 致命錯誤

3. 安全性考量

  • 避免在日誌中記錄敏感資訊(密碼、API 金鑰等)
  • 使用 TLS 加密傳輸日誌
  • 設定適當的日誌保留期限

4. 效能優化

  • 設定合理的日誌緩衝區大小
  • 使用非同步日誌傳輸
  • 考慮日誌取樣策略處理高流量場景

5. 監控與告警

  • 設定日誌儲存空間監控
  • 建立關鍵錯誤的告警機制
  • 定期審查日誌收集管道的健康狀態

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy