mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-11 12:21:17 +00:00
Fix wrong links
This commit is contained in:
268
19_observability/19.1_prometheus.md
Normal file
268
19_observability/19.1_prometheus.md
Normal file
@@ -0,0 +1,268 @@
|
||||
## 19.1 Prometheus + Grafana
|
||||
|
||||
Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。
|
||||
|
||||
[Prometheus](https://prometheus.io/) 是一个开源的系统监控和报警工具包。它受 Google Borgmon 的启发,由 SoundCloud 在 2012 年创建。
|
||||
|
||||
### 19.1.1 架构简介
|
||||
|
||||
Prometheus 的主要组件包括:
|
||||
|
||||
* **Prometheus Server**:核心组件,负责收集和存储时间序列数据。
|
||||
* **Exporters**:负责向 Prometheus 暴露监控数据 (如 Node Exporter,cAdvisor)。
|
||||
* **Alertmanager**:处理报警发送。
|
||||
* **Pushgateway**:用于支持短生命周期的 Job 推送数据。
|
||||
|
||||
### 19.1.2 快速部署
|
||||
|
||||
我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。
|
||||
|
||||
本节示例使用了:
|
||||
|
||||
* `node-exporter`:采集宿主机指标 (CPU、内存、磁盘、网络等)。
|
||||
* `cAdvisor`:采集容器指标 (容器 CPU/内存/网络 IO、文件系统等)。
|
||||
|
||||
在生产环境中,建议将 Prometheus 的数据目录做持久化,并显式配置数据保留周期。
|
||||
|
||||
#### 1. 准备配置文件
|
||||
|
||||
创建 `prometheus.yml`:
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'node-exporter'
|
||||
static_configs:
|
||||
- targets: ['node-exporter:9100']
|
||||
|
||||
- job_name: 'cadvisor'
|
||||
static_configs:
|
||||
- targets: ['cadvisor:8080']
|
||||
|
||||
rule_files:
|
||||
- /etc/prometheus/rules.yml
|
||||
```
|
||||
|
||||
#### 2. 编写 Docker Compose 文件
|
||||
|
||||
创建 `compose.yaml` (或 `docker-compose.yml`):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- ./rules.yml:/etc/prometheus/rules.yml
|
||||
- prometheus_data:/prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --storage.tsdb.path=/prometheus
|
||||
- --storage.tsdb.retention.time=15d
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
networks:
|
||||
- monitoring
|
||||
depends_on:
|
||||
- prometheus
|
||||
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
ports:
|
||||
- "9100:9100"
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
cadvisor:
|
||||
image: gcr.io/cadvisor/cadvisor:latest
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:ro
|
||||
- /sys:/sys:ro
|
||||
- /var/lib/docker/:/var/lib/docker:ro
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
networks:
|
||||
monitoring:
|
||||
|
||||
volumes:
|
||||
prometheus_data:
|
||||
```
|
||||
|
||||
#### 3. 启动服务
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker compose up -d
|
||||
```
|
||||
|
||||
启动后,访问以下地址:
|
||||
|
||||
* Prometheus: `http://localhost:9090`
|
||||
* Grafana:`http://localhost:3000` (默认账号密码:admin/admin)
|
||||
|
||||
### 19.1.3 配置 Grafana 面板
|
||||
|
||||
1. 在 Grafana 中添加 Prometheus 数据源,URL 填写 `http://prometheus:9090`。
|
||||
2. 导入现成的 Dashboard 模板,例如 [Node Exporter Full](https://grafana.com/grafana/dashboards/1860) (ID:1860) 和 [Docker Container](https://grafana.com/grafana/dashboards/193) (ID:193)。
|
||||
|
||||
这样,你就拥有了一个直观的容器监控大屏。
|
||||
|
||||
### 19.1.4 生产要点与告警闭环
|
||||
|
||||
完成部署后,建议补齐以下生产要点。
|
||||
|
||||
#### 指标采集的“最小闭环”
|
||||
|
||||
1. 在 Prometheus 页面打开 **Status -> Targets**,确认 `prometheus`、`node-exporter`、`cadvisor` 的 `State` 均为 `UP`。
|
||||
2. 在 **Graph** 中尝试查询:
|
||||
|
||||
* `up`
|
||||
* `rate(container_cpu_usage_seconds_total[5m])`
|
||||
|
||||
3. 在 Grafana Dashboard 中重点关注:
|
||||
|
||||
* 宿主机 CPU/Load/内存/磁盘
|
||||
* 容器 CPU/内存使用率、容器重启次数
|
||||
|
||||
如果你发现“面板为空”,通常不是 Grafana 的问题,而是 Prometheus 没抓到数据或查询标签与 Dashboard 不匹配。
|
||||
|
||||
#### 常见问题排查
|
||||
|
||||
* **Target down**:检查容器网络是否互通,端口是否暴露到同一网络,以及 exporter 是否在容器内正常监听。
|
||||
* **cAdvisor 无数据或报错**:确认挂载了 Docker 目录与宿主机的 `/sys`、`/var/run` 等路径,并确保宿主机上 Docker 运行正常。
|
||||
* **指标缺失**:确认你的 Docker/内核版本与 cAdvisor 兼容;对于 containerd 等运行时,采集方式会不同。
|
||||
|
||||
#### 关键指标速查 (节点/容器)
|
||||
|
||||
在生产环境排障时,建议优先关注下面几类指标,并在 Grafana 面板中建立对应的常用视图。
|
||||
|
||||
* **节点 CPU 使用率**:`100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)`
|
||||
* **节点内存使用率**:`(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100`
|
||||
* **节点磁盘空间使用率**:`(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100`
|
||||
* **容器 CPU**:`sum by (name) (rate(container_cpu_usage_seconds_total[5m]))`
|
||||
* **容器内存**:`sum by (name) (container_memory_working_set_bytes)`
|
||||
|
||||
说明:不同版本的 cAdvisor/Docker 对 label 命名可能存在差异 (如 `name`、`container`、`container_name`),如果查询为空,建议先用 `label_values(container_cpu_usage_seconds_total, __name__)` 或在 Prometheus 的图形界面查看可用 label。
|
||||
|
||||
#### Targets down 排错清单
|
||||
|
||||
当 **Status -> Targets** 出现 `DOWN` 时,建议按以下顺序排查:
|
||||
|
||||
1. **网络连通性**:Prometheus 容器是否能解析并访问目标 (同一 Docker network、DNS、端口)。
|
||||
2. **端口/路径**:确认 exporter 监听端口与 Prometheus 配置一致;必要时在 Prometheus 容器内 `curl http://node-exporter:9100/metrics`。
|
||||
3. **权限/挂载**:cAdvisor 需要访问宿主机 `/sys`、`/var/lib/docker` 等挂载路径,缺失会导致指标不全或报错。
|
||||
4. **时间问题**:宿主机与容器时间偏差过大可能导致“数据看起来断档”,需要检查 NTP/时区配置。
|
||||
5. **目标本身异常**:确认 exporter 容器是否在重启,查看 `docker logs`。
|
||||
|
||||
#### 告警 (Alertmanager) 建议
|
||||
|
||||
生产环境建议引入 Alertmanager 做告警聚合与路由,并在 Prometheus 中配置 `alerting` 与 `rule_files`。
|
||||
|
||||
为了保持“最小告警闭环”,建议至少覆盖两类告警:
|
||||
|
||||
* **采集链路告警**:例如 `up == 0`,用于发现 exporter 或网络故障。
|
||||
* **资源风险告警**:例如节点磁盘空间不足,用于提前发现容量风险。
|
||||
|
||||
##### 1. 准备告警规则文件
|
||||
|
||||
创建 `rules.yml`:
|
||||
|
||||
```yaml
|
||||
groups:
|
||||
- name: docker_practice
|
||||
rules:
|
||||
- alert: PrometheusTargetDown
|
||||
expr: up == 0
|
||||
for: 2m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Prometheus 抓取目标不可达"
|
||||
description: "Job={{ $labels.job }}, Instance={{ $labels.instance }}"
|
||||
|
||||
- alert: HostDiskSpaceLow
|
||||
expr: |
|
||||
(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) < 0.10
|
||||
for: 10m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "磁盘可用空间不足"
|
||||
description: "Instance={{ $labels.instance }}, Mountpoint={{ $labels.mountpoint }}"
|
||||
```
|
||||
|
||||
说明:这里的规则是“可用空间低于 10%”的阈值告警,并非“未来 24 小时写满”的预测。生产环境建议针对特定文件系统与挂载点做更精确的过滤。
|
||||
|
||||
##### 2. 配置 Prometheus 加载规则并接入 Alertmanager
|
||||
|
||||
修改 `prometheus.yml`,增加:
|
||||
|
||||
```yaml
|
||||
rule_files:
|
||||
- /etc/prometheus/rules.yml
|
||||
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- static_configs:
|
||||
- targets: ["alertmanager:9093"]
|
||||
```
|
||||
|
||||
并在 Compose 中挂载规则文件。
|
||||
|
||||
##### 3. 部署 Alertmanager
|
||||
|
||||
创建 `alertmanager.yml`:
|
||||
|
||||
```yaml
|
||||
route:
|
||||
receiver: default
|
||||
|
||||
receivers:
|
||||
- name: default
|
||||
webhook_configs:
|
||||
- url: http://example.com/webhook
|
||||
```
|
||||
|
||||
再在 `compose.yaml` 增加服务:
|
||||
|
||||
```yaml
|
||||
alertmanager:
|
||||
image: prom/alertmanager:latest
|
||||
volumes:
|
||||
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
|
||||
ports:
|
||||
- "9093:9093"
|
||||
networks:
|
||||
- monitoring
|
||||
```
|
||||
|
||||
生产环境中,建议将告警发送到可追踪的渠道 (如 IM 机器人、事件平台、工单系统),并在告警中附带 Dashboard 链接与排障入口,避免告警成为噪声。
|
||||
|
||||
#### 建议的文件清单
|
||||
|
||||
为了避免示例难以复现,建议在同一目录下准备以下文件:
|
||||
|
||||
* `compose.yaml`:Prometheus、Grafana、exporters、Alertmanager 的部署文件
|
||||
* `prometheus.yml`:Prometheus 抓取配置与告警配置
|
||||
* `rules.yml`:告警规则
|
||||
* `alertmanager.yml`:告警路由与接收器配置
|
||||
212
19_observability/19.2_elk.md
Normal file
212
19_observability/19.2_elk.md
Normal file
@@ -0,0 +1,212 @@
|
||||
## 19.2 ELK/EFK 堆栈
|
||||
|
||||
ELK (Elasticsearch,Logstash,Kibana) 是目前业界最流行的开源日志解决方案。而在容器领域,由于 Fluentd 更加轻量级且对容器支持更好,EFK (Elasticsearch,Fluentd,Kibana) 组合也变得非常流行。
|
||||
|
||||
### 19.2.1 方案架构
|
||||
|
||||
我们将采用以下架构:
|
||||
|
||||
1. **Docker Container**:容器将日志输出到标准输出 (stdout/stderr)。
|
||||
2. **Fluentd**:作为 Docker 的 Logging Driver 或运行为守护容器,收集容器日志。
|
||||
3. **Elasticsearch**:存储从 Fluentd 接收到的日志数据。
|
||||
4. **Kibana**:从 Elasticsearch 读取数据并进行可视化展示。
|
||||
|
||||
### 19.2.2 部署流程
|
||||
|
||||
我们将使用 Docker Compose 来一键部署整个日志堆栈。
|
||||
|
||||
#### 1. 编写 Compose 文件
|
||||
|
||||
1. 编写 `compose.yaml` (或 `docker-compose.yml`) 配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
|
||||
container_name: elasticsearch
|
||||
environment:
|
||||
- "discovery.type=single-node"
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
ports:
|
||||
- "9200:9200"
|
||||
volumes:
|
||||
- es_data:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- logging
|
||||
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:7.17.0
|
||||
container_name: kibana
|
||||
environment:
|
||||
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
||||
ports:
|
||||
- "5601:5601"
|
||||
links:
|
||||
- elasticsearch
|
||||
networks:
|
||||
- logging
|
||||
|
||||
fluentd:
|
||||
image: fluent/fluentd-kubernetes-daemonset:v1.14.3-debian-elasticsearch7-1.0
|
||||
container_name: fluentd
|
||||
environment:
|
||||
- "FLUENT_ELASTICSEARCH_HOST=elasticsearch"
|
||||
- "FLUENT_ELASTICSEARCH_PORT=9200"
|
||||
- "FLUENT_ELASTICSEARCH_SCHEME=http"
|
||||
- "FLUENT_UID=0"
|
||||
ports:
|
||||
- "24224:24224"
|
||||
- "24224:24224/udp"
|
||||
links:
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ./fluentd/conf:/fluentd/etc
|
||||
networks:
|
||||
- logging
|
||||
|
||||
volumes:
|
||||
es_data:
|
||||
|
||||
networks:
|
||||
logging:
|
||||
```
|
||||
|
||||
#### 2. 配置 Fluentd
|
||||
|
||||
创建 `fluentd/conf/fluent.conf`:
|
||||
|
||||
```ini
|
||||
<source>
|
||||
@type forward
|
||||
port 24224
|
||||
bind 0.0.0.0
|
||||
</source>
|
||||
|
||||
<match *.**>
|
||||
@type copy
|
||||
<store>
|
||||
@type elasticsearch
|
||||
host elasticsearch
|
||||
port 9200
|
||||
logstash_format true
|
||||
logstash_prefix docker
|
||||
logstash_dateformat %Y%m%d
|
||||
include_tag_key true
|
||||
type_name access_log
|
||||
tag_key @log_name
|
||||
flush_interval 1s
|
||||
</store>
|
||||
<store>
|
||||
@type stdout
|
||||
</store>
|
||||
</match>
|
||||
```
|
||||
|
||||
#### 3. 配置应用容器使用 fluentd 驱动
|
||||
|
||||
启动一个测试容器,指定日志驱动为 `fluentd`:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--log-driver=fluentd \
|
||||
--log-opt fluentd-address=localhost:24224 \
|
||||
--log-opt tag=nginx-test \
|
||||
--name nginx-test \
|
||||
nginx
|
||||
```
|
||||
|
||||
**注意**:确保 `fluentd` 容器已经启动并监听在 `localhost:24224`。在生产环境中,如果你是在不同机器上,需要将 `localhost` 替换为运行 fluentd 的主机 IP。
|
||||
|
||||
#### 4. 在 Kibana 中查看日志
|
||||
|
||||
1. 访问 `http://localhost:5601`。
|
||||
2. 进入 **Management**->**Kibana**->**Index Patterns**。
|
||||
3. 创建新的 Index Pattern,输入 `docker-*` (我们在 fluent.conf 中配置的前缀)。
|
||||
4. 选择 `@timestamp` 作为时间字段。
|
||||
5. 去 **Discover** 页面,你就能看到 Nginx 容器的日志了。
|
||||
|
||||
#### Kibana 建索引模式常见坑
|
||||
|
||||
首次接入 EFK/ELK 时,“Elasticsearch 有数据但 Kibana 看不到”很常见,通常是 Kibana 配置或时间窗口问题:
|
||||
|
||||
* **Index Pattern 不匹配**:确认 Kibana 的 Index Pattern 与实际索引前缀一致。可以先用 `_cat/indices` 查看真实索引名。
|
||||
* **时间字段选择错误**:若索引里包含 `@timestamp`,一般选择它;如果选择了错误的字段,会导致 Discover 无法按时间筛选。
|
||||
* **时间窗口/时区**:Discover 右上角的时间范围默认可能是最近 15 分钟,且时区可能影响显示。建议先把范围扩大到最近 24 小时再验证。
|
||||
* **数据解析失败**:若日志是非结构化文本,仍可入库但字段不可用;生产环境建议输出 JSON 并在采集端解析。
|
||||
|
||||
#### 5. 验证日志是否写入 Elasticsearch (生产排错必备)
|
||||
|
||||
当你在 Kibana 看不到日志时,建议先跳过 UI,从存储端直接验证“日志是否入库”。
|
||||
|
||||
1. 查看索引是否创建:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:9200/_cat/indices?v
|
||||
```
|
||||
|
||||
如果 Fluentd 使用了 `logstash_format true` 且 `logstash_prefix docker`,通常会看到形如 `docker-YYYY.MM.DD` 的索引。
|
||||
|
||||
2. 查看最近一段时间的日志文档:
|
||||
|
||||
```bash
|
||||
curl -s -H 'Content-Type: application/json' \
|
||||
http://localhost:9200/docker-*/_search \
|
||||
-d '{"size":1,"sort":[{"@timestamp":"desc"}]}'
|
||||
```
|
||||
|
||||
如果 Elasticsearch 中已经有文档,但 Kibana 仍然为空,常见原因是:
|
||||
|
||||
* Index Pattern 没匹配到索引 (例如写成了 `docker-*` 但实际索引前缀不同)。
|
||||
* 时间字段没选对或时区不一致,导致 Discover 时间窗口内看不到数据。
|
||||
|
||||
### 19.2.3 总结
|
||||
|
||||
通过 Docker 的日志驱动机制,结合 ELK/EFK 强大的收集和分析能力,我们可以轻松构建一个能够处理海量日志的监控平台,这对于排查生产问题至关重要。
|
||||
|
||||
### 19.2.4 生产要点
|
||||
|
||||
在生产环境中,日志系统往往比监控系统更容易因为“容量与写入压力”出问题,建议特别关注:
|
||||
|
||||
* **容量规划**:日志增长速度与磁盘占用直接相关。建议设置日志保留周期与索引生命周期策略 (ILM),避免 Elasticsearch 因磁盘水位触发只读或不可用。
|
||||
* **资源配置**:Elasticsearch 对 JVM Heap 较敏感。除示例中的 `ES_JAVA_OPTS` 外,生产环境需要结合节点内存、分片规模、查询压力做评估。
|
||||
* **链路可靠性**:采集端到存储端要考虑网络抖动、背压与重试策略;当 Elasticsearch 写入变慢时,采集端的缓冲与落盘策略决定了是否会丢日志。
|
||||
* **日志格式**:推荐应用输出结构化日志 (JSON) 并包含关键字段 (如 `trace_id`、`request_id`、`service`、`env`),以便快速过滤与关联分析。
|
||||
|
||||
#### 索引与保留策略的落地建议
|
||||
|
||||
无论是 EFK 还是 ELK,生产上都需要回答两个问题:
|
||||
|
||||
* 日志保留多久?
|
||||
* 保留期内的日志如何保证可查询、不过度占用存储?
|
||||
|
||||
建议按环境与业务重要性对日志分层,并制定不同的保留周期,例如:
|
||||
|
||||
* **生产环境**:7~30 天
|
||||
* **测试环境**:1~7 天
|
||||
|
||||
实现方式通常有两类:
|
||||
|
||||
* **按天滚动索引**:如 `docker-YYYY.MM.DD`,再定期删除过期索引。
|
||||
* **使用 ILM**:定义 Hot/Warm/Cold/删除阶段,按时间与容量自动滚动与回收。
|
||||
|
||||
对于中小规模集群,先把“按天滚动 + 过期删除”做扎实,往往就能解决 80% 的容量问题;当日志量上来、查询压力变大后,再逐步引入 ILM、分层存储与更精细的分片规划。
|
||||
|
||||
#### 最小可用的“过期索引清理”示例
|
||||
|
||||
如果你采用按天滚动索引 (例如 `docker-YYYY.MM.DD`),可以通过 Elasticsearch API 定期清理过期索引。
|
||||
|
||||
下面示例仅用于演示思路:获取所有 `docker-` 前缀索引并删除指定索引。生产环境建议基于日期计算、灰度验证与权限控制后再执行自动化清理。
|
||||
|
||||
1. 列出索引:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:9200/_cat/indices/docker-*?v
|
||||
```
|
||||
|
||||
2. 删除某个过期索引 (示例):
|
||||
|
||||
```bash
|
||||
curl -X DELETE http://localhost:9200/docker-2026.02.01
|
||||
```
|
||||
|
||||
如果你希望更自动化的治理能力,可以进一步使用 ILM 为索引配置滚动与删除策略。
|
||||
@@ -1,8 +1,17 @@
|
||||
# 第十九章 容器监控与日志
|
||||
|
||||
在生产环境中,容器化应用部署完成后,实时掌握容器集群的状态以及应用日志非常重要。本章将介绍针对 Docker 容器和 Kubernetes 集群的监控与日志管理方案。
|
||||
在生产环境中,容器化应用部署完成后,实时掌握容器的运行状态以及应用日志非常重要。本章将以 Docker/Compose 的场景为主,介绍容器监控与日志管理的落地思路与最小实践闭环。
|
||||
|
||||
对于 Kubernetes 场景,可观测性链路与组件选择通常会有所不同 (例如使用 Prometheus Operator、日志采集 DaemonSet 等)。本章会在关键点给出迁移提示,但不会展开为完整的 Kubernetes 教程。
|
||||
|
||||
我们将重点探讨以下内容:
|
||||
|
||||
- **容器监控**:以 Prometheus 为主,讲解如何采集和展示容器性能指标。
|
||||
- **日志管理**:以 ELK (Elasticsearch, Logstash, Kibana) 套件为例,介绍集中式日志收集平台。
|
||||
|
||||
为了让读者能够在生产环境中真正用起来,本章会补齐以下“最小闭环”:
|
||||
|
||||
* 关键指标与日志的验证方法
|
||||
* 常见故障排查路径
|
||||
* 最小告警闭环 (Prometheus -> Alertmanager -> 接收端)
|
||||
* 日志容量治理的最小实践
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
## 19.2 ELK/EFK 堆栈
|
||||
|
||||
ELK (Elasticsearch,Logstash,Kibana) 是目前业界最流行的开源日志解决方案。而在容器领域,由于 Fluentd 更加轻量级且对容器支持更好,EFK (Elasticsearch,Fluentd,Kibana) 组合也变得非常流行。
|
||||
|
||||
### 19.2.1 方案架构
|
||||
|
||||
我们将采用以下架构:
|
||||
|
||||
1. **Docker Container**:容器将日志输出到标准输出 (stdout/stderr)。
|
||||
2. **Fluentd**:作为 Docker 的 Logging Driver 或运行为守护容器,收集容器日志。
|
||||
3. **Elasticsearch**:存储从 Fluentd 接收到的日志数据。
|
||||
4. **Kibana**:从 Elasticsearch 读取数据并进行可视化展示。
|
||||
|
||||
### 19.2.2 部署流程
|
||||
|
||||
我们将使用 Docker Compose 来一键部署整个日志堆栈。
|
||||
|
||||
#### 1. 编写 Compose 文件
|
||||
|
||||
1. 编写 `compose.yaml` (或 `docker-compose.yml`) 配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
|
||||
container_name: elasticsearch
|
||||
environment:
|
||||
- "discovery.type=single-node"
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
ports:
|
||||
- "9200:9200"
|
||||
volumes:
|
||||
- es_data:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- logging
|
||||
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:7.17.0
|
||||
container_name: kibana
|
||||
environment:
|
||||
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
||||
ports:
|
||||
- "5601:5601"
|
||||
links:
|
||||
- elasticsearch
|
||||
networks:
|
||||
- logging
|
||||
|
||||
fluentd:
|
||||
image: fluent/fluentd-kubernetes-daemonset:v1.14.3-debian-elasticsearch7-1.0
|
||||
container_name: fluentd
|
||||
environment:
|
||||
- "FLUENT_ELASTICSEARCH_HOST=elasticsearch"
|
||||
- "FLUENT_ELASTICSEARCH_PORT=9200"
|
||||
- "FLUENT_ELASTICSEARCH_SCHEME=http"
|
||||
- "FLUENT_UID=0"
|
||||
ports:
|
||||
- "24224:24224"
|
||||
- "24224:24224/udp"
|
||||
links:
|
||||
- elasticsearch
|
||||
volumes:
|
||||
- ./fluentd/conf:/fluentd/etc
|
||||
networks:
|
||||
- logging
|
||||
|
||||
volumes:
|
||||
es_data:
|
||||
|
||||
networks:
|
||||
logging:
|
||||
```
|
||||
|
||||
#### 2. 配置 Fluentd
|
||||
|
||||
创建 `fluentd/conf/fluent.conf`:
|
||||
|
||||
```ini
|
||||
<source>
|
||||
@type forward
|
||||
port 24224
|
||||
bind 0.0.0.0
|
||||
</source>
|
||||
|
||||
<match *.**>
|
||||
@type copy
|
||||
<store>
|
||||
@type elasticsearch
|
||||
host elasticsearch
|
||||
port 9200
|
||||
logstash_format true
|
||||
logstash_prefix docker
|
||||
logstash_dateformat %Y%m%d
|
||||
include_tag_key true
|
||||
type_name access_log
|
||||
tag_key @log_name
|
||||
flush_interval 1s
|
||||
</store>
|
||||
<store>
|
||||
@type stdout
|
||||
</store>
|
||||
</match>
|
||||
```
|
||||
|
||||
#### 3. 配置应用容器使用 fluentd 驱动
|
||||
|
||||
启动一个测试容器,指定日志驱动为 `fluentd`:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--log-driver=fluentd \
|
||||
--log-opt fluentd-address=localhost:24224 \
|
||||
--log-opt tag=nginx-test \
|
||||
--name nginx-test \
|
||||
nginx
|
||||
```
|
||||
|
||||
**注意**:确保 `fluentd` 容器已经启动并监听在 `localhost:24224`。在生产环境中,如果你是在不同机器上,需要将 `localhost` 替换为运行 fluentd 的主机 IP。
|
||||
|
||||
#### 4. 在 Kibana 中查看日志
|
||||
|
||||
1. 访问 `http://localhost:5601`。
|
||||
2. 进入 **Management**->**Kibana**->**Index Patterns**。
|
||||
3. 创建新的 Index Pattern,输入 `docker-*` (我们在 fluent.conf 中配置的前缀)。
|
||||
4. 选择 `@timestamp` 作为时间字段。
|
||||
5. 去 **Discover** 页面,你就能看到 Nginx 容器的日志了。
|
||||
|
||||
### 19.2.3 总结
|
||||
|
||||
通过 Docker 的日志驱动机制,结合 ELK/EFK 强大的收集和分析能力,我们可以轻松构建一个能够处理海量日志的监控平台,这对于排查生产问题至关重要。
|
||||
@@ -1,109 +0,0 @@
|
||||
## 19.1 Prometheus + Grafana
|
||||
|
||||
Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。
|
||||
|
||||
[Prometheus](https://prometheus.io/) 是一个开源的系统监控和报警工具包。它受 Google Borgmon 的启发,由 SoundCloud 在 2012 年创建。
|
||||
|
||||
### 19.1.1 架构简介
|
||||
|
||||
Prometheus 的主要组件包括:
|
||||
|
||||
* **Prometheus Server**:核心组件,负责收集和存储时间序列数据。
|
||||
* **Exporters**:负责向 Prometheus 暴露监控数据 (如 Node Exporter,cAdvisor)。
|
||||
* **Alertmanager**:处理报警发送。
|
||||
* **Pushgateway**:用于支持短生命周期的 Job 推送数据。
|
||||
|
||||
### 19.1.2 快速部署
|
||||
|
||||
我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。
|
||||
|
||||
#### 1. 准备配置文件
|
||||
|
||||
创建 `prometheus.yml`:
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'node-exporter'
|
||||
static_configs:
|
||||
- targets: ['node-exporter:9100']
|
||||
|
||||
- job_name: 'cadvisor'
|
||||
static_configs:
|
||||
- targets: ['cadvisor:8080']
|
||||
```
|
||||
|
||||
#### 2. 编写 Docker Compose 文件
|
||||
|
||||
创建 `compose.yaml` (或 `docker-compose.yml`):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
ports:
|
||||
- "9090:9090"
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
networks:
|
||||
- monitoring
|
||||
depends_on:
|
||||
- prometheus
|
||||
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
ports:
|
||||
- "9100:9100"
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
cadvisor:
|
||||
image: gcr.io/cadvisor/cadvisor:latest
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:ro
|
||||
- /sys:/sys:ro
|
||||
- /var/lib/docker/:/var/lib/docker:ro
|
||||
networks:
|
||||
- monitoring
|
||||
|
||||
networks:
|
||||
monitoring:
|
||||
```
|
||||
|
||||
#### 3. 启动服务
|
||||
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker compose up -d
|
||||
```
|
||||
|
||||
启动后,访问以下地址:
|
||||
|
||||
* Prometheus: `http://localhost:9090`
|
||||
* Grafana:`http://localhost:3000` (默认账号密码:admin/admin)
|
||||
|
||||
### 19.1.3 配置 Grafana 面板
|
||||
|
||||
1. 在 Grafana 中添加 Prometheus 数据源,URL 填写 `http://prometheus:9090`。
|
||||
2. 导入现成的 Dashboard 模板,例如 [Node Exporter Full](https://grafana.com/grafana/dashboards/1860) (ID:1860) 和 [Docker Container](https://grafana.com/grafana/dashboards/193) (ID:193)。
|
||||
|
||||
这样,你就拥有了一个直观的容器监控大屏。
|
||||
@@ -1,10 +1,15 @@
|
||||
# 日志管理
|
||||
# 本章小结
|
||||
|
||||
在容器化环境中,日志管理比传统环境更为复杂。容器是短暂的,意味着容器内的日志文件可能会随着容器的销毁而丢失。因此,我们需要一种集中式的日志管理方案来收集、存储和分析容器日志。
|
||||
本章从两个维度介绍了容器可观测性:
|
||||
|
||||
* **指标监控**:以 Prometheus + Grafana 为主,完成指标采集、存储与可视化。
|
||||
* **日志管理**:以 EFK/ELK 为例,完成容器日志的集中采集、检索与分析。
|
||||
|
||||
生产环境中,建议将“可观测性”当成一个完整闭环:**采集 -> 存储 -> 展示 -> 告警 -> 排错 -> 容量治理**。
|
||||
|
||||
## 19.3 Docker 日志驱动
|
||||
|
||||
Docker 提供了多种日志驱动 (Log Driver) 机制,允许我们将容器日志转发到不同的后端。
|
||||
Docker 提供了多种日志驱动 (Log Driver),用于将容器标准输出的日志转发到不同后端。
|
||||
|
||||
常见的日志驱动包括:
|
||||
|
||||
@@ -15,12 +20,30 @@ Docker 提供了多种日志驱动 (Log Driver) 机制,允许我们将容器
|
||||
* `gelf`:支持 GELF 协议的日志后端 (如 Graylog)。
|
||||
* `awslogs`:发送到 Amazon CloudWatch Logs。
|
||||
|
||||
## 19.3 日志管理方案
|
||||
生产建议:无论采用哪种驱动,都要明确日志的保留周期、容量上限与传输可靠性,避免“日志把磁盘写满”或“链路抖动导致丢日志”。
|
||||
|
||||
对于大规模的容器集群,我们通常会采用 EFK (Elasticsearch + Fluentd + Kibana) 或 ELK (Elasticsearch + Logstash + Kibana) 方案。
|
||||
## 19.4 日志平台选型对比与注意事项
|
||||
|
||||
* **Elasticsearch**:负责日志的存储和全文检索。
|
||||
* **Fluentd/Logstash**:负责日志的采集、过滤和转发。
|
||||
* **Kibana**:负责日志的可视化展示。
|
||||
日志平台通常由“采集/处理/存储/查询展示”几部分组成。常见选型包括:
|
||||
|
||||
本章将介绍如何使用 EFK 方案来处理 Docker 容器日志。
|
||||
* **EFK/ELK**:Elasticsearch + Fluentd/Logstash + Kibana,适合全文检索与结构化查询。
|
||||
* **Loki + Grafana**:更偏“日志像指标一样存储”的思路,部署与成本可能更友好,但查询能力与使用习惯不同。
|
||||
|
||||
选型时建议关注:
|
||||
|
||||
* **写入压力与背压**:当存储端变慢时,采集端是否会缓冲、落盘、重试,是否会影响业务。
|
||||
* **容量治理**:是否具备按天/按大小滚动、保留策略、生命周期管理 (ILM) 等能力。
|
||||
* **安全与合规**:鉴权、TLS、审计、敏感字段脱敏。
|
||||
* **可运维性**:升级策略、备份恢复、告警指标是否齐全。
|
||||
|
||||
## 19.5 上线前检查清单
|
||||
|
||||
你可以用下面的清单快速检查“是否具备最小生产可用性”:
|
||||
|
||||
* Prometheus 数据目录已持久化,并设置了合理的保留周期。
|
||||
* Prometheus Targets 全部为 `UP`,并且关键查询 (CPU/内存/容器指标) 有数据。
|
||||
* Grafana 已导入面板并能定位到具体实例/容器;默认账号密码已修改。
|
||||
* 至少有一条关键告警已打通 Alertmanager 的接收链路,并验证告警能被正确发送与抑制。
|
||||
* Elasticsearch 数据目录已持久化,并有明确的日志保留周期与容量上限策略。
|
||||
* Kibana 能查询到最新日志;当 UI 异常时能用 Elasticsearch API 验证入库。
|
||||
* 可观测性组件未直接暴露到公网,访问已加鉴权或置于内网。
|
||||
|
||||
Reference in New Issue
Block a user