跳到主要内容

K8s 监控与日志

监控体系架构

Metrics Server

Metrics Server 采集 Node 和 Pod 的 CPU/内存使用量,是 kubectl top 和 HPA 的数据来源。

# 安装 Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 使用
kubectl top nodes
kubectl top pods -A --sort-by=memory
注意

Metrics Server 只保留最近的指标数据(不持久化),不适合历史查询。生产环境需要 Prometheus 做持久监控。

Prometheus + Grafana

kube-prometheus-stack

生产环境推荐使用 kube-prometheus-stack(Helm Chart),一键部署完整监控栈:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring --create-namespace \
--set grafana.adminPassword=admin \
--set prometheus.prometheusSpec.retention=30d \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi

包含组件

  • Prometheus Operator:管理 Prometheus 实例
  • Prometheus:指标采集和存储
  • Alertmanager:告警管理
  • Grafana:可视化(预置 K8s Dashboard)
  • node-exporter:Node 指标采集
  • kube-state-metrics:K8s 对象状态指标

核心监控指标

层级关键指标PromQL 示例
NodeCPU 使用率100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
Node内存使用率(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
Node磁盘使用率(1 - node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100
PodCPU 使用rate(container_cpu_usage_seconds_total[5m])
Pod内存使用container_memory_working_set_bytes
Pod重启次数kube_pod_container_status_restarts_total
Service请求速率rate(http_requests_total[5m])
Service错误率rate(http_requests_total{code=~"5.."}[5m]) / rate(http_requests_total[5m])
ServiceP99 延迟histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

告警规则

PrometheusRule 示例
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: k8s-alerts
namespace: monitoring
spec:
groups:
- name: pod-alerts
rules:
# Pod 频繁重启
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} 频繁重启"

# Pod 长时间 Pending
- alert: PodPending
expr: kube_pod_status_phase{phase="Pending"} == 1
for: 15m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} Pending 超过 15 分钟"

- name: node-alerts
rules:
# Node CPU 过高
- alert: NodeHighCPU
expr: 100 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 85
for: 10m
labels:
severity: critical
annotations:
summary: "Node {{ $labels.instance }} CPU 使用率 {{ $value }}%"

# Node 磁盘即将满
- alert: NodeDiskFull
expr: (1 - node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.*"} / node_filesystem_size_bytes) * 100 > 85
for: 5m
labels:
severity: critical

Alertmanager 配置

alertmanager.yaml
global:
resolve_timeout: 5m

route:
receiver: default
group_by: [alertname, namespace]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: critical
receiver: pager
repeat_interval: 1h

receivers:
- name: default
webhook_configs:
- url: http://alertbot:8080/webhook
- name: pager
webhook_configs:
- url: http://alertbot:8080/pager

日志方案

方案对比

方案架构存储优势劣势
EFKFluent Bit → ES → KibanaElasticsearch功能强大,全文搜索资源消耗大
PLGPromtail → Loki → GrafanaLoki(对象存储)轻量,成本低不支持全文搜索

Loki + Grafana(推荐轻量方案)

# 安装 Loki Stack
helm install loki grafana/loki-stack \
--namespace logging --create-namespace \
--set promtail.enabled=true \
--set grafana.enabled=false # 复用监控的 Grafana

Loki 只索引标签(label),不索引日志内容,存储成本远低于 Elasticsearch。

# Grafana 中的 LogQL 查询示例
{namespace="default", app="myapp"} # 按标签过滤
{namespace="default"} |= "error" # 包含 error
{namespace="default"} | json | status >= 500 # JSON 日志解析
{namespace="default"} | json | latency_ms > 1000 | line_format "slow: {{.path}}"

EFK Stack

Fluent Bit ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: logging
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Daemon Off
Log_Level info

[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser cri
Refresh_Interval 5
Mem_Buf_Limit 5MB

[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Merge_Log On
K8S-Logging.Exclude On

[OUTPUT]
Name es
Match *
Host elasticsearch
Port 9200
Index k8s-logs
Type _doc

常见面试问题

Q1: K8s 监控使用什么方案?

答案

生产标准方案是 kube-prometheus-stack

  • Prometheus:采集和存储指标
  • Grafana:可视化仪表盘(预置 K8s Dashboard)
  • Alertmanager:告警管理和路由
  • node-exporter + kube-state-metrics:数据采集

关键监控维度:Node 资源(CPU/内存/磁盘)、Pod 状态(重启/OOM)、应用指标(QPS/延迟/错误率)。

Q2: K8s 日志方案怎么选?

答案

场景推荐
小规模 / 成本敏感Loki + Grafana(轻量,只索引标签)
大规模 / 全文搜索EFK(Elasticsearch 强大但吃资源)
云托管CloudWatch / Stackdriver / 阿里云 SLS

共同点:都使用 DaemonSet(Promtail/Fluent Bit)在每个 Node 采集容器日志。

Q3: 如何监控 Pod 的 OOM 和频繁重启?

答案

# Pod 频繁重启
rate(kube_pod_container_status_restarts_total[15m]) > 0

# 容器 OOM Killed
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}

# 内存接近 limit
container_memory_working_set_bytes / kube_pod_container_resource_limits{resource="memory"} > 0.9

结合 Alertmanager 配置告警规则,关键告警发送到即时通讯工具或值班系统。

相关链接