跳转至

kube-prometheus-stack 全新部署 SOP(rainchen-k8s 集群)

配套文档:RUNBOOK.md(日常运行与故障处置,供值班使用)、backup/README.md(备份与回滚资产台账)。 本文只回答"这次改了什么、怎么改、怎么验、怎么退";服务的日常使用、排障、容量管理见 RUNBOOK。

目录

一、背景

项目 内容
变更类型 新增(集群此前无任何监控栈,也无 monitoring.coreos.com CRD,无迁移负担、无既有对象被覆盖)
触发条件 集群于 2026-09-16 重建为 v1.36.4(Rocky Linux 9.8 / containerd 2.3.5),旧集群的监控资料(CentOS 7、Harbor 镜像源、Traefik v2 写法)已不适用,需要在新集群配套监控与可视化能力
目标集群 rainchen-k8s:k8s-master-01(192.168.31.10,4C/7.6Gi)+ k8s-node-01/02/03(192.168.31.13/14/15,各 8C/16Gi)
chart 版本 kube-prometheus-stack 91.4.1(app v0.94.0 = prometheus-operator v0.94.0,operator 于 2026-09-02 发布)
存储 Prometheus TSDB → nfs-csi-hdd;Grafana / Alertmanager → nfs-csi(SSD)
入口 traefik(k8s-master-01 hostPort 80/443),域名 *.rainchen.top,内部 CA 自签证书
镜像来源 上游仓库直连(quay.io / registry.k8s.io / docker.io / ghcr.io)
执行日期 2026-09-17 13:34(首次安装)、13:40(幂等复跑)

二、目标

变更完成后应达到的可验证状态,以及 2026-09-19 复核时的实际值:

编号 目标状态 实测(2026-09-19,运行 2 天后)
G1 monitoring 下 9 个 Pod 全部 Running,重启次数 0 9/9 Running,重启次数全 0
G2 helm release deployed,chart 91.4.1 / app v0.94.0 revision 2,deployed,chart 91.4.1 / app v0.94.0
G3 Prometheus 运行 v3.13.3(LTS),TSDB 落 nfs-csi-hdd v3.13.3,PV volumeHandle 含 srv/nfs/k8s-hdd
G4 抓取目标全部 up,且无控制面常驻 down target 26/26 up,down 0,无 etcd/scheduler/controller-manager/kube-proxy target
G5 两个域名经 traefik 返回 200,Grafana 内置数据源与仪表盘 均 200;数据源 2 个,仪表盘 25 个
G6 重复执行第 5 章为零变更 见 6.6:apply 全部 unchanged,Pod/PVC uid 未变
G7 告警规则已加载,但不接外部渠道,仅存不发送 30 个 PrometheusRule 已加载,Alertmanager receiver 为 null

三、前置条件

3.1 权限与工具

项 要求 本次实测
集群权限 cluster-admin(需创建 CRD、ClusterRole/ClusterRoleBinding、命名空间) ~/.kube/config 中的 kubernetes-admin
本机工具 helm ≥ 3、kubectl、openssl、python3 helm v3.16.3、kubectl v1.36.4
远端权限 需能 ssh 到 root@192.168.31.10 做节点侧排障 可用(免密钥)

3.2 依赖

依赖 说明 本次实测
StorageClass nfs-csi-hdd 与 nfs-csi 均可动态供给 后端均为 192.168.31.249;SSD 侧 /srv/nfs/k8s、HDD 侧 /srv/nfs/k8s-hdd(500GiB loop 镜像)
入口 traefik 已接管 master-01 的 80/443,默认 IngressClass traefik 41.6.0 / v3.7.13,hostPort 80/443
TLS 证书 traefik 命名空间的 traefik-selfsigned-tls,SAN 需覆盖目标域名 SAN 含 *.rainchen.top,有效期至 2036-09-13
metrics-server 本 chart 不含,HPA 场景需另行提供 集群已运行 metrics-server v0.9.0,本次不涉及
镜像可达性 节点可直连海外仓库 可达但慢:prometheus 镜像 1m57s、grafana 镜像(460MB)1m33s

3.3 执行前检查(只读)

kubectl get nodes
# 预期:4 个节点均为 Ready,版本 v1.36.4

kubectl get sc
# 预期:含 nfs-csi-hdd 与 nfs-csi(default)

kubectl get crd | grep -c monitoring.coreos.com
# 预期:0(首次部署)。非 0 说明集群已有监控栈,须改走升级流程,不可直接套用本 SOP

kubectl get ns monitoring
# 预期:Error from server (NotFound)。若已存在,须先确认其内容归属

helm list -n monitoring
# 预期:空。若已有同名 release,先执行第 5 章步骤 0 备份

四、影响范围

项 内容
涉及主机 全部 4 台节点。node-exporter 为 DaemonSet 并已加 operator: Exists 容忍,穿透 master 的 control-plane:NoSchedule 污点,4 个实例全覆盖
组件落点 Prometheus / Alertmanager / operator / kube-state-metrics 落在 k8s-node-02,Grafana 落在 k8s-node-03(调度器决定,未做硬约束)
集群级变更 新增 10 个 monitoring.coreos.com CRD、24 个 ClusterRole/ClusterRoleBinding、1 个 ValidatingWebhookConfiguration(kube-prometheus-stack-admission)
命名空间级变更 新建 monitoring;其中 6 类工作负载、9 个 ServiceMonitor、30 个 PrometheusRule、3 个 PVC
是否需停服 不需要。全部为新增资源,未修改任何既有工作负载;既有 gitlab / traefik / nfs-csi / calico / cnpg 不受影响
业务影响 无。新增 Pod requests 合计约 1.1C/3Gi;节点 CPU 使用率由 4%~14% 升至 5%~15%,内存由 15%~23% 升至 25%~33%(含既有业务自身增长)
窗口期 无强制窗口。首次部署含镜像拉取实测约 4 分钟;镜像完全未缓存时最坏约 10 分钟
新增持久化 3 个 PVC:Prometheus 100Gi(nfs-csi-hdd)、Grafana 10Gi(nfs-csi)、Alertmanager 10Gi(nfs-csi)
回滚成本 低。helm uninstall 即可移除全部工作负载;CRD 与 PVC 默认保留;详见第七章

五、分步操作

以下为实现体的等价操作序列,供阅读、复核与手工复现,以实现体为准。 实现文件:prometheus_deploy/values.yaml、prometheus_deploy/manifests/00-namespace.yaml、prometheus_deploy/manifests/crds/、prometheus_deploy/manifests/02-ingressroute.yaml。 代码块不承担幂等与错误处理,幂等性由 kubectl apply 与 helm upgrade --install 的语义保证(验证见 6.6)。

cd prometheus_deploy                                  # 进入交付目录,以下均为相对该目录的路径

# —— 步骤 0:前置备份(仅在集群已存在同名 release 时执行;本次为新装故跳过)——
# 高危:helm upgrade 会覆盖既有 release 的工作负载定义,升级前必须先留档
helm get manifest kube-prometheus-stack -n monitoring > ../backup/manifests/kube-prometheus-stack-$(date +%Y%m%d-%H%M%S).yaml
helm get values kube-prometheus-stack -n monitoring > ../backup/values/kube-prometheus-stack-$(date +%Y%m%d-%H%M%S).yaml

# —— 步骤 1:安装 CRD ——
# 高危:集群级对象,影响所有命名空间的 CR 创建;本步不可与其他 release 混管
# 用 --server-side 规避 client-side apply 的 262144 字节 annotation 上限(单个 CRD 可达 840KB)
kubectl apply --server-side -f manifests/crds/        # 创建 10 个 CRD,幂等

# —— 步骤 2:创建命名空间 ——
kubectl apply -f manifests/00-namespace.yaml          # 幂等:已存在则 unchanged

# —— 步骤 3:创建 Grafana admin 凭据 ——
# 密码随机生成、不入 values 明文、不写入任何文档;仅落 600 权限文件供取用
PW_FILE=logs/grafana-admin-password.txt
if [ ! -f "$PW_FILE" ]; then                          # 幂等:已生成则跳过,不覆盖既有密码
  PW="$(openssl rand -base64 24 | tr -d '/+=' | cut -c1-18)"
  kubectl create secret generic grafana-admin -n monitoring \
    --from-literal=admin-user=admin --from-literal=admin-password="$PW"
  printf 'admin / %s\n' "$PW" > "$PW_FILE" && chmod 600 "$PW_FILE"
fi

# —— 步骤 4:安装监控栈 ——
# --timeout 30m 是为适配节点拉镜像慢(单镜像可达 2 分钟),非组件启动慢
# --wait 表示等待工作负载就绪,失败会返回非 0,便于流水线判定
helm upgrade --install kube-prometheus-stack \
  charts/kube-prometheus-stack-91.4.1.tgz \
  -n monitoring -f values.yaml \
  --timeout 30m --wait

# —— 步骤 5:暴露入口 ——
# 路由不写 tls.secretName:证书位于 traefik 命名空间,而 CRD 的 secretName 按同命名空间解析,
# 显式写反而找不到;沿用 traefik values 中 tlsStore.default 的默认证书更稳
kubectl apply -f manifests/02-ingressroute.yaml       # prometheus / grafana 两条路由,幂等

各步失败时的判断依据

步骤 失败表现 判断与处置
1 error: unable to recognize 或 CRD 校验失败 多为 kubectl 版本过低;确认 ≥ v1.25。若报 annotation 超长,说明漏了 --server-side
2 namespaces "monitoring" already exists 非致命,说明此前已建;用 kubectl get ns monitoring -o yaml 确认归属后再继续
3 Secret 创建失败 确认命名空间已存在(步骤 2 必须先于本步)
4 Error: UPGRADE FAILED: context deadline exceeded 多为镜像拉取超时。先执行 kubectl -n monitoring get pods 看是否有 ImagePullBackOff,等镜像拉齐后重跑步骤 4 即可;release 会自动回到 deployed
4 Release ... failed 且 Pod 反复重启 见 RUNBOOK 的「Pod 无法启动」场景;确认无误后按第七章回滚
5 no matches for kind "IngressRoute" traefik CRD 未安装;确认 kubectl api-resources \| grep ingressroute 有输出

关键参数说明(改值只改 prometheus_deploy/values.yaml)

参数 值 含义
crds.enabled false CRD 由步骤 1 独立管理。交给 release 会导致 helm uninstall 连删 CRD 及集群内全部 CR
prometheus.prometheusSpec.image.tag v3.13.3 钉在 LTS 版本,不跟随 operator 默认的 3.14.0
prometheus.prometheusSpec.retention 15d 保留期的时间维度上限
prometheus.prometheusSpec.retentionSize 90GiB 保留期的容量维度上限,先于 100Gi PVC 写满触发
prometheus.prometheusSpec.securityContext.fsGroup 65534 使 nobody 用户可写 NFS 卷,依赖 nfs-csi 的 enableFSGroupPolicy 与导出侧 no_root_squash
kubeEtcd / kubeScheduler / kubeControllerManager / kubeProxy .enabled false 其监听地址为 127.0.0.1,集群内抓不到,连同对应告警规则一并关闭
prometheus-node-exporter.tolerations operator: Exists 使 master 节点也被采集
alertmanager.config.receivers 单一 null 本轮不接外部告警渠道
grafana.admin.existingSecret grafana-admin 密码经 Secret 注入,values 中不出现明文

六、验证

6.1 release 与版本

helm list -n monitoring
# 预期:kube-prometheus-stack  monitoring  2  deployed  kube-prometheus-stack-91.4.1  v0.94.0
# 若 CHART 不是 91.4.1 或 STATUS 非 deployed:执行 helm history kube-prometheus-stack -n monitoring 查看失败原因

kubectl get pods -n monitoring -o wide
# 预期:9 个 Pod 全部 Running,RESTARTS 全为 0
# 若存在非 Running:见 RUNBOOK 的「Pod 无法启动」场景

kubectl get pod -n monitoring -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort -u
# 预期(8 个镜像):
#   docker.io/grafana/grafana:13.2.2-distroless
#   quay.io/kiwigrid/k8s-sidecar:2.11.2
#   quay.io/prometheus/alertmanager:v0.34.0
#   quay.io/prometheus/node-exporter:v1.12.1-distroless
#   quay.io/prometheus/prometheus:v3.13.3
#   quay.io/prometheus-operator/prometheus-operator:v0.94.0
#   quay.io/prometheus-operator/prometheus-config-reloader:v0.94.0
#   registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.20.0

6.2 存储落点

kubectl get pvc -n monitoring
# 预期:3 个 PVC 全部 Bound
#   prometheus-kube-prometheus-stack-prometheus-db-...   100Gi  nfs-csi-hdd
#   kube-prometheus-stack-grafana                         10Gi  nfs-csi
#   alertmanager-kube-prometheus-stack-alertmanager-db-... 10Gi  nfs-csi
# 若有 Pending:kubectl describe pvc <名> -n monitoring 看 provisioner 报错,多为 NFS 服务端不可达

kubectl get pv -o custom-columns='SC:.spec.storageClassName,HANDLE:.spec.csi.volumeHandle,RECLAIM:.spec.persistentVolumeReclaimPolicy' | grep nfs-csi
# 预期:Prometheus 的 HANDLE 含 192.168.31.249#srv/nfs/k8s-hdd#;
#       Grafana/Alertmanager 的 HANDLE 含 192.168.31.249#srv/nfs/k8s#;RECLAIM 均为 Delete

6.3 抓取目标与 TSDB

# 本机临时转发 Prometheus 端口(Prometheus Service 为 ClusterIP,无对外路由开放 API 以外的用途)
kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 19090:9090 &

curl -s http://localhost:19090/api/v1/status/buildinfo | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["version"])'
# 预期:3.13.3

curl -s http://localhost:19090/api/v1/targets | python3 -c '
import sys,json
d=json.load(sys.stdin)["data"]["activeTargets"]
print("合计",len(d),"up",len([t for t in d if t["health"]=="up"]))'
# 预期:合计 26 up 26(实测 26/26,非 up 恒为 0)
# 若出现非 up:curl -s http://localhost:19090/api/v1/targets | python3 -c '...打印 lastError...' 定位,
#             常见为 kubelet 的 10250 证书校验与 apiserver 的 token 失效,见 RUNBOOK 对应场景

curl -s http://localhost:19090/api/v1/status/tsdb | python3 -c '
import sys,json;print("head series:",json.load(sys.stdin)["data"]["headStats"]["numSeries"])'
# 预期:7 万~9 万量级(实测:上线 5 分钟时 73,444;运行 2 天后 87,571)

6.4 Grafana

kubectl -n monitoring port-forward svc/kube-prometheus-stack-grafana 13000:80 &
PW=$(kubectl -n monitoring get secret grafana-admin -o jsonpath='{.data.admin-password}' | base64 -d)

curl -s -u "admin:$PW" http://localhost:13000/api/health
# 预期:{"database":"ok","version":"13.2.2",...}

curl -s -u "admin:$PW" http://localhost:13000/api/datasources
# 预期含两条:Prometheus → http://kube-prometheus-stack-prometheus.monitoring:9090/
#             Alertmanager → http://kube-prometheus-stack-alertmanager.monitoring:9093/

curl -s -u "admin:$PW" 'http://localhost:13000/api/search?type=dash-db&limit=500' \
  | python3 -c 'import sys,json;print("仪表盘:",len(json.load(sys.stdin)))'
# 预期:25

6.5 入口可达

# 未配 DNS 时用 --resolve 把域名直接指向入口 IP,避免依赖解析
curl -sk --resolve prometheus.rainchen.top:443:192.168.31.10 -o /dev/null -w '%{http_code}\n' \
  https://prometheus.rainchen.top/-/ready
# 预期:200。若 404 → 路由未生效(kubectl get ingressroute -n monitoring);若超时 → traefik 未监听 443

curl -sk --resolve grafana.rainchen.top:443:192.168.31.10 -o /dev/null -w '%{http_code}\n' \
  https://grafana.rainchen.top/login
# 预期:200

openssl s_client -connect 192.168.31.10:443 -servername grafana.rainchen.top </dev/null 2>/dev/null \
  | openssl x509 -noout -ext subjectAltName
# 预期:DNS 含 *.rainchen.top,与访问域名匹配(自签,客户端需导入内部 CA 才不告警)

6.6 幂等复跑验证

# 复跑前抓取对象指纹(uid 是对象身份,重建即变化)
kubectl get pods,pvc -n monitoring -o jsonpath='{range .items[*]}{.kind}/{.metadata.name}{"\t"}{.metadata.uid}{"\n"}{end}' | sort > logs/07-idem-before.txt

kubectl apply --server-side -f manifests/crds/     # 预期:无实质变更
kubectl apply -f manifests/00-namespace.yaml       # 预期:namespace/monitoring unchanged
kubectl apply -f manifests/02-ingressroute.yaml    # 预期:两条路由 unchanged
helm upgrade --install kube-prometheus-stack charts/kube-prometheus-stack-91.4.1.tgz \
  -n monitoring -f values.yaml --timeout 30m --wait

kubectl get pods,pvc -n monitoring -o jsonpath='{range .items[*]}{.kind}/{.metadata.name}{"\t"}{.metadata.uid}{"\n"}{end}' | sort > logs/07-idem-after.txt
diff logs/07-idem-before.txt logs/07-idem-after.txt
# 预期:无输出

实测结果:三个 apply 全部 unchanged;helm release 的 revision 由 1 递增为 2(helm 的版本记录机制),但全部 Pod 与 PVC 的 uid 未变、无任何重建、重启次数保持 0——即集群侧零变更。

若要求 helm 层也完全跳过,可在升级前先比对渲染结果与集群现状,无差异则不执行 helm upgrade:

helm template kube-prometheus-stack charts/kube-prometheus-stack-91.4.1.tgz -n monitoring -f values.yaml \
  | kubectl diff -f -
# 预期:差异仅出现在带 helm.sh/hook 注解的 admission webhook 资源上
#       (此类 hook 成功后已被删除,但 helm template 仍会渲染,属已知噪音),其余对象无差异
# 注意:不要用 --server-side 做该比对,会因字段管理器与 helm 冲突而报 Conflict

七、回滚

7.1 备份方式与位置

本次为全新部署,未覆盖任何既有文件或对象,因此不存在 .bak 类备份。回滚依赖的离线资产与台账登记见 prometheus_deploy/backup/README.md:

资产 位置 用途
chart 离线包 prometheus_deploy/charts/kube-prometheus-stack-91.4.1.tgz 不依赖仓库可用性即可重建
定制 values prometheus_deploy/values.yaml 原样复用
CRD 定义 prometheus_deploy/manifests/crds/ CRD 与 release 解耦,可独立重建
渲染快照 prometheus_deploy/logs/rendered-manifests.yaml 部署前完整渲染结果,用于回溯"本该是什么样"
Grafana 凭据 prometheus_deploy/logs/grafana-admin-password.txt(600) 卸载重建后需重建同名 Secret

7.2 回滚步骤

级别一:移除工作负载(保留 CRD 与数据,最常用)

# 高危:删除本 release 全部工作负载、Service、ServiceMonitor、PrometheusRule
# 保留:CRD、PVC 与其中的监控数据(helm uninstall 不触碰 PVC,因 PVC 非 release 管理)
# 回滚前备份 release 定义,便于日后原样恢复:
helm get manifest kube-prometheus-stack -n monitoring > ../backup/manifests/rollback-$(date +%Y%m%d-%H%M%S).yaml
helm uninstall kube-prometheus-stack -n monitoring

# 如确认不再需要入口路由
kubectl delete -f manifests/02-ingressroute.yaml

级别二:连同持久化数据一并清除(数据不可恢复)

# 高危:SC 为 Delete,删除 PVC 会连带删除 NFS 服务端上的数据目录,无回收站
# 执行前先确认清单,逐条核对后再删
kubectl -n monitoring get pvc
kubectl -n monitoring delete pvc prometheus-kube-prometheus-stack-prometheus-db-prometheus-kube-prometheus-stack-prometheus-0
kubectl -n monitoring delete pvc kube-prometheus-stack-grafana
kubectl -n monitoring delete pvc alertmanager-kube-prometheus-stack-alertmanager-db-alertmanager-kube-prometheus-stack-alertmanager-0
kubectl -n monitoring delete secret grafana-admin
kubectl delete -f manifests/00-namespace.yaml

级别三:彻底清除,含 CRD 与所有 CR

# 高危:删除 CRD 会级联删除集群内全部 Prometheus / Alertmanager / ServiceMonitor /
#       PrometheusRule / PodMonitor / Probe / ScrapeConfig / ThanosRuler 对象
# 若集群内存在其他依赖这些 CRD 的监控栈,禁止执行本级别
kubectl delete -f manifests/crds/

7.3 回滚后的验证

kubectl get all -n monitoring
# 级别一后预期:无工作负载残留(仅可能剩 Service/CR 由 CRD 决定,若执行了级别三则全无)

kubectl get crd | grep -c monitoring.coreos.com
# 级别一/二后预期:10;级别三后预期:0

kubectl get pvc -n monitoring
# 级别一后预期:仍有 3 个 PVC(数据保留);级别二后预期:No resources found

curl -sk --resolve prometheus.rainchen.top:443:192.168.31.10 -o /dev/null -w '%{http_code}\n' \
  https://prometheus.rainchen.top/-/ready
# 级别一后预期:404(路由已摘除,traefik 入口本身仍在)

kubectl get pods -A | grep -vE 'Running|Completed'
# 预期:无输出,即无新增异常 Pod

八、风险说明

风险点 影响 缓解措施
HDD 承载 TSDB(本方案的核心取舍) nfs-csi-hdd 是 dell-R620 /data 机械盘上的 500GiB ext4 loop 镜像,且该盘同时承载 4 台 k8s VM 的 qcow2;TSDB 的 WAL 持续写与两小时一次 compaction 属小随机 IO,可能与 VM 争抢磁盘 设 retentionSize: 90GiB + retention: 15d 双上限。实测写入量远低于预估:运行 2 天占 1113 MiB(blocks 866 MB + WAL 251 MB),线性外推 15 天约 8~9 GiB,对 100Gi PVC 与 HDD 压力都很小。若日后 series 数量级增长,改 values.yaml 的 storageClassName 为 nfs-csi 并重建 PVC 即可迁移
NFS 使用 hard 挂载(timeo=600, retrans=3) NFS 服务端 192.168.31.249 抖动时,Prometheus 的 IO 会阻塞在 D 状态,监控数据断档 监控数据非业务关键,断档可接受;需注意 NFS 服务端与 k8s 节点同宿主机,属同源故障域(宿主机重启会同时影响两者)
单副本、无 HA Prometheus Pod 重启期间无采集,窗口内数据不可回溯 已接受。如需 HA:replicas: 2 + 硬反亲和 + Thanos Query 去重,属独立变更
PVC 回收策略为 Delete 误删 PVC 会立即删除 NFS 上的历史数据 回滚章节已标注「高危」并要求逐条核对;如需保留应改用 Retain 策略的自定义 SC(本次沿用既有 SC,未改动存储层)
控制面指标缺失 无 etcd / kube-scheduler / kube-controller-manager / kube-proxy 指标,相关告警也一并关闭 属本次刻意裁剪。补齐需另行变更各组件的 --bind-address 并重启控制面,影响面独立,不混入本次变更
镜像拉取慢且偶发超时 首次部署耗时较长;拉取失败会进入 ImagePullBackOff 并自动重试 已设 --timeout 30m。若节点网络长期不稳,可先推镜像到内网仓库,再改 values.yaml 的 image 字段
自签证书不受信 浏览器访问会告警;且需 DNS 能解析 *.rainchen.top 沿用既有内部 CA,可分发 traefik_deploy/certs/ca.crt 给客户端导入
Alertmanager 已加载规则但不发通知 告警仅停留在 Alertmanager 界面,不会主动触达 与用户约定的本轮范围;接入渠道(飞书/邮件)为独立变更,只需追加 receivers 与 route
Grafana admin 密码为随机生成 与旧环境惯用密码不同 明文仅在 logs/grafana-admin-password.txt(600);文档只写取用命令,不落明文。轮换见 RUNBOOK
绕过 helm 直接改工作负载 会产生注解级漂移,helm upgrade 时不易察觉 见附录 C。规范做法是改 values.yaml 后走 helm upgrade;确需重启用 kubectl rollout restart 并知悉其会写入 restartedAt 注解

附录 A:交付物清单

路径(相对项目根) 说明
prometheus_deploy/SOP.md 本文档
prometheus_deploy/RUNBOOK.md 服务运行与使用手册(日常运维、故障处置)
prometheus_deploy/values.yaml 定制 values,唯一的配置改动入口
prometheus_deploy/manifests/00-namespace.yaml 命名空间
prometheus_deploy/manifests/crds/ 10 个 monitoring.coreos.com CRD 定义
prometheus_deploy/manifests/02-ingressroute.yaml Prometheus / Grafana 两条 Traefik 路由
prometheus_deploy/charts/kube-prometheus-stack-91.4.1.tgz 离线 chart 包
prometheus_deploy/charts/values-default-91.4.1.yaml chart 原始默认 values,用于比对排查
prometheus_deploy/backup/README.md 备份与回滚资产台账
prometheus_deploy/logs/ 各步骤原始日志、渲染快照、幂等指纹、Drift 检查

附录 B:决策经过

决策点 取舍 理由
chart 版本 91.4.1(最新)而非 90.2.0(更保守) operator v0.94.0 于 2026-09-02 发布,至变更日已沉淀两周,且 91.x 系列已迭代 5 个 patch
Prometheus 版本 v3.13.3(LTS)而非 operator 默认的 v3.14.0 3.14 是最新稳定版,但按官方 6 周节奏非 LTS 版本随后即停止修 bug;3.13 LTS 的 bugfix 支持到 2027-07-31,且 3.13.2 在 operator 兼容矩阵内
CRD 管理方式 crds.enabled: false + 独立 apply 交给 Helm 会导致 helm uninstall 连删 CRD 及全部 CR,且 Helm 不更新 CRD;与既有 nfs-csi 的做法一致
存储落点 Prometheus 用 HDD,Grafana/Alertmanager 用 SSD 用户指定 TSDB 用 nfs-csi-hdd;Grafana 的 sqlite 与 Alertmanager 的少量状态写入对 IO 敏感但数据量小,放 SSD 避免无谓的机械盘 IO
控制面监控 关闭而非改造监听地址 实测四类组件均绑 127.0.0.1,改造需重启控制面且影响面独立,不宜与本次混做
告警渠道 本轮不接,Alertmanager 空跑 先观察规则误报率,避免上线即产生噪音;接渠道是独立的小变更
入口方式 Traefik IngressRoute(traefik.io/v1alpha1) 与集群既有入口体系一致;旧资料的 traefik.containo.us 组号在 v3 已移除,不可沿用

附录 C:实施记录与偏离说明

C.1 执行时间线

时间(北京时间) 事件
2026-09-17 13:30 前置检查:确认无 monitoring CRD 与命名空间;验证节点可直连 quay.io / docker.io(慢)
2026-09-17 13:33 安装 10 个 CRD(server-side)、创建 monitoring 命名空间、创建 grafana-admin Secret
2026-09-17 13:34 helm upgrade --install 完成,revision 1,deployed
2026-09-17 13:37 应用两条 IngressRoute
2026-09-17 13:38 验证:26/26 target up、Grafana 健康、两域名 200
2026-09-17 13:40 幂等复跑,revision 2;Pod/PVC uid 未变,零重建
2026-09-19 13:36 / 13:39 运行期外部操作:Grafana Deployment 被 kubectl rollout restart 两次(详见 C.2)
2026-09-19 复核:9/9 Pod Running、26/26 up、head series 87,571、两域名 200,无新增漂移

C.2 与实现体的偏离

  1. 镜像拉取速度低于预期:首次部署时 node-02 拉 quay.io 出现 TLS handshake timeout、node-03 拉 docker.io 出现 response headers timeout,重试后均成功(分别耗时 1m57s 与 1m33s)。据此把 helm 超时从常规值放宽到 30m,并把该特征写入第三章前置条件与第八章风险表。
  2. Grafana 被绕过 helm 重启:2026-09-19 13:36 与 13:39,Grafana Deployment 的 podTemplate 两次变更,ReplicaSet 依次为 6c6db755c4 → 769b5d8d8c → 57cdd7cddf。经比对,差异仅为 kubectl.kubernetes.io/restartedAt 注解与随之变化的 pod-template-hash,容器镜像与其余 spec 完全一致;helm history 无新 revision,说明是直接对 Deployment 执行 kubectl rollout restart,而非走 helm upgrade。
  3. 影响:功能无影响,Pod 重建两次,重启计数归零。
  4. 遗留:该注解会保留在 Deployment 上;kubectl diff 默认忽略 restartedAt,故常规漂移检查不会报出,属已知盲区。
  5. 处置:无需修复。若要与 helm 完全对齐,可执行一次 helm upgrade --install(参数同第 5 章步骤 4)后观察;本 SOP 未执行该动作。

C.3 未产出 INCIDENT 文档的说明

本次变更过程未发生故障,运行期未发生中断或数据损坏,故不产出 INCIDENT-*.md。运行期唯一处于 firing 状态的业务告警是 KubeHpaMaxedOut(server 命名空间的 gitlab-sidekiq-all-in-1-v2 HPA 达到 maxReplicas 超过 15 分钟),属既有业务容量问题,非本次监控栈引入,已登记在 RUNBOOK 的「监控与告警」章节供值班跟进;Watchdog 为设计上恒定 firing 的心跳告警,属正常。


来源:/home/rain/Documents/k8s_ins/prometheus_deploy/SOP.md | 最后更新:2026-09-19 16:49(由 build/sync.py 同步,请勿在站点侧修改)