📘 第34课:监控与告警
Kubernetes
📊 K8s监控体系
K8s集群和应用的监控是运维的核心。Prometheus + Grafana是事实上的标准方案。
🔧 kube-prometheus-stack
# 使用Helm一键部署完整监控栈 ✅
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
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.storageClassName=standard \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi
# 访问Grafana ✅
kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80
# 访问Prometheus ✅
kubectl port-forward -n monitoring svc/monitoring-kube-prometheus-prometheus 9090:9090
📋 监控指标分类
| 层级 | 指标 | 来源 |
| 集群 | 节点CPU/内存/磁盘、Pod数量 | kube-state-metrics |
| 节点 | CPU/内存/网络/磁盘IO | node-exporter |
| Pod/容器 | CPU/内存/重启次数/状态 | cAdvisor |
| 应用 | 请求量/延迟/错误率 | 应用/metrics端点 |
🔔 Prometheus告警规则
# 告警规则 ✅
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: app-alerts
spec:
groups:
- name: app
rules:
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[5m]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} is crash looping"
- alert: HighMemoryUsage
expr: |
container_memory_working_set_bytes /
container_spec_memory_limit_bytes > 0.9
for: 5m
labels:
severity: warning
- alert: PodNotReady
expr: |
kube_pod_status_phase{phase!="Running"} == 1
for: 10m
labels:
severity: warning
📧 AlertManager通知
# AlertManager配置 ✅
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'slack'
routes:
- match:
severity: critical
receiver: 'pagerduty'
receivers:
- name: 'slack'
slack_configs:
- api_url: 'https://hooks.slack.com/services/xxx'
channel: '#alerts'
- name: 'pagerduty'
pagerduty_configs:
- service_key: '<key>'
📊 应用自定义指标
# 应用暴露/metrics端点 ✅
# Prometheus客户端库(以Node.js为例)
const client = require('prom-client');
const registry = new client.Registry();
const httpRequestDuration = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'route', 'status'],
registers: [registry]
});
app.get('/metrics', (req, res) => {
res.set('Content-Type', registry.contentType);
res.end(registry.metrics());
});
# K8s ServiceMonitor自动发现 ✅
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-metrics
spec:
selector:
matchLabels:
app: my-app
endpoints:
- port: http
path: /metrics
interval: 15s
❓ 常见问题
🏆 本课成就
- 搭建kube-prometheus-stack监控 ✅
- 理解K8s监控指标层级
- 掌握Prometheus告警规则 ✅
- 学会AlertManager通知配置
- 掌握应用自定义指标暴露 ✅
📚 深度补充:监控与告警进阶要点
【Kubernetes入门阶段】生产环境注意事项
| 要点 | 说明 | 最佳实践 |
| 资源规划 | 根据业务负载合理分配CPU/内存 | 先压测再上线,设置requests和limits |
| 监控告警 | 设置关键指标阈值和告警规则 | Prometheus + AlertManager,5分钟P99延迟告警 |
| 备份策略 | 定期备份关键数据和配置 | 自动化备份脚本 + 异地存储 + 定期恢复演练 |
| 灰度发布 | 新版本逐步放量降低风险 | 金丝雀发布5%→20%→50%→100% |
| 回滚预案 | 部署前确认回滚方案和步骤 | 保留前一版本镜像,数据库迁移向前兼容 |
| 文档更新 | 配置变更必须同步更新文档 | GitOps管理配置,变更即文档 |
| 安全基线 | 遵循CIS Docker Benchmark | 非root运行、只读FS、最小能力 |
| 日志规范 | 结构化日志,统一格式 | JSON格式日志,包含traceId |
常见误区与避坑指南
- 过度配置:不是所有服务都需要高可用,根据实际需求选择架构复杂度,避免过度工程
- 忽略日志:日志是排障的关键,确保日志格式统一、级别合理、采集完整
- 资源超卖:容器资源限制不是摆设,超卖会导致性能下降甚至OOM Kill
- 安全忽视:默认配置不等于安全配置,生产环境必须加固(非root、只读FS、最小能力)
- 监控缺失:没有监控等于盲飞,至少要有基础的健康检查和资源监控
- 手动运维:能自动化的绝不手动,手动操作容易出错且不可追溯
- 忽略网络策略:默认所有容器互通不安全,应按最小权限原则配置网络
进阶阅读与参考
Docker命令速查卡
# 容器生命周期
docker create/start/stop/restart/rm/pause/unpause
docker logs/top/stats/inspect/exec diff
# 镜像构建
docker build/pull/push/tag/rmi/images/history
docker save/load/import/manifest
# 网络与存储
docker network create/ls/inspect/connect/disconnect/rm/prune
docker volume create/ls/inspect/rm/prune
# Docker Compose
docker compose up/down/ps/logs/build/exec
docker compose config/stop/start/scale/top/cp
# 系统维护
docker system df/prune/info
docker builder prune
docker container/prune/image prune
# K8s常用命令
kubectl get/describe/logs/exec/apply/delete
kubectl rollout status/undo/history
kubectl scale/autoscale/set
本阶段知识脉络
Kubernetes入门阶段知识体系:
核心概念 → 实操演练 → 最佳实践 → 故障排查
每一课都遵循:概念讲解 → 命令实操 → 代码示例 → 常见问题 → 练习巩固
确保学完即能上手,理论实践并重。
Kubernetes资源层次
K8s资源层次结构
Cluster(集群)
└── Namespace(命名空间)
├── Deployment(无状态应用)
│ └── ReplicaSet(副本集)
│ └── Pod(最小调度单元)
│ └── Container(容器)
├── StatefulSet(有状态应用)
│ └── Pod
├── DaemonSet(每节点一个Pod)
│ └── Pod
├── Job/CronJob(任务)
│ └── Pod
├── Service(服务发现)
├── Ingress(外部路由)
├── ConfigMap(配置)
├── Secret(密钥)
├── PV/PVC(持久化存储)
└── NetworkPolicy(网络策略)
K8s vs Docker Compose对比
| 特性 | Docker Compose | Kubernetes |
| 规模 | 单主机 | 多主机集群 |
| 自愈 | restart策略 | 自动重启/替换Pod |
| 扩缩容 | 手动--scale | HPA自动扩缩容 |
| 滚动更新 | 手动操作 | 自动RollingUpdate |
| 服务发现 | 服务名DNS | Service + CoreDNS |
| 配置管理 | .env文件 | ConfigMap + Secret |
| 存储 | Volume/Bind Mount | PV/PVC/StorageClass |
| 密钥管理 | 环境变量 | Secret(加密存储) |
| 网络策略 | 网络隔离 | NetworkPolicy |
| 适用场景 | 开发/小规模 | 生产/大规模 |
实战案例:故障排查流程
# Step 1: 检查容器状态
docker ps -a # 查看所有容器
docker inspect <container> # 查看详细配置
# Step 2: 查看日志
docker logs --tail 100 <container> # 最近100行日志
docker logs --since 1h <container> # 最近1小时
# Step 3: 进入容器排查
docker exec -it <container> sh # 进入容器shell
# Step 4: 检查资源
docker stats --no-stream # 资源使用概览
docker system df # 磁盘使用
# Step 5: 网络排查
docker network ls # 网络列表
docker exec <c> ping <target> # 网络连通性
docker exec <c> nslookup <svc> # DNS解析
# Step 6: 检查健康状态
docker inspect --format '{{.State.Health}}' <c>
docker inspect --format '{{.State.ExitCode}}' <c>
docker inspect --format '{{.State.OOMKilled}}' <c>
Dockerfile模板:多语言通用
# 通用最佳实践模板
FROM alpine:3.19 AS builder
# ... 构建步骤 ...
FROM alpine:3.19
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/output .
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
EXPOSE 8080
CMD ["./app"]
Docker Compose健康检查模板
services:
app:
build: .
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M