引言:容器化带来的日志与监控挑战
随着Docker和Kubernetes成为应用部署的主流方案,传统的日志和监控方式面临全新挑战。容器的临时性意味着日志随容器销毁而消失,多实例部署使得分散的日志难以集中分析,而微服务架构下的故障定位更需要全链路的监控数据支撑。
本文将从零搭建一套完整的容器化日志采集与监控告警体系,技术栈选择Filebeat + Elasticsearch + Kibana(日志)和Prometheus + Grafana + Alertmanager(监控),全部基于Docker Compose部署,便于快速落地和验证。
一、日志采集架构设计
1.1 为什么选择Filebeat
在容器化环境中,日志采集Agent的选择有三个核心考量:资源占用、侵入性和可靠性。Filebeat基于Go语言编写,内存占用通常在20-50MB之间,支持自动发现Docker容器并适配日志路径,且具备背压敏感机制——当Elasticsearch写入缓慢时,Filebeat会自动降低采集速率,避免数据丢失。
1.2 Docker日志驱动配置
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
json-file驱动是最通用的选择,每行一个JSON对象,包含时间戳和日志流类型(stdout/stderr)。设置max-size和max-file防止单个容器的日志文件无限增长。
1.3 Filebeat自动发现配置
# filebeat.yml - 自动发现Docker容器
filebeat.autodiscover:
providers:
- type: docker
hints.enabled: true
templates:
- condition:
contains:
docker.container.labels.logging: "true"
config:
- type: container
paths:
- /var/lib/docker/containers/${data.docker.container.id}/*.log
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
- decode_json_fields:
fields: ["message"]
target: "json"
overwrite_keys: true
output.elasticsearch:
hosts: ["elasticsearch:9200"]
indices:
- index: "app-logs-%{[docker.container.labels.service]:unknown}-%{+yyyy.MM.dd}"
setup.kibana:
host: "kibana:5601"
setup.ilm.enabled: true
setup.ilm.rollover_alias: "app-logs"
setup.ilm.pattern: "{now/d}-000001"
这个配置的关键点是通过hints模式自动发现带有logging=true标签的容器,并将日志按服务名分类存储到不同的索引中。add_docker_metadata处理器会为每条日志添加容器名称、镜像名、标签等信息,极大方便后续检索。
二、Elasticsearch索引管理
在容器化环境中,日志量增长迅速,必须合理管理索引生命周期。
2.1 索引生命周期策略
PUT _ilm/policy/app-logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "1d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"forcemerge": {
"max_num_segments": 1
},
"shrink": {
"number_of_shards": 1
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
这套策略实现了:热阶段每天滚动或50GB滚动,温阶段7天后合并segment和缩减分片,30天后自动删除。既保证了近期的查询性能,又控制了存储成本。
三、Prometheus监控体系搭建
3.1 基础架构部署
# docker-compose.yml - 监控部分
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.51.0
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
- '--storage.tsdb.retention.size=50GB'
ports:
- "9090:9090"
networks:
- monitor
node-exporter:
image: prom/node-exporter:v1.7.0
container_name: node-exporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
networks:
- monitor
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitor
grafana:
image: grafana/grafana:10.4.0
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
networks:
- monitor
alertmanager:
image: prom/alertmanager:v0.27.0
container_name: alertmanager
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
networks:
- monitor
volumes:
prometheus_data:
grafana_data:
networks:
monitor:
driver: bridge
cAdvisor是容器监控的核心组件,它自动收集所有运行中容器的CPU、内存、网络和磁盘IO指标,并以Prometheus格式暴露。node-exporter则提供宿主机的硬件级指标。
3.2 Prometheus配置与自动发现
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
scrape_configs:
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
labels:
env: 'production'
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'docker-containers'
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 30s
relabel_configs:
- source_labels: ['__meta_docker_container_label_monitoring']
regex: 'true'
action: keep
- source_labels: ['__meta_docker_container_name']
target_label: container
regex: '/(.*)'
末尾的docker_sd_configs部分实现了Docker服务自动发现:只要容器带有monitoring=true标签,就会自动纳入监控。
四、告警规则设计
4.1 核心告警规则
# alert_rules.yml
groups:
- name: container_alerts
rules:
- alert: ContainerHighCpu
expr: rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "容器CPU使用率过高"
- alert: ContainerHighMemory
expr: container_memory_usage_bytes / container_spec_memory_limit_bytes * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "容器内存使用率过高"
- alert: ContainerRestartLoop
expr: increase(container_restart_count[1h]) > 5
for: 10m
labels:
severity: critical
annotations:
summary: "容器频繁重启"
- alert: ContainerOOMKilled
expr: container_oom_events_total > 0
for: 1m
labels:
severity: critical
annotations:
summary: "容器被OOM Killer终止"
- name: system_alerts
rules:
- alert: HostHighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes * 100 > 90
for: 10m
labels:
severity: critical
annotations:
summary: "宿主机磁盘使用率过高"
告警设计的原则是分层分级:warning级别的告警允许较长的for等待时间(避免误报),critical级别的告警则要求快速响应。ContainerOOMKilled是最严重的告警之一,一旦触发需要立即排查内存泄漏或调大容器内存限制。
4.2 Alertmanager路由配置
# alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'container', 'env']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'critical'
repeat_interval: 1h
receivers:
- name: 'default'
webhook_configs:
- url: 'http://notification-service:8080/alert'
send_resolved: true
- name: 'critical'
webhook_configs:
- url: 'http://notification-service:8080/critical-alert'
send_resolved: true
通过路由分派,critical级别的告警会以更短的重复间隔发送,确保不会被忽视。webhook接收端可以对接企业微信、钉钉、飞书等IM工具。
五、Grafana仪表盘配置
Grafana仪表盘的设计应当面向不同角色:运维人员关注系统健康度,开发人员关注应用性能指标。
# 推荐的仪表盘面板布局
## 系统总览面板
# 1. 宿主机CPU/内存/磁盘/网络 四大核心指标折线图
# 2. 运行中容器数量及状态分布
# 3. 活跃告警列表
## 容器详情面板
# 1. 单容器CPU使用率(含limit线)
# 2. 单容器内存使用量(含limit线)
# 3. 容器网络流量(入/出)
# 4. 容器磁盘IO(读/写)
## 关键PromQL查询示例
# 容器CPU使用率
rate(container_cpu_usage_seconds_total{container!=""}[5m]) * 100
# 容器内存使用率
container_memory_working_set_bytes / container_spec_memory_limit_bytes * 100
# 5分钟内HTTP错误率
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100
六、日志与监控的联动分析
实现日志和监控的真正价值,需要建立两者的联动机制:
# 在Grafana中配置Elasticsearch数据源
# 这样可以在同一个仪表盘中查看日志与指标
# 典型联动场景:
# 1. 发现CPU飙升告警 -> 跳转Kibana查看对应时段的错误日志
# 2. 容器重启告警 -> 自动查询最近stdout/stderr日志
# 3. 磁盘使用率告警 -> 分析日志索引大小和增长率
# 在Kibana中创建关联查询
GET app-logs-*/_search
{
"query": {
"bool": {
"must": [
{ "term": { "docker.container.name": "目标容器" } },
{ "range": { "@timestamp": { "gte": "告警触发时间-10m" } } }
]
}
},
"sort": [{ "@timestamp": "desc" }],
"size": 100
}
七、总结
容器化环境下的日志采集与监控告警体系,核心目标是实现三个能力:全量采集不留盲区、快速检索定位问题、主动告警防患未然。
关键实践总结:使用Filebeat自动发现机制降低运维成本;通过ILM策略管理日志生命周期避免存储失控;告警规则遵循分层分级原则减少噪音;Grafana仪表盘面向角色设计提升使用效率;日志与监控联动实现从指标到根因的快速跳转。这套体系可以随着业务规模增长而平滑扩展,从单机Docker到Kubernetes集群都能适用。