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 与实现体的偏离¶
- 镜像拉取速度低于预期:首次部署时 node-02 拉 quay.io 出现
TLS handshake timeout、node-03 拉 docker.io 出现response headers timeout,重试后均成功(分别耗时 1m57s 与 1m33s)。据此把 helm 超时从常规值放宽到 30m,并把该特征写入第三章前置条件与第八章风险表。 - 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。 - 影响:功能无影响,Pod 重建两次,重启计数归零。
- 遗留:该注解会保留在 Deployment 上;
kubectl diff默认忽略restartedAt,故常规漂移检查不会报出,属已知盲区。 - 处置:无需修复。若要与 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同步,请勿在站点侧修改)