日志与监控
概述#
运维工作的核心公式是:发现问题 → 定位问题 → 解决问题。日志和监控分别对应"知道发生了什么"和"发现正在发生什么"。在 Kubernetes 环境中,由于 Pod 的动态性和短暂性,日志和监控的方式和传统虚拟机有很大不同。这一章从最基础的 kubectl logs 讲起,到集群级日志采集架构,再到 Metrics 和 Events 监控,帮你建立完整的可观测性认知。
kubectl logs 的局限性#
kubectl logs 是每个 K8s 用户接触的第一个排障命令,但在生产环境中它有明显的局限:
四大痛点#
| 局限 | 说明 |
|---|---|
| 只能看单 Pod 日志 | 一个 Deployment 有 10 个副本,你需要逐个查看,无法聚合 |
| 不持久化 | Pod 被删除(重启/缩容/滚动更新)后,日志也随之消失 |
| 多容器需指定 -c | 一个 Pod 里有多个容器时,必须用 -c 指定容器名,否则只看第一个 |
| 日志存储有限 | 容器运行时的日志缓冲和轮转有限,长时间运行后会丢失早期日志 |
常用命令#
# 查看 Pod 日志
kubectl logs <pod-name> -n <namespace>
# 查看多容器 Pod 中指定容器的日志
kubectl logs <pod-name> -c <container-name>
# 实时 tail 日志(类似 tail -f)
kubectl logs -f <pod-name>
# 查看最近 100 行
kubectl logs --tail=100 <pod-name>
# 查看过去 1 小时的日志
kubectl logs --since=1h <pod-name>
# 查看上一个容器实例的日志(容器重启后)
kubectl logs <pod-name> --previous
# 按标签查看(需要拼接)
kubectl logs -l app=my-api --tail=50什么时候该用 kubectl logs#
- 快速排障:应用刚报错、Pod 刚重启,快速看一眼
- 测试/开发环境:没有部署日志采集系统
- 验证问题:确认某个特定 Pod 的日志内容
生产环境不能依赖 kubectl logs 作为长期日志方案。你需要专门的日志采集和存储系统。
日志采集架构#
Kubernetes 中有两种主流的日志采集架构:
架构对比#
| 维度 | DaemonSet 模式 | Sidecar 模式 |
|---|---|---|
| 部署方式 | 每个节点跑一个日志采集 Agent(DaemonSet) | 每个 Pod 里加一个 sidecar 容器负责采集 |
| 资源开销 | 低——每个节点只一个 Agent 进程 | 高——每个 Pod 多一个 sidecar 容器 |
| 运维复杂度 | 低——集中配置,一次部署 | 高——需要每个 Pod 配置 sidecar |
| 灵活性 | 中——所有 Pod 日志一视同仁 | 高——每个 Pod 可自定义处理逻辑 |
| 适用场景 | 标准日志采集(90% 的场景) | 特殊日志处理(日志文件非 stdout、需要预处理) |
DaemonSet 模式(推荐)#
┌──────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ │
│ Node-1 Node-2 Node-3│
│ ┌────────┐ ┌────────┐ ┌────────┐
│ │ Agent │ │ Agent │ │ Agent │ ← DaemonSet
│ │ Daemon │ │ Daemon │ │ Daemon │
│ └───┬────┘ └───┬────┘ └───┬────┘
│ │ 采集 /var/log │ │
│ ┌───┴────┐ ┌───┴────┐ ┌───┴────┐
│ │ Pod A │ │ Pod C │ │ Pod E │
│ │ Pod B │ │ Pod D │ │ Pod F │
│ └────────┘ └────────┘ └────────┘
│ ↓ 转发 ↓ ↓
│ ┌────────────────────────────────────────────────┐
│ │ 日志存储后端 (Loki / Elasticsearch) │
│ └────────────────────────────────────────────────┘Agent 以 DaemonSet 部署在每个节点,挂载节点的 /var/log/containers/ 目录,tail 所有容器的 stdout/stderr 输出。这是目前最主流、最低成本的方案。
几种常见方案#
| 方案 | Agent | 存储 | 特点 |
|---|---|---|---|
| EFK | Fluent Bit (DaemonSet) | Elasticsearch | 功能强大,ES 资源消耗大 |
| Loki Stack | Promtail (DaemonSet) | Loki | 轻量,与 Grafana 深度集成,按标签索引 |
| Fluent Bit + Loki | Fluent Bit (DaemonSet) | Loki | Fluent Bit 的采集能力 + Loki 的轻量存储 |
Loki 方案简述#
Loki 是 Grafana Labs 出品的日志聚合系统,设计理念和 Prometheus 一脉相承——不索引全文,只索引标签(label),日志内容以压缩块存储。这让它的资源开销比 Elasticsearch 低得多,特别适合中小规模集群。
数据流:容器 stdout/stderr → Promtail (DaemonSet 采集) → Loki (存储+索引) → Grafana (查询展示)
Fluentd 方案简述#
Fluentd (或轻量版 Fluent Bit) 是 CNCF 毕业项目,插件生态丰富,支持把日志写入多种后端(ES、Loki、Kafka、S3 等)。典型架构是 Fluent Bit (轻量采集) → Fluentd (聚合处理) → Elasticsearch:
- Fluent Bit 以 DaemonSet 部署,只负责 tail 日志文件
- Fluentd 以 Deployment 部署,负责解析 JSON、添加环境标签、批量写入 ES
- 两层架构的好处:Fluentd 的副本数可以独立扩缩
对于本教程的读者:选择 Loki + Promtail 或 Fluent Bit + Elasticsearch 取决于你的团队技术栈和规模。如果已有 Elasticsearch 基础就选 EFK,如果用了 Grafana 做可视化就选 Loki。没有银弹方案。
Metrics Server 与 kubectl top#
什么是 Metrics Server#
Metrics Server 是 Kubernetes 内置资源指标采集组件,它从 kubelet 汇总各节点上 Pod 的 CPU/内存使用数据,提供给 kubectl top 和 HPA 使用。
# 安装(一句带过——大多数发行版已自带)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yamlkubectl top 用法#
# 查看节点资源使用
kubectl top nodes
# 输出示例:
# NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
# node-1 1200m 30% 6Gi 40%
# node-2 800m 20% 4Gi 27%
# 查看 Pod 资源使用
kubectl top pods -n production
# 输出示例:
# NAME CPU(cores) MEMORY(bytes)
# my-api-7d5f8b9c-x2k3 150m 320Mi
# my-api-7d5f8b9c-y7m4 180m 340Mi
# 按标签筛选
kubectl top pods -l app=my-api
# 查看所有命名空间的 Pod
kubectl top pods -AMetrics Server 的局限#
- 不持久化——数据只是当前快照,没有历史曲线
- 只提供 CPU/内存,不提供网络、磁盘等指标
- 精度较低——默认采样间隔 60 秒(
--metric-resolution,非 15 秒),不是实时值
对于长期趋势分析和复杂指标,需要 Prometheus。
Prometheus + Grafana#
这是 Kubernetes 可观测性的标准组合,不展开详细部署步骤,但每个 K8s 运维人员都需要知道它们分别做什么:
Prometheus(指标采集 + 存储 + 告警)
├─ 从各个 Target(K8s 节点、Pod、Service)拉取 metrics
├─ 用 PromQL 查询语句分析数据
├─ Alertmanager 根据规则发送告警
└─ 数据存储在本机 TSDB 中(可对接远程存储)
Grafana(可视化 + 仪表盘)
├─ 连接 Prometheus 作为数据源
├─ 用 PromQL 构建 Dashboard 面板
├─ 社区有大量现成的 K8s Dashboard 模板
└─ 支持告警和注释对于刚入门的运维人员,建议:
- 用
kube-prometheus-stackHelm Chart 一键部署 Prometheus + Grafana + 常用 Dashboard - 先熟悉 Grafana 自带的模板,理解 Node Exporter、kube-state-metrics 各面板的含义
- 再逐步写自己的 PromQL 查询,建立自定义告警规则
K8s Events 排查#
Kubernetes Events 是集群的"新闻播报"。每当集群中发生什么——Pod 调度失败、Liveness 探针触发重启、节点 NotReady——都会产生一条 Event。
什么是 Events#
Events 不是传统意义上的"日志",它记录的是集群状态的变化。它是理解 K8s 内部发生了什么的第一手资料。
查看 Events#
# 查看命名空间内所有 Events(按时间排序)
kubectl get events -n production --sort-by='.lastTimestamp'
# 查看所有命名空间的 Events
kubectl get events -A --sort-by='.lastTimestamp'
# 持续监控新 Event(类似 watch)
kubectl get events -n production -wEvents 在 describe 中的体现#
kubectl describe 的底部 Events 段落是最常用的排障入口:
kubectl describe pod my-pod -n production输出中 Events 部分示例:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned production/my-pod to node-1
Normal Pulling 10m kubelet Pulling image "myapp:1.0"
Normal Pulled 9m kubelet Successfully pulled image "myapp:1.0"
Normal Created 9m kubelet Created container app
Normal Started 9m kubelet Started container app
Warning Unhealthy 2m kubelet Liveness probe failed: Get "http://10.244.1.5:8080/healthz": dial tcp: connect: connection refusedEvents 排障速查#
| 常见 Event 类型 | 含义 | 排查方向 |
|---|---|---|
FailedScheduling | Pod 无法调度 | 检查节点资源、nodeSelector、Taint、Affinity 规则 |
Failed / ErrImagePull | 镜像拉取失败 | 检查镜像名、tag 是否存在、imagePullSecrets |
CrashLoopBackOff | 容器反复崩溃重启 | kubectl logs --previous 看上次崩溃日志 |
OOMKilled | 内存超 Limit 被杀 | 检查 resources.limits.memory 设置 |
Unhealthy | Liveness/Readiness 探针失败 | 检查探针配置和应用健康检查端点 |
FailedMount | Volume 挂载失败 | 检查 PV/PVC/StorageClass/Secret 是否存在 |
Evicted | Pod 被驱逐 | 节点磁盘/内存压力,检查节点状态 |
Event 的存活时间#
Kubernetes Events 默认保留 60 分钟(由 API Server 的 --event-ttl 参数控制)。超过这个时间的 Event 会被 API Server 自动清理。对于需要长期保留的 Events,建议安装 kubernetes-event-exporter 将 Events 导出到 Loki/ES 做持久化存储。
实战要点#
- kubectl logs 是临时排障工具:生产环境必须有日志采集系统,Loki + Promtail 是轻量级的好选择。
- 日志采集优先选 DaemonSet 模式:能覆盖 90% 的场景,只在确实需要 sidecar 时才用。
- Metrics Server 是 HPA 的基础:如果
kubectl top不工作,HPA 的 CPU 百分比指标也会显示<unknown>。 - Events 是第一手的"发生了什么":排查任何问题之前先看 Events,往往比翻日志更快找到根因。
- Prometheus 是 K8s 的标配监控:不要求你第一天就玩转 PromQL,但要知道它和 Grafana 是事实标准。
小结#
Kubernetes 的可观测性体系分为三层:日志(Logs)告诉你过去发生了什么,指标(Metrics)告诉你当前的状态和趋势,事件(Events)告诉你集群内部发生了什么变化。kubectl logs 和 kubectl get events 是运维人员的日常排障命令,但在生产环境中需要专门的日志采集(DaemonSet 模式为主)和监控系统(Prometheus + Grafana)来支撑长期运维。从入门到生产,日志和监控不是"可选项",而是"必修课"。