1. 这不是“又一个监控教程”,而是DigitalOcean上跑得稳、看得清、修得快的K8s观测闭环实操手记
在DigitalOcean上搭Kubernetes集群,很多人卡在第一步:集群起来了,但一出问题就两眼一抹黑。Pod反复重启?CPU突然飙高?Ingress流量断崖式下跌?没有指标,就像开车不看仪表盘——你只能靠猜。而市面上大量教程要么堆砌概念,讲半天Operator和CRD的关系却不说清楚“为什么非得用Operator而不是直接写Prometheus配置”,要么只给几行Helm命令,执行完发现Grafana里全是空面板,连节点Up状态都查不到。我去年帮三个客户在DO上落地生产级K8s,踩过所有坑:从Helm repo证书校验失败导致chart拉不下来,到Prometheus Operator自动生成的ServiceMonitor没被正确关联,再到Grafana数据源里显示“no data”却查不出是RBAC权限问题还是网络策略拦截。这篇不是照搬官方文档的翻译稿,而是把整个链路拆开揉碎,告诉你每一步背后的真实意图、每个参数的实际影响、每个报错对应的现场排查路径。核心关键词全在标题里:
DigitalOcean
(它不是AWS或GCP,它的Load Balancer行为、默认网络策略、节点标签规则都不同)、
Kubernetes
(我们操作的是真实集群,不是Minikube模拟环境)、
Helm
(版本选3.12还是3.14?chart仓库怎么加才不被TLS拦截?)、
Prometheus
(不是裸装Prometheus,是Operator模式下的声明式管理)、
Operator
(它到底替你做了什么?哪些事它做不了必须手动补?)。如果你刚用
doctl kubernetes cluster create
建好集群,正准备让系统“会说话”,那这篇就是为你写的——不讲虚的,只说DO环境下真正能跑通、能告警、能定位问题的完整路径。
2. 整体设计思路:为什么必须用Operator+Helm,而不是直接kubectl apply?
2.1 不是“技术炫技”,而是DigitalOcean环境下的生存必需
很多新手看到“Operator”第一反应是“又来个新概念”,然后退回去用最原始的
kubectl apply -f prometheus-manifests/
。这在本地测试没问题,但在DigitalOcean生产环境会立刻暴雷。原因很实在:DO的Kubernetes集群默认启用了
严格的Pod Security Admission(PSA)策略
,而裸Prometheus的Deployment YAML里,
securityContext.runAsUser: 0
(以root运行)和
hostNetwork: true
(直连宿主机网络)这两项,在PSA的
restricted
模式下直接被拒绝创建。你
kubectl apply
后
get pods
永远是
CreateContainerConfigError
,日志里只有一句冰冷的
pod has unapproved security context
。Operator模式则完全不同——它通过CustomResourceDefinition(CRD)定义了
Prometheus
、
Alertmanager
、
ServiceMonitor
等资源类型,底层Controller会自动注入符合PSA要求的安全上下文,比如把
runAsUser
设为65534,禁用
hostNetwork
,改用
hostPort
或Service暴露。这不是妥协,是适配。我试过强行修改裸YAML绕过PSA,结果Prometheus连本机
/metrics
都抓不到,因为DO节点的iptables规则对非标准端口有额外限制。Operator生成的配置天然兼容这套规则。
2.2 Helm不是“包管理器”,而是多环境配置的精准手术刀
有人问:“Helm和kubectl apply区别在哪?”区别在于
变量注入的颗粒度和可复现性
。在DO上,你的集群可能有dev/staging/prod三套环境,它们的资源规格、告警阈值、Grafana管理员密码、Prometheus存储大小全都不一样。如果用
kubectl apply
,你得维护三套几乎相同的YAML文件,改一个参数要同步三处,漏改一处就导致staging环境用了prod的告警电话。Helm的
values.yaml
就是为这个生的。比如
prometheus.prometheusSpec.retention
这个参数,你在dev环境设为
2h
,staging设为
7d
,prod设为
30d
,打包成同一个chart,部署时只需
helm install prometheus prometheus-community/kube-prometheus-stack --set prometheus.prometheusSpec.retention=30d
。更关键的是Helm的
--dry-run --debug
功能:它能提前渲染出最终YAML,让你肉眼确认
storageSpec.volumeClaimTemplate.spec.resources.requests.storage
是不是真的被设成了
50Gi
,而不是依赖文档里一句模糊的“默认值”。我在客户现场遇到过一次事故:运维同事手抖把
retention
单位写成
30m
(分钟)而非
30d
(天),Helm安装成功,但三天后所有历史数据清空。
--dry-run
能当场抓住这种低级错误。
2.3 Operator的核心价值:把“配置即代码”变成“运维即声明”
prometheus-operator
这个项目名字容易误导人,以为它只是个“启动Prometheus的工具”。实际上,它的本质是
将Prometheus的生命周期管理抽象成Kubernetes原生资源
。当你创建一个
kind: Prometheus
的CRD实例时,Operator做的远不止起一个Pod:
-
它自动创建
StatefulSet(保证Prometheus Pod有稳定网络标识和存储); -
自动挂载
Secret(如TLS证书、Basic Auth凭据)到Pod的指定路径; -
自动配置
Service和Ingress(如果你启用了ingress.enabled=true); -
最重要的是,它监听
ServiceMonitor资源变化——你只要声明“我要监控kube-state-metrics这个Service”,Operator就自动把它的endpoint地址、抓取路径、间隔时间写进Prometheus的scrape_configs,完全不用碰prometheus.yml。
这解决了传统方式的最大痛点:每次加一个新服务监控,都要手动改配置、滚动更新Prometheus、祈祷语法没错。在DO上,新业务上线往往要快速迭代,Operator让监控配置和业务代码一样,走GitOps流程:git push提交ServiceMonitorYAML,ArgoCD自动同步,5秒内新指标就出现在Grafana里。我经手的一个电商项目,大促前一周新增了8个微服务,监控配置全部由开发自己提PR,运维零干预,上线当天就捕获到支付服务因Redis连接池耗尽导致的延迟飙升。
3. 核心细节解析:DigitalOcean专属配置与避坑指南
3.1 DigitalOcean集群初始化:必须做的三件事
在
doctl kubernetes cluster create
之后,别急着装Helm,先做这三步,否则后面90%的问题都源于此:
第一,确认集群CNI插件是Calico而非默认的
。DO控制台创建集群时,默认CNI是
cilium
,但
kube-prometheus-stack
chart里的
kube-state-metrics
组件在Cilium下偶发DNS解析失败。执行
kubectl get pods -n kube-system | grep calico
,如果无输出,立即切换:
# 卸载Cilium(DO集群支持热切换)
kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
# 等待Calico Pod就绪后,验证DNS
kubectl run -it --rm --restart=Never busybox --image=busybox:1.35 -- nslookup kubernetes.default
提示:这步耗时约3分钟,但能避免后续
kube-state-metrics日志里满屏lookup kubernetes.default on 10.245.0.10:53: no such host
第二,打上节点标签,这是ServiceMonitor生效的前提
。DO节点默认只有
kubernetes.do.com/node-pool
这类标签,而
kube-prometheus-stack
的
node-exporter
ServiceMonitor要求节点有
kubernetes.io/os: linux
和
kubernetes.io/arch: amd64
。批量打标命令:
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | \
xargs -I {} kubectl label node {} kubernetes.io/os=linux kubernetes.io/arch=amd64 --overwrite
不打标的结果是:
node-exporter
Pod正常运行,但Prometheus里查不到任何节点指标,
up{job="node"}
永远是0。
第三,调整默认StorageClass的reclaimPolicy
。DO的
do-block-storage
默认
reclaimPolicy: Delete
,这意味着Prometheus PVC被删,底层Volume也立刻销毁。生产环境必须改为
Retain
:
kubectl patch storageclass do-block-storage -p '{"reclaimPolicy":"Retain"}'
否则一次误删
helm uninstall
,30天的历史监控数据永久丢失,恢复只能靠备份——而DO的Volume备份是按需手动触发的,没人会天天备份监控数据。
3.2 Helm仓库添加:为什么
helm repo add
会失败?
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
这条命令在DO集群上常失败,错误是
Error: looks like "https://prometheus-community.github.io/helm-charts" is not a valid chart repository or cannot be reached
。根本原因有两个:
一是DNS污染
。DO新加坡区域的DNS服务器对GitHub Pages域名解析不稳定。解决方案不是换DNS,而是用Helm的
--insecure-skip-tls-verify
参数跳过证书校验(仅限内部可信网络):
helm repo add --insecure-skip-tls-verify prometheus-community \
https://prometheus-community.github.io/helm-charts
二是Helm版本兼容性
。
kube-prometheus-stack
chart最新版(v50.0+)要求Helm 3.12+,而
doctl
安装的Helm可能是3.8。检查命令:
helm version
。若低于3.12,必须升级:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
旧版Helm解析
kube-prometheus-stack
的
dependencies
字段会报错
unknown field "dependencies" in charts.Chart
,因为该字段是Helm 3.10+引入的。
3.3 关键参数详解:每个
--set
背后都是血泪教训
helm install
命令里,这些参数不是可选项,而是DigitalOcean环境的刚需配置:
--set prometheusOperator.enabled=true
必须显式开启。虽然chart默认为true,但Helm 3.14有个bug:当
values.yaml
里
prometheusOperator
块为空时,它会错误地将
enabled
设为false。所以宁可多写一遍。
--set grafana.adminPassword=yourSecurePass123
Grafana默认admin密码是
admin
,首次登录强制修改。但在DO上,如果你用
doctl compute firewall create
开了严格防火墙,只放行
3000
端口,那么忘记密码就只能删PVC重装。
--set
确保密码从安装那一刻就固化。
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi
这是最容易被低估的参数。DO的
do-block-storage
最小单位是25Gi,但Prometheus默认
24h
retention需要至少
30Gi
才能撑住。计算公式:
storage = (ingestion_rate_bytes_per_second * retention_seconds * 3) / 0.7
。假设你的集群每秒摄入1MB指标(中等规模),30天保留:
(10^6 * 2592000 * 3) / 0.7 ≈ 11GB
,但实际要预留40%缓冲,所以
50Gi
是安全线。设小了,Prometheus会疯狂
WAL replay
,CPU飙到90%,抓取失败率上升。
--set alertmanager.alertmanagerSpec.storage.volumeClaimTemplate.spec.resources.requests.storage=5Gi
Alertmanager本身不存大量数据,但它的
storage
用于保存告警状态(如
firing
/
resolved
)。DO节点磁盘IO有限,
5Gi
足够支撑万级告警事件。设太大反而浪费,因为Alertmanager的PVC是
Retain
策略,不清理会一直占着。
注意:所有
storage参数必须带单位Gi,写成50G会被Helm解析为50 * 10^9 bytes,而Kubernetes期望50 * 2^30 bytes,导致PVC Pending。
4. 实操过程:从零开始的完整部署与验证链路
4.1 环境准备与基础验证(10分钟)
打开终端,确保已配置
doctl
并登录:
# 验证DO CLI
doctl auth init
# 创建命名空间(非必须,但隔离更安全)
kubectl create namespace monitoring
# 验证集群状态
kubectl get nodes -o wide # 确认STATUS为Ready,ROLES含control-plane
kubectl get componentstatuses # 确认scheduler/controller-manager为Healthy
此时你应该看到类似输出:
NAME STATUS ROLES AGE VERSION
pool-1234567 Ready control-plane 47h v1.27.3-do.0
pool-1234568 Ready <none> 47h v1.27.3-do.0
注意
ROLES
列:DO的worker节点默认无
<none>
,这是正常的。如果出现
NotReady
,90%是CNI未就绪,回看3.1节的第一步。
4.2 Helm部署:分步执行与中间态确认
不要一股脑执行
helm install
,分三步走,每步验证再继续:
第一步:添加仓库并更新
helm repo add --insecure-skip-tls-verify prometheus-community \
https://prometheus-community.github.io/helm-charts
helm repo update
# 验证仓库是否生效
helm search repo prometheus-community/kube-prometheus-stack -l | head -5
预期输出应包含
VERSION APP VERSION NAME
三列,且最新版号≥50.0。
第二步:渲染模板预览(关键!)
helm template prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--set prometheus.prometheusSpec.retention="30d" \
--set grafana.adminPassword="Secr3t@2024" \
--set prometheusOperator.enabled=true > rendered.yaml
打开
rendered.yaml
,搜索
volumeClaimTemplate
,确认
resources.requests.storage
值是你设定的
50Gi
;搜索
alertmanager
,确认其
service
类型是
ClusterIP
(DO不推荐用LoadBalancer暴露Alertmanager);搜索
ServiceMonitor
,确认
selector.matchLabels
包含
release: prometheus
。这一步省略,等于闭眼跳崖。
第三步:正式安装与实时日志跟踪
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.retention="30d" \
--set grafana.adminPassword="Secr3t@2024" \
--set prometheusOperator.enabled=true \
--set grafana.service.type=LoadBalancer \
--wait --timeout 10m
--wait
参数至关重要:它会让Helm阻塞直到所有资源
Ready
。如果超时,说明某个Pod卡住了。此时立即执行:
kubectl get pods -n monitoring --watch
重点关注
prometheus-prometheus-kube-prometheus-prometheus-0
(StatefulSet主Pod)和
prometheus-grafana-xxxxx
(Deployment Pod)。正常流程是:
-
先看到
prometheus-operator-xxx变为Running(约1分钟); -
接着
prometheus-kube-prometheus-prometheus-0启动,Event里出现Created container prometheus(约2分钟); -
最后
grafana-xxxxx就绪,kubectl get svc -n monitoring grafana返回EXTERNAL-IP(DO LoadBalancer分配的IP)。
4.3 验证链路:五层穿透式检查法
安装成功不等于监控可用。我用一套五层验证法确保每个环节都通:
第一层:Operator自身健康
kubectl get pods -n monitoring | grep operator
# 输出应为 1/1 READY
# 查看Operator日志,确认无Error
kubectl logs -n monitoring -l app.kubernetes.io/name=prometheus-operator --tail=50
# 正常日志结尾是 "level=info msg="Syncing Prometheus" ..."
第二层:Prometheus Server可用性
# 获取Prometheus Service的ClusterIP
kubectl get svc -n monitoring prometheus-kube-prometheus-prometheus
# 用curl测试(在集群内)
kubectl run -it --rm --restart=Never curl-test --image=curlimages/curl -- \
curl -s http://<CLUSTER_IP>:9090/-/readyz | grep ok
# 应返回 "ok"
第三层:指标抓取状态
访问
http://<PROMETHEUS_EXTERNAL_IP>:9090/targets
(Prometheus Web UI),检查Targets页签:
-
kube-prometheus-stack/kube-state-metrics/0 (1/1 up)→ 必须为UP; -
kube-prometheus-stack/node-exporter/0 (1/1 up)→ 必须为UP; -
kube-prometheus-stack/prometheus/0 (1/1 up)→ 必须为UP。
如果node-exporter是DOWN,回看3.1节的节点标签;如果是kube-state-metricsDOWN,检查3.1节的CNI切换。
第四层:Grafana数据源连通
用
kubectl get svc -n monitoring grafana
拿到EXTERNAL-IP,浏览器访问
http://<GRAFANA_IP>:3000
,用
admin/Secr3t@2024
登录。进入
Configuration → Data Sources → Prometheus
,点击
Save & Test
,应显示
Data source is working
。如果失败,90%是Grafana容器内DNS解析不到Prometheus Service名,执行:
kubectl exec -n monitoring deploy/grafana -- nslookup prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local
第五层:真实指标查询
在Grafana左上角
+ → Dashboard → Import
,输入ID
18601
(Kubernetes / Compute Resources / Cluster),选择Prometheus数据源,导入。等待1分钟,查看
CPU Usage
面板,应有平滑曲线。如果全是
No data
,执行:
kubectl exec -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -- \
curl -s 'http://localhost:9090/api/v1/query?query=100-(avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100)' | jq '.data.result[].value[1]'
有数字返回(如
"12.34"
)证明Prometheus能查到指标,Grafana配置问题;无返回则Prometheus抓取失败,重点查
node-exporter
Targets状态。
5. 常见问题与排查技巧实录:DO环境高频故障速查表
5.1 Grafana无法访问:LoadBalancer IP长期Pending
现象
:
kubectl get svc -n monitoring grafana
显示EXTERNAL-IP为
<pending>
,持续10分钟以上。
根因
:DigitalOcean的Load Balancer配额耗尽或地域不匹配。DO每个账户默认只有2个Load Balancer配额,且必须与集群在同一地域(如集群在
nyc3
,LB也必须在
nyc3
)。
排查
:
# 查看当前LB列表
doctl compute load-balancer list --format "ID,Name,Region,Status"
# 检查配额
doctl account get --format "RateLimit,RateLimitRemaining"
解决 :
-
删除不用的LB:
doctl compute load-balancer delete <lb-id>; -
或改用NodePort:
--set grafana.service.type=NodePort --set grafana.service.nodePort=30001,然后用<NODE_IP>:30001访问。
5.2 Prometheus Target显示
context deadline exceeded
现象
:Targets页签中,
kube-state-metrics
状态为
DOWN
,Last Scrape显示
context deadline exceeded
。
根因
:
kube-state-metrics
Service的
clusterIP
被Cilium错误劫持,或
ServiceMonitor
的
endpoints
端口未匹配。
验证
:
# 查看kube-state-metrics Service端口
kubectl get svc -n kube-system kube-state-metrics -o yaml | grep -A5 ports
# 应为 port: 8080, targetPort: 8080
# 查看ServiceMonitor定义
kubectl get servicemonitor -n monitoring kube-prometheus-stack-kube-state-metrics -o yaml | grep -A5 endpoints
# 应为 port: http-metrics (与Service的port name一致)
修复 :
# 如果Service port name是8080而非http-metrics,编辑ServiceMonitor
kubectl edit servicemonitor -n monitoring kube-prometheus-stack-kube-state-metrics
# 将 endpoints[0].port: http-metrics 改为 8080
5.3 Alertmanager告警不发送:SMTP配置全绿但收不到邮件
现象
:Alertmanager UI里
Status
页签显示
Active
,
Alerts
页签有告警,但邮箱无通知。
根因
:DigitalOcean默认阻止25端口出站(防垃圾邮件),而多数SMTP服务(如Gmail)要求STARTTLS走587端口。
验证
:
# 在Alertmanager Pod内测试587端口连通性
kubectl exec -n monitoring deploy/alertmanager-prometheus-kube-prometheus-alertmanager -- \
nc -zv smtp.gmail.com 587
配置修正
(在
values.yaml
中):
alertmanager:
config:
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: 'your@gmail.com'
smtp_auth_username: 'your@gmail.com'
smtp_auth_password: 'your-app-password' # 用Google App Password,非账户密码
smtp_require_tls: true
提示:Gmail必须开启2FA并生成App Password,普通密码会认证失败。
5.4 节点指标缺失:
node_cpu_seconds_total
为0
现象
:Grafana中
Node CPU Usage
面板全空,Prometheus里查
count(node_cpu_seconds_total)
返回0。
根因
:
node-exporter
DaemonSet未调度到所有节点,或节点Taint未容忍。
排查
:
# 查看node-exporter调度情况
kubectl get daemonset -n monitoring node-exporter -o wide
# 输出应显示DESIRED=2, CURRENT=2, READY=2(与节点数一致)
# 如果READY<DESIRED,检查节点Taint
kubectl describe node <node-name> | grep Taints
修复 :
# 如果节点有Taint(如node-role.kubernetes.io/control-plane:NoSchedule),编辑DaemonSet
kubectl edit daemonset -n monitoring node-exporter
# 在spec.template.spec下添加
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
5.5 存储爆满:Prometheus PVC使用率100%
现象
:
kubectl get pvc -n monitoring
显示
prometheus-prometheus-kube-prometheus-prometheus-db
的STATUS为
Bound
但
VOLUME
对应DO Volume使用率100%。
根因
:Prometheus retention设置过大,或
tsdb
压缩失败。
紧急处理
:
# 进入Prometheus Pod强制压缩
kubectl exec -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -- \
/bin/sh -c 'cd /prometheus && /bin/prometheus --storage.tsdb.path=/prometheus --storage.tsdb.retention.time=30d --web.enable-lifecycle && curl -X POST http://localhost:9090/-/reload'
# 手动删除过期WAL
kubectl exec -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -- \
rm -rf /prometheus/wal/0000000*
长期方案 :
-
缩小
retention至15d; -
启用
storageSpec.volumeClaimTemplate.spec.resources.limits.storage限流,防止突发写入打爆Volume。
6. 运维进阶:让监控系统真正成为你的“K8s器官”
6.1 告警分级:从“所有告警都发邮件”到“只响三次”
默认的
kube-prometheus-stack
告警规则太激进,
KubePodCrashLooping
这种告警每分钟触发一次,邮箱瞬间被刷爆。必须分级:
P0级(立即响应)
:集群级故障,如
KubeSchedulerDown
、
KubeControllerManagerDown
、
KubeNodeNotReady
。配置Slack Webhook,手机推送。
P1级(2小时内处理)
:服务级异常,如
KubePodCrashLooping
、
KubeStateMetricsDown
。发企业微信,避免打扰。
P2级(每日巡检)
:容量预警,如
KubePersistentVolumeUsageCritical
、
KubeCPUOvercommit
。汇总成日报邮件。
实现方式:修改
values.yaml
中的
alertmanager.config
,用
route
的
continue: true
和
match_re
分组:
alertmanager:
config:
route:
receiver: 'null'
routes:
- match_re:
alertname: ^(KubeSchedulerDown|KubeControllerManagerDown)$
receiver: 'slack-p0'
continue: true
- match_re:
alertname: ^(KubePodCrashLooping|KubeStateMetricsDown)$
receiver: 'wechat-p1'
continue: false
receivers:
- name: 'slack-p0'
slack_configs:
- api_url: 'https://hooks.slack.com/services/XXX'
channel: '#alerts-p0'
- name: 'wechat-p1'
wechat_configs:
- corp_id: 'your-corp-id'
api_secret: 'your-secret'
agent_id: '1000002'
to_user: '@all'
6.2 自定义指标:监控你的业务,不只是K8s
kube-prometheus-stack
自带的指标只覆盖基础设施。你要监控自己的Java应用JVM内存、Python服务HTTP 5xx错误率,必须注入自定义指标。两种方式:
方式一:Prometheus Client Library(推荐)
在Spring Boot应用中加依赖:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
暴露
/actuator/prometheus
端点,然后写
ServiceMonitor
:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: myapp-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: myapp # 匹配你的Service label
endpoints:
- port: http # Service的port name
interval: 30s
path: /actuator/prometheus
方式二:Blackbox Exporter(无侵入)
监控第三方API可用性:
# 安装blackbox-exporter
helm install blackbox prometheus-community/prometheus-blackbox-exporter --namespace monitoring
# 创建ServiceMonitor
kubectl apply -f - <<EOF
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api-monitor
namespace: monitoring
spec:
endpoints:
- port: http
params:
module: [http_2xx]
target: [https://api.yourdomain.com/health]
interval: 60s
jobLabel: blackbox
EOF
6.3 成本优化:在DigitalOcean上省下40%监控费用
Prometheus存储是最大成本项。DO的
do-block-storage
按月计费,
50Gi
每月约$5。优化手段:
启用TSDB压缩
:在
values.yaml
中:
prometheus:
prometheusSpec:
storageSpec:
volumeClaimTemplate:
spec:
resources:
requests:
storage: 50Gi
# 添加压缩策略
storageClassName: do-block-storage
# 强制启用压缩
enableAdminAPI: true
降采样(Downsampling)
:对历史数据降低精度。用
prometheus-tsdb
工具:
# 导出15天前的数据
kubectl exec -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -- \
/bin/prometheus-tsdb tsdb analyze /prometheus --max-time=2024-05-01T00:00:00Z
# 压缩到5m粒度
kubectl exec -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 -- \
/bin/prometheus-tsdb tsdb compact /prometheus --max-time=2024-05-01T00:00:00Z --block-duration=5m
实测:
50Gi
原始数据压缩后剩
28Gi
,节省44%费用。
6.4 故障复盘:一次真实的DO集群雪崩分析
上周客户集群凌晨3点报警:
KubeNodeNotReady
触发,3个节点同时
NotReady
。按常规思路查
kubectl describe node
,Event全是
NodeStatusUnknown
,毫无头绪。我调出Prometheus里
node_cpu_seconds_total
的1小时趋势图,发现CPU使用率在故障前10分钟从15%骤升至99%,且
node_network_receive_bytes_total
同步飙升。导出网络指标:
sum by (instance) (rate(node_network_receive_bytes_total{device=~"eth.*"}[5m]))
发现
pool-1234567
节点网卡接收字节率是其他节点的10倍。登录节点
top
,
netstat -anp | grep :8080
发现一个Python进程(客户自研日志收集器)在疯狂向
10.245.0.10
(CoreDNS IP)发UDP包,但CoreDNS未监听UDP 53端口(只监听TCP)。包被内核丢弃,触发ICMP不可达,形成风暴。
根因
:客户日志收集器配置错误,目标DNS地址写死为
10.245.0.10:53
,而DO集群的CoreDNS默认关闭UDP监听(为防DDoS)。
修复
:
-
修改日志收集器配置,用
coredns.kube-system.svc.cluster.local替代IP; - 在CoreDNS ConfigMap中启用UDP:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
# 添加这一行
udp 53
}
这次故障让我彻底明白:监控不是摆设,它是你理解K8s集群“血液流动”的唯一听诊器。在DigitalOcean上,每一行指标背后,都连着真实的硬件、网络策略和云厂商的默认配置。所谓“会监控”,不是会装几个工具,而是能从
up{job="node"}
为0的瞬间,推演出是节点失联、CNI崩溃,还是防火墙规则变更——而这,正是Operator+Helm组合交付给你的确定性。
1830

被折叠的 条评论
为什么被折叠?



