功能介紹
什麼是容器性能監控?
容器性能監控是指收集、分析和可視化容器化應用程序的運行時指標,包括CPU使用率、內存消耗、網絡I/O、磁盤I/O等關鍵性能指標。
日誌管理的重要性
- 故障排查:快速定位和解決應用問題
- 性能優化:識別性能瓶頸和優化機會
- 安全審計:檢測安全事件和異常行為
- 合規性:滿足法規要求和審計需求
監控和日誌挑戰
- 數據量大:容器環境產生的日誌和指標數據量巨大
- 動態性:容器的短暫性和動態調度增加了監控難度
- 多維度:需要從主機、容器、應用等多個維度進行監控
- 實時性:要求實時或近實時的監控和告警能力
使用教程
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 |
查看所有容器統計 |