功能介紹

什麼是容器性能監控?

容器性能監控是指收集、分析和可視化容器化應用程序的運行時指標,包括CPU使用率、內存消耗、網絡I/O、磁盤I/O等關鍵性能指標。

日誌管理的重要性

  1. 故障排查:快速定位和解決應用問題
  2. 性能優化:識別性能瓶頸和優化機會
  3. 安全審計:檢測安全事件和異常行為
  4. 合規性:滿足法規要求和審計需求

監控和日誌挑戰

  1. 數據量大:容器環境產生的日誌和指標數據量巨大
  2. 動態性:容器的短暫性和動態調度增加了監控難度
  3. 多維度:需要從主機、容器、應用等多個維度進行監控
  4. 實時性:要求實時或近實時的監控和告警能力

使用教程

Docker內置監控命令

# 查看容器資源使用統計
docker stats

# 查看特定容器的統計信息
docker stats container-name

# 實時查看多個容器的統計信息
docker stats container1 container2 container3

# 以JSON格式輸出統計信息
docker stats --format json container-name

# 限制輸出的統計字段
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" container-name

容器日誌查看和管理

# 查看容器日誌
docker logs container-name

# 實時查看日誌
docker logs -f container-name

# 查看最近的日誌條目
docker logs --tail 100 container-name

# 查看特定時間段的日誌
docker logs --since "2023-01-01T00:00:00" container-name
docker logs --until "2023-01-01T12:00:00" container-name

# 查看帶時間戳的日誌
docker logs -t container-name

# 查看詳細日誌信息
docker logs --details container-name

日誌驅動配置

# 使用JSON文件日誌驅動(默認)
docker run --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3 nginx

# 使用syslog日誌驅動
docker run --log-driver=syslog --log-opt syslog-address=tcp://localhost:514 nginx

# 使用fluentd日誌驅動
docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 nginx

# 使用awslogs日誌驅動
docker run --log-driver=awslogs --log-opt awslogs-region=us-east-1 --log-opt awslogs-group=myLogGroup nginx

# 使用gelf日誌驅動
docker run --log-driver=gelf --log-opt gelf-address=udp://localhost:12201 nginx

自定義監控指標

# 使用cAdvisor監控容器
docker run -d \
  --name=cadvisor \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  gcr.io/cadvisor/cadvisor:latest

# 使用Prometheus監控Docker
# 創建prometheus.yml配置文件
cat > prometheus.yml << EOF
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'docker'
    static_configs:
      - targets: ['localhost:9323']
EOF

# 運行Prometheus
docker run -d \
  --name=prometheus \
  -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

案例講解

案例一:搭建完整的監控系統

# 1. 創建監控網絡
docker network create monitoring

# 2. 部署cAdvisor用於容器監控
docker run -d \
  --name=cadvisor \
  --network=monitoring \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  gcr.io/cadvisor/cadvisor:latest

# 3. 部署Prometheus用於指標收集
cat > prometheus.yml << EOF
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']
EOF

docker run -d \
  --name=prometheus \
  --network=monitoring \
  -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

# 4. 部署Grafana用於數據可視化
docker run -d \
  --name=grafana \
  --network=monitoring \
  -p 3000:3000 \
  grafana/grafana

# 5. 配置應用容器以支持監控
docker run -d \
  --name=monitored-app \
  --network=monitoring \
  --log-driver=json-file \
  --log-opt max-size=10m \
  nginx:alpine

# 6. 訪問監控界面
# cAdvisor: http://localhost:8080
# Prometheus: http://localhost:9090
# Grafana: http://localhost:3000 (默認用户密碼 admin/admin)

案例二:日誌收集和分析系統

# 1. 部署ELK Stack用於日誌收集和分析
# Elasticsearch
docker run -d \
  --name elasticsearch \
  --network monitoring \
  -p 9200:9200 \
  -p 9300:9300 \
  -e "discovery.type=single-node" \
  docker.elastic.co/elasticsearch/elasticsearch:7.17.0

# Logstash
cat > logstash.conf << EOF
input {
  beats {
    port => 5044
  }
}

filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" }
  }
  date {
    match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "docker-logs-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}
EOF

docker run -d \
  --name logstash \
  --network monitoring \
  -p 5044:5044 \
  -v $(pwd)/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
  docker.elastic.co/logstash/logstash:7.17.0

# Kibana
docker run -d \
  --name kibana \
  --network monitoring \
  -p 5601:5601 \
  -e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" \
  docker.elastic.co/kibana/kibana:7.17.0

# 2. 配置應用容器使用日誌收集
docker run -d \
  --name logging-app \
  --network monitoring \
  --log-driver=fluentd \
  --log-opt fluentd-address=logstash:5044 \
  nginx:alpine

# 3. 訪問Kibana進行日誌分析
# Kibana: http://localhost:5601

案例三:自定義應用監控

# 1. 創建帶監控端點的應用
mkdir monitoring-app
cat > monitoring-app/app.py << EOF
from flask import Flask, jsonify
import psutil
import time

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello Monitoring!'

@app.route('/metrics')
def metrics():
    cpu_percent = psutil.cpu_percent(interval=1)
    memory = psutil.virtual_memory()
    disk = psutil.disk_usage('/')
    
    return jsonify({
        'cpu_percent': cpu_percent,
        'memory_total': memory.total,
        'memory_used': memory.used,
        'memory_percent': memory.percent,
        'disk_total': disk.total,
        'disk_used': disk.used,
        'disk_percent': disk.percent
    })

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
EOF

cat > monitoring-app/requirements.txt << EOF
Flask==2.0.1
psutil==5.8.0
EOF

cat > monitoring-app/Dockerfile << EOF
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]
EOF

# 2. 構建和運行應用
docker build -t monitoring-app monitoring-app/

docker run -d \
  --name monitored-app \
  --network monitoring \
  -p 5000:5000 \
  monitoring-app

# 3. 創建監控腳本
cat > monitor-script.sh << EOF
#!/bin/bash

while true; do
  echo "=== Container Stats ==="
  docker stats --no-stream --format "table {{.Container}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}"
  
  echo "=== Application Metrics ==="
  curl -s http://localhost:5000/metrics | jq '.'
  
  echo "=== Recent Logs ==="
  docker logs --tail 5 monitored-app
  
  echo ""
  sleep 10
done
EOF

chmod +x monitor-script.sh

# 4. 運行監控腳本
./monitor-script.sh

常見問題解答

Q1: 如何優化日誌性能?

A: 優化日誌性能的方法:

# 1. 配置日誌輪轉
docker run \
  --log-driver=json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  my-app

# 2. 使用異步日誌驅動
docker run \
  --log-driver=syslog \
  --log-opt syslog-address=udp://localhost:514 \
  my-app

# 3. 過濾不必要的日誌
# 在應用中實現日誌級別控制
# 設置INFO/WARN/ERROR級別而非DEBUG

# 4. 使用外部日誌收集器
# 部署Fluentd、Logstash等日誌收集器
docker run -d \
  --name fluentd \
  -p 24224:24224 \
  -v /data:/fluentd/log \
  fluent/fluentd:latest

# 5. 配置日誌採樣
# 在應用層面實現日誌採樣,避免過多重複日誌

Q2: 如何處理監控數據存儲?

A: 監控數據存儲的最佳實踐:

# 1. 選擇合適的存儲後端
# Prometheus本地存儲適用於短期存儲
# 對於長期存儲,考慮使用Thanos、Cortex等解決方案

# 2. 配置數據保留策略
# Prometheus配置示例
cat > prometheus-retention.yml << EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

# 數據保留時間
storage:
  tsdb:
    retention.time: 30d
EOF

# 3. 使用遠程存儲
# 配置Prometheus遠程寫入到長期存儲
cat > prometheus-remote-write.yml << EOF
remote_write:
  - url: "http://remote-storage:9090/api/v1/write"
    write_relabel_configs:
      - source_labels: [__name__]
        regex: 'container_.+'
        action: keep
EOF

# 4. 定期備份監控數據
# 創建備份腳本
cat > backup-monitoring.sh << EOF
#!/bin/bash
# 備份Prometheus數據
docker exec prometheus tar czf - /prometheus > prometheus-backup-\$(date +%Y%m%d).tar.gz

# 備份Grafana配置
docker exec grafana tar czf - /var/lib/grafana > grafana-backup-\$(date +%Y%m%d).tar.gz
EOF

Q3: 如何設置有效的告警機制?

A: 設置有效告警機制的方法:

# 1. 配置Prometheus告警規則
cat > alert-rules.yml << EOF
groups:
- name: container-alerts
  rules:
  - alert: HighContainerCPU
    expr: rate(container_cpu_usage_seconds_total[5m]) > 0.8
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage on container {{ \$labels.container }}"
      description: "{{ \$labels.container }} CPU usage is above 80% for more than 2 minutes."

  - alert: HighContainerMemory
    expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.8
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "High memory usage on container {{ \$labels.container }}"
      description: "{{ \$labels.container }} memory usage is above 80% for more than 2 minutes."
      
  - alert: ContainerDown
    expr: absent(container_last_seen)
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Container down"
      description: "Container has disappeared."
EOF

# 2. 部署Alertmanager處理告警
cat > alertmanager.yml << EOF
route:
  receiver: 'slack-notifications'

receivers:
- name: 'slack-notifications'
  slack_configs:
  - api_url: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
    channel: '#alerts'
    send_resolved: true
EOF

docker run -d \
  --name alertmanager \
  --network monitoring \
  -p 9093:9093 \
  -v $(pwd)/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
  prom/alertmanager

# 3. 配置健康檢查
docker run -d \
  --name health-checked-app \
  --health-cmd="curl -f http://localhost:80/ || exit 1" \
  --health-interval=30s \
  --health-timeout=10s \
  --health-retries=3 \
  --health-start-period=5s \
  nginx:alpine

最佳實踐

1. 監控最佳實踐

  • 實施分層監控(基礎設施、平台、應用)
  • 設置合理的監控指標採集頻率
  • 建立基線性能指標
  • 實現實時監控和歷史數據分析
  • 定期審查和優化監控配置

2. 日誌管理最佳實踐

  • 統一日誌格式和結構
  • 實施日誌輪轉和清理策略
  • 集中化日誌收集和存儲
  • 實現日誌搜索和分析能力
  • 建立日誌安全和訪問控制

3. 告警最佳實踐

  • 設置合理的告警閾值
  • 避免告警疲勞(過多無效告警)
  • 實現告警分級和路由
  • 建立告警響應和處理流程
  • 定期審查和優化告警規則

4. 性能優化實踐

  • 監控關鍵性能指標
  • 識別和解決性能瓶頸
  • 實施容量規劃
  • 優化資源配置
  • 建立性能基準和趨勢分析

命令速查表

命令 描述
docker stats 查看容器資源使用統計
docker stats --format 格式化輸出統計信息
docker logs <container> 查看容器日誌
docker logs -f <container> 實時查看日誌
docker logs --since/--until 查看特定時間段日誌
docker system df 查看Docker磁盤使用情況
docker events 查看Docker事件
docker top <container> 查看容器進程
docker inspect <container> 查看容器詳細信息
docker ps -q | xargs docker stats 查看所有容器統計