Author SHA1 Message Date
panxiao81 f00b5e3fc2 排除 OCI HelmRepository 正常缺失 Ready 条件的误报 2026-09-25 19:39:04 +00:00
panxiao81 9a800f55fc 补齐证书、秘密同步、GitOps 与数据服务监控
yaml / yaml (pull_request) Successful in 3m20s
2026-09-25 19:35:38 +00:00
panxiao81 18ded1e4a8 Merge 原子部署解耦后的 dynamic runner 镜像
yaml / yaml (push) Successful in 4m32s
2026-09-25 19:12:07 +00:00
panxiao81 ca0862fe5a fix: 原子部署解耦后的 controller 与 runner
yaml / yaml (pull_request) Failing after 10m54s
2026-09-25 19:11:39 +00:00
panxiao81 a729f01546 Merge 部署修复后的 dynamic runner placement v2
yaml / yaml (push) Successful in 17s
2026-09-25 18:54:41 +00:00
panxiao81 bbcd5d6aa5 fix: 部署合法 consumer 名称的 placement v2
yaml / yaml (pull_request) Successful in 20s
2026-09-25 18:53:23 +00:00
panxiao81 c0c4ff521b Merge pull request '部署 dynamic runner placement v2' (#154) from deploy/workload-placement-v2 into main
yaml / yaml (push) Successful in 31s
Reviewed-on: #154
2026-09-25 18:37:40 +00:00
panxiao81 8bc039b40f Merge pull request #155: 授予 Backstage Kubernetes 只读观察权限
yaml / yaml (push) Successful in 27s
2026-09-25 18:33:32 +00:00
panxiao81 349aa77fb0 ops: 暂停 placement v2 自动 rollout
yaml / yaml (pull_request) Successful in 50s
2026-09-25 18:30:55 +00:00
panxiao81 cae6acbfb0 feat: 授予 Backstage Kubernetes 只读观察权限
yaml / yaml (pull_request) Successful in 43s
2026-09-25 18:30:42 +00:00
panxiao81 4d80f8efd7 deploy: 切换 dynamic runner placement v2
yaml / yaml (pull_request) Successful in 42s
2026-09-25 18:11:05 +00:00
panxiao81 9009e3fa11 启用 Backstage 显式目录位置 (#153)
yaml / yaml (push) Successful in 49s
2026-09-25 18:07:37 +00:00
panxiao81 a252ee5602 fix: 启用 Backstage 显式目录位置
yaml / yaml (pull_request) Successful in 47s
2026-09-25 18:06:59 +00:00
panxiao81 dbf66590ac 修复告警 Source 链接并接入 Grafana Alertmanager 数据源 (#152)
yaml / yaml (push) Successful in 51s
Co-authored-by: panxiao81 <[email protected]>
2026-09-25 18:02:14 +00:00
panxiao81 e8e7bd4b20 优先使用 PrometheusRule 声明基础告警 (#151)
yaml / yaml (push) Successful in 51s
Co-authored-by: panxiao81 <[email protected]>
2026-09-25 17:53:07 +00:00
panxiao81 185e3edaba 修复 Backstage 首次启动 (#150)
yaml / yaml (push) Successful in 1m13s
2026-09-25 17:47:34 +00:00
panxiao81 072936ce03 fix: 修正 Backstage 数据库模式与健康探针
yaml / yaml (pull_request) Successful in 54s
2026-09-25 17:46:49 +00:00
panxiao81 39aeac25ee 补齐集群状态、主机与通知链路基础监控 (#149)
yaml / yaml (push) Successful in 1m10s
Co-authored-by: panxiao81 <[email protected]>
2026-09-25 17:45:56 +00:00
panxiao81 a43b7d3c26 修复 kubelet 超限与旧 Docker 采集目标 (#148)
yaml / yaml (push) Failing after 10m32s
Co-authored-by: panxiao81 <[email protected]>
2026-09-25 17:22:01 +00:00
panxiao81 c06c6f7857 启用 Alertmanager Telegram 频道告警 (#147)
yaml / yaml (push) Successful in 39s
Co-authored-by: panxiao81 <[email protected]>
2026-09-25 17:10:30 +00:00
panxiao81 6a27adc18d 部署 Backstage 门户第一版 (#146)
yaml / yaml (push) Successful in 51s
2026-09-25 17:08:01 +00:00
panxiao81 29b3bdeeb1 feat: 部署 Backstage 门户第一版
yaml / yaml (pull_request) Successful in 22s
2026-09-25 16:09:23 +00:00
panxiao81 7a62dde601 Merge pull request '为 Backstage 镜像仓库配置 SPIFFE 发布权限' (#145) from feat/zot-backstage-access into main
yaml / yaml (push) Successful in 25s
Reviewed-on: #145
2026-09-25 15:26:38 +00:00
panxiao81 521a49599a 为 Backstage 镜像仓库配置 SPIFFE 发布权限
yaml / yaml (pull_request) Successful in 30s
2026-09-25 15:23:56 +00:00
panxiao81 185a47e2bb 合并 zot 本地维护身份删除权限修正
yaml / yaml (push) Successful in 25s
2026-09-25 14:53:58 +00:00
panxiao81 8dabbdce68 修复 zot 本地维护身份在 CI 镜像仓库的删除权限
yaml / yaml (pull_request) Successful in 25s
2026-09-25 14:52:14 +00:00
panxiao81 d5b1bb9640 为 Gitea 添加 Hydra OIDC 登录入口
yaml / yaml (push) Successful in 25s
2026-09-25 13:56:23 +00:00
panxiao81 cfb2fddfa9 feat: 为 Gitea 添加 Hydra OIDC 登录入口
yaml / yaml (pull_request) Successful in 17s
2026-09-25 13:55:03 +00:00
40 changed files with 1698 additions and 39 deletions
+20
View File
@@ -0,0 +1,20 @@
# Backstage
Backstage 作为 homelab 的只读开发者门户运行。应用源码、插件、测试和镜像构建归
`panxiao81/backstage` 仓库管理;本目录只保存 Kubernetes/Flux 部署声明,并通过
OCI digest 固定镜像。
## 外部前置
- OpenBao `kv/k8s/backstage` 必须包含以下与容器环境变量同名的字段:
`BACKEND_SECRET`、`AUTH_SESSION_SECRET`、`AUTH_OIDC_CLIENT_ID`、
`AUTH_OIDC_CLIENT_SECRET`、`POSTGRES_PASSWORD`、`GITEA_TOKEN`。
- PostgreSQL 需要在共享集群中预先创建由 `backstage` 角色拥有的 `backstage`
数据库;密码必须与 OpenBao 中的 `POSTGRES_PASSWORD` 一致。
- Authelia OIDC 客户端回调地址为
`https://backstage.ad.ddupan.top/api/auth/oidc/handler/frame`。
- AD DNS 需要将 `backstage.ad.ddupan.top` 指向 Envoy Gateway
`192.168.10.127`。
Flux 等待 ExternalSecret 和 Deployment 就绪;任何前置缺失都会使该
Kustomization 保持 NotReady,而不会回退到明文 Secret。
+85
View File
@@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
namespace: backstage
labels:
app.kubernetes.io/name: backstage
backstage.io/kubernetes-id: homelab-backstage
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: backstage
template:
metadata:
labels:
app.kubernetes.io/name: backstage
backstage.io/kubernetes-id: homelab-backstage
spec:
serviceAccountName: backstage
securityContext:
fsGroup: 1000
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: backstage
image: zot.ad.ddupan.top/panxiao81/backstage@sha256:e5a12550726f19a680bc7c40e2cc07cc624318f9279ee121814d293a006ef210
imagePullPolicy: IfNotPresent
env:
- name: BACKSTAGE_BASE_URL
value: https://backstage.ad.ddupan.top
- name: POSTGRES_HOST
value: shared-postgresql-rw.shared-db.svc.cluster.local
- name: POSTGRES_PORT
value: "5432"
- name: POSTGRES_USER
value: backstage
- name: POSTGRES_DATABASE
value: backstage
- name: GITEA_HOST
value: git.ddupan.top
envFrom:
- secretRef:
name: backstage
ports:
- containerPort: 7007
name: http
protocol: TCP
readinessProbe:
httpGet:
path: /.backstage/health/v1/readiness
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
livenessProbe:
httpGet:
path: /.backstage/health/v1/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 3
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp
volumes:
- emptyDir: {}
name: tmp
+16
View File
@@ -0,0 +1,16 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: backstage
namespace: backstage
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: openbao
target:
creationPolicy: Owner
name: backstage
dataFrom:
- extract:
key: k8s/backstage
+20
View File
@@ -0,0 +1,20 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backstage
namespace: backstage
spec:
parentRefs:
- name: eg
namespace: envoy-gateway-system
sectionName: https
hostnames:
- backstage.ad.ddupan.top
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: backstage
port: 7007
+11
View File
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- serviceaccount.yaml
- rbac.yaml
- external-secret.yaml
- deployment.yaml
- service.yaml
- networkpolicy.yaml
- httproute.yaml
+7
View File
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: backstage
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.36
+24
View File
@@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backstage-ingress
namespace: backstage
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: backstage
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: envoy-gateway-system
ports:
- port: 7007
protocol: TCP
- from:
- ipBlock:
cidr: 192.168.10.127/32
ports:
- port: 7007
protocol: TCP
+51
View File
@@ -0,0 +1,51 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: backstage-read-only
rules:
- apiGroups: [""]
resources:
- configmaps
- limitranges
- pods
- pods/log
- resourcequotas
- services
verbs: [get, list, watch]
- apiGroups: [apps]
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs: [get, list, watch]
- apiGroups: [autoscaling]
resources:
- horizontalpodautoscalers
verbs: [get, list, watch]
- apiGroups: [batch]
resources:
- cronjobs
- jobs
verbs: [get, list, watch]
- apiGroups: [networking.k8s.io]
resources:
- ingresses
verbs: [get, list, watch]
- apiGroups: [metrics.k8s.io]
resources:
- pods
verbs: [get, list]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: backstage-read-only
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: backstage-read-only
subjects:
- kind: ServiceAccount
name: backstage
namespace: backstage
+15
View File
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: backstage
namespace: backstage
labels:
backstage.io/kubernetes-id: homelab-backstage
spec:
selector:
app.kubernetes.io/name: backstage
ports:
- name: http
port: 7007
protocol: TCP
targetPort: http
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: backstage
namespace: backstage
automountServiceAccountToken: true
+12
View File
@@ -44,3 +44,15 @@ API、OIDC、Git/Flux 和 runner 均已验证。第二跳按明确决定跳过
结构,或者 release notes 指出相关 breaking migration 时,才恢复停机一致备份、分阶段
suspend、详细日志审计和扩展验收。出现启动失败或 migration error 时也立即升级为完整
故障流程。
## Hydra 人类登录 PoC
新增 `hydra` OIDC 登录源,旧 `authelia` 入口保留。Hydra 通过通用 OIDC Login/Consent
适配器转到现有 Authelia 完成人类认证;不是 Gitea 直接验证 LDAP 或 SPIFFE。
入口为 `https://git.ddupan.top/user/oauth2/hydra`,需 LAN/Tailscale 可达 Hydra 内网域名。
新 client secret 通过 `ExternalSecret/gitea-hydra-oidc` 从 OpenBao 投射。沿用
preferred_username、已验证邮箱与 groups;当前仍映射 gitea-admins,不在本轮切换组模型。
先部署并验证 Hydra discovery 后再接入本配置,避免 Gitea init 因上游不可达而失败。
实际登录验收与部署状态见 wiki;依赖和回退见 [Hydra README](../hydra/README.md)。
+7
View File
@@ -116,6 +116,13 @@ gitea:
scopes: openid profile email groups
groupClaimName: groups
adminGroup: gitea-admins
- name: hydra
provider: openidConnect
existingSecret: gitea-hydra-oidc
autoDiscoverUrl: https://hydra.ad.ddupan.top/.well-known/openid-configuration
scopes: openid profile email groups
groupClaimName: groups
adminGroup: gitea-admins
persistence:
size: 20Gi
+22
View File
@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: gitea-hydra-oidc
namespace: gitea
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: openbao
target:
name: gitea-hydra-oidc
creationPolicy: Owner
template:
data:
key: gitea
secret: "{{ .client_secret }}"
data:
- secretKey: client_secret
remoteRef:
key: k8s/hydra
property: gitea_client_secret
+1
View File
@@ -16,3 +16,4 @@ resources:
- helmrepository.yaml
- helmrelease.yaml
- httproute.yaml
- hydra-external-secret.yaml
+29 -5
View File
@@ -70,11 +70,11 @@ configFiles:
},
"accessControl": {
"repositories": {
"panxiao81/gitea-dynamic-runner-controller": {
"panxiao81/backstage": {
"policies": [
{
"users": [
"spiffe://ddupan.top/ci/panxiao81/gitea-dynamic-runner/publish-images",
"spiffe://ddupan.top/ci/panxiao81/backstage/image",
"spiffe://ddupan.top/dev/panxiao81"
],
"actions": [
@@ -88,18 +88,42 @@ configFiles:
"read"
]
},
"panxiao81/gitea-dynamic-runner-runner": {
"panxiao81/gitea-dynamic-runner-controller": {
"policies": [
{
"users": [
"spiffe://ddupan.top/ci/panxiao81/gitea-dynamic-runner/publish-images",
"spiffe://ddupan.top/dev/panxiao81"
"spiffe://ddupan.top/ci/panxiao81/gitea-dynamic-runner/publish-images"
],
"actions": [
"read",
"create",
"update"
]
},
{
"users": ["spiffe://ddupan.top/dev/panxiao81"],
"actions": ["read", "create", "update", "delete"]
}
],
"defaultPolicy": [
"read"
]
},
"panxiao81/gitea-dynamic-runner-runner": {
"policies": [
{
"users": [
"spiffe://ddupan.top/ci/panxiao81/gitea-dynamic-runner/publish-images"
],
"actions": [
"read",
"create",
"update"
]
},
{
"users": ["spiffe://ddupan.top/dev/panxiao81"],
"actions": ["read", "create", "update", "delete"]
}
],
"defaultPolicy": [
+22
View File
@@ -0,0 +1,22 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: backstage
namespace: flux-system
spec:
dependsOn:
- name: envoy-gateway
- name: external-secrets
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: backstage
namespace: backstage
interval: 10m
path: ./apps/backstage
prune: true
sourceRef:
kind: GitRepository
name: flux-system
timeout: 5m
wait: true
+1
View File
@@ -7,6 +7,7 @@ resources:
- apps/envoy-gateway.yaml
- apps/external-secrets.yaml
- apps/gitea.yaml
- apps/backstage.yaml
- apps/http-echo.yaml
- apps/openebs.yaml
- apps/nats.yaml
+8 -6
View File
@@ -1,10 +1,10 @@
# Gitea dynamic runner
本目录部署单副本 Go controller,在同一进程运行 RunnerService scheduler、原生
Kubernetes Pod worker、OpenSandbox VM worker 和 SPIFFE mTLS facade:
Kubernetes worker、OpenSandbox worker 和 SPIFFE mTLS facade:
```text
Gitea RunnerService -> scheduler -> JetStream ci.runner.pod
Gitea RunnerService -> scheduler -> JetStream ci.runner.container.kubernetes
|
v
homelab Kubernetes Pod
@@ -15,7 +15,8 @@ Gitea RunnerService -> scheduler -> JetStream ci.runner.pod
Gitea
```
Pod backend 不经过 OpenSandbox。VM backend 后续启用时才访问 VyOS 暴露的
`container+kubernetes` placement 不经过 OpenSandbox;`vm+opensandbox` placement
访问 VyOS 暴露的
OpenSandbox Lifecycle API;本目录不修改 sandbox 平台侧 ESO、Bao Terraform 或
OpenSandbox chart 所有权边界。
@@ -82,9 +83,9 @@ kubectl -n dynamic-runner rollout status deploy/dynamic-runner-controller --time
kubectl -n dynamic-runner logs deploy/dynamic-runner-controller -f
```
确认 scheduler 只领取一条 `[self-hosted,pod]` task,然后验证:
确认 scheduler 只领取一条 `[self-hosted,container,kubernetes]` task,然后验证:
1. assignment message 进入并离开 durable `pod` consumer;
1. assignment message 进入并离开 durable `container.kubernetes` consumer;
2. `gitea-task-<task-id>` Pod 创建,取得实际 Pod UID;
3. 同名 `ClusterStaticEntry` 的 parent ID 包含该 UID,SPIFFE ID 使用 repository/job key;
4. 官方 runner v3.5.0 经 facade claim 精确 task,Gitea 实时收到日志和终态;
@@ -96,7 +97,8 @@ ClusterStaticEntry 全部消失;完整自动清理通过前不得提高 `POD_C
`VM_CAPACITY`。
VM backend 已通过 `vm-dev` canary 完成 Docker、kind、SPIFFE 和完整生命周期测试。
生产调度标签为 `[self-hosted, vm]`,初始保持 `VM_CAPACITY=1`;扩容前先观察实际任务的
生产规范标签为 `[self-hosted, vm, opensandbox]`,旧 `[self-hosted, vm]` 仍严格映射到
同一 placement。初始保持 `VM_CAPACITY=1`;扩容前先观察实际任务的
资源水位、等待时间以及 OpenSandbox 是否存在 terminal sandbox 残留。
## 回滚
+3 -3
View File
@@ -38,12 +38,12 @@ spec:
mountPath: /trust
containers:
- name: controller
image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:7374a08a238ca1c76a9aee33c57520ae0edaa9b5b443708487d5b3a69a61da4e
image: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-controller@sha256:15735667e8990974a30d9a5e6a1030d63f791ed6d80fa2b0dc9e39959ffcf334
imagePullPolicy: IfNotPresent
args: [controller]
env:
- name: COMPONENTS
value: scheduler,pod-worker,vm-worker
value: scheduler,kubernetes-worker,opensandbox-worker
- name: GITEA_INSTANCE_URL
value: https://git.ddupan.top
- name: GITEA_RUNNER_UUID_FILE
@@ -73,7 +73,7 @@ spec:
fieldRef:
fieldPath: metadata.namespace
- name: POD_EXECUTOR_IMAGE
value: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-runner@sha256:325d75a208b1a1c6f3b4d4705e47bbc58b34733edcd12f689c60769ab6772a59
value: zot.ad.ddupan.top/panxiao81/gitea-dynamic-runner-runner@sha256:83e96c3959af663a75a7229cb04cbbb97a642d4ef3704ac5cdceb1d502a72ed3
- name: POD_SERVICE_ACCOUNT
value: gitea-dynamic-runner
- name: POD_EXECUTOR_UID
+4 -3
View File
@@ -35,10 +35,11 @@ ci_worker_password
## CI stream 约定
controller 首次启动时幂等创建 `CI_RUNNER` stream:`ci.runner.>`、
controller 使用 `CI_RUNNER` stream:`ci.runner.>`、
`WorkQueuePolicy`、file storage、24h/10000 条/256 MiB 上限。每类 runner 使用独立
subject 和 durable pull consumer;`ci.runner.<backend>.binding` 传递 runner 实际
领取任务后的身份绑定。同类型的多个 worker 共享 durable consumer。ACK 后消息立即
placement subject 和 durable pull consumer;assignment v2 subject 为
`ci.runner.<workload-class>.<driver>`,当前为 `ci.runner.container.kubernetes` 与
`ci.runner.vm.opensandbox`。同 placement 的多个 worker 共享 durable consumer。ACK 后消息立即
删除,不保存 CI 历史。
## 验证
@@ -32,6 +32,14 @@ datasources:
isDefault: true
jsonData:
prometheusType: Prometheus
- name: Alertmanager
uid: alertmanager
type: alertmanager
access: proxy
url: http://vmalertmanager-main.monitoring.svc:9093
jsonData:
implementation: prometheus
handleGrafanaManagedAlerts: false
- name: VictoriaLogs
type: victoriametrics-logs-datasource
access: proxy
@@ -0,0 +1,18 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: alertmanager-telegram
namespace: monitoring
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: openbao
target:
name: alertmanager-telegram
creationPolicy: Owner
data:
- secretKey: telegram_bot_token
remoteRef:
key: k8s/alertmanager
property: telegram_bot_token
@@ -0,0 +1,257 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kube-state-metrics
namespace: monitoring
spec:
interval: 30m
timeout: 5m
dependsOn:
- name: vm-operator
- name: prometheus-operator-crds
chart:
spec:
chart: kube-state-metrics
version: 8.5.0
sourceRef:
kind: HelmRepository
name: prometheus-community
namespace: monitoring
interval: 1h
driftDetection:
mode: enabled
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
fullnameOverride: kube-state-metrics
collectors:
- cronjobs
- daemonsets
- deployments
- jobs
- namespaces
- nodes
- persistentvolumeclaims
- persistentvolumes
- pods
- statefulsets
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 384Mi
prometheus:
monitor:
enabled: true
jobLabel: app.kubernetes.io/name
http:
interval: 30s
honorLabels: true
metrics:
interval: 30s
honorLabels: true
selfMonitor:
enabled: true
rbac:
extraRules:
- apiGroups:
- kustomize.toolkit.fluxcd.io
resources:
- kustomizations
verbs:
- list
- watch
- apiGroups:
- helm.toolkit.fluxcd.io
resources:
- helmreleases
verbs:
- list
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- gitrepositories
- helmrepositories
- helmcharts
- ocirepositories
verbs:
- list
- watch
customResourceState:
enabled: true
config:
kind: CustomResourceStateMetrics
spec:
resources:
- groupVersionKind:
group: kustomize.toolkit.fluxcd.io
version: v1
kind: Kustomization
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
- groupVersionKind:
group: helm.toolkit.fluxcd.io
version: v2
kind: HelmRelease
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
- groupVersionKind:
group: source.toolkit.fluxcd.io
version: v1
kind: GitRepository
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
- groupVersionKind:
group: source.toolkit.fluxcd.io
version: v1
kind: HelmRepository
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
repository_type:
- spec
- type
- groupVersionKind:
group: source.toolkit.fluxcd.io
version: v1
kind: HelmChart
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
- groupVersionKind:
group: source.toolkit.fluxcd.io
version: v1
kind: OCIRepository
metricNamePrefix: gotk
metrics:
- name: resource_info
help: The current state of a GitOps Toolkit resource.
each:
type: Info
info:
labelsFromPath:
name:
- metadata
- name
labelsFromPath:
resource_namespace:
- metadata
- namespace
suspended:
- spec
- suspend
ready:
- status
- conditions
- '[type=Ready]'
- status
@@ -6,6 +6,7 @@ resources:
- vmagent.yaml
- vmalert.yaml
- vmalertmanager.yaml
- alertmanager-external-secret.yaml
- reload-rbac.yaml
- rules/vm-health.yaml
- rules/vmagent.yaml
@@ -16,3 +17,12 @@ resources:
- scrapes/kubelet.yaml
- exporters/node-exporter.yaml
- exporters/process-exporter.yaml
- exporters/kube-state-metrics-helmrelease.yaml
- rules/kubernetes-health.yaml
- rules/host-health.yaml
- rules/monitoring-delivery.yaml
- scrapes/platform-controllers.yaml
- rules/platform-controllers.yaml
- scrapes/cnpg.yaml
- scrapes/seaweedfs.yaml
- rules/data-services.yaml
@@ -0,0 +1,148 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: data-services
namespace: monitoring
spec:
groups:
- name: data-services
interval: 30s
rules:
- alert: DataServiceMetricsUnavailable
expr: up{job="cnpg"} == 0 or absent(up{job="cnpg"})
for: 5m
labels:
severity: critical
job: cnpg
annotations:
summary: 数据服务 {{ $labels.job }} 指标不可用
description: 检查监控对象、Pod 与 exporter;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: DataServiceMetricsUnavailable
expr: up{job="seaweedfs-master"} == 0 or absent(up{job="seaweedfs-master"})
for: 5m
labels:
severity: critical
job: seaweedfs-master
annotations:
summary: 数据服务 {{ $labels.job }} 指标不可用
description: 检查监控对象、Pod 与 exporter;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: DataServiceMetricsUnavailable
expr: up{job="seaweedfs-volume"} == 0 or absent(up{job="seaweedfs-volume"})
for: 5m
labels:
severity: critical
job: seaweedfs-volume
annotations:
summary: 数据服务 {{ $labels.job }} 指标不可用
description: 检查监控对象、Pod 与 exporter;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: DataServiceMetricsUnavailable
expr: up{job="seaweedfs-filer"} == 0 or absent(up{job="seaweedfs-filer"})
for: 5m
labels:
severity: critical
job: seaweedfs-filer
annotations:
summary: 数据服务 {{ $labels.job }} 指标不可用
description: 检查监控对象、Pod 与 exporter;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: CnpgPostgresDown
expr: cnpg_collector_up{job="cnpg"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: CNPG {{ $labels.pod }} PostgreSQL 不可用
description: 检查数据库 Pod 状态、实例日志和存储;exporter up 不代表数据库可用。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: CnpgMetricsCollectionFailed
expr: cnpg_collector_last_collection_error{job="cnpg"} == 1
for: 5m
labels:
severity: warning
annotations:
summary: CNPG {{ $labels.pod }} SQL 指标采集失败
description: 检查内置 exporter 日志、数据库连接与查询兼容性。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: CnpgConnectionsHigh
expr: sum by (job,namespace,pod) (cnpg_backends_total{job="cnpg"}) / on(job,namespace,pod)
max by(job,namespace,pod) (cnpg_pg_settings_setting{job="cnpg",name="max_connections"})
> 0.8
for: 10m
labels:
severity: warning
annotations:
summary: CNPG {{ $labels.pod }} 连接使用率超过 80%
description: 检查连接池、空闲连接和连接泄漏,不直接提高 max_connections。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: CnpgLongTransaction
expr: cnpg_backends_max_tx_duration_seconds{job="cnpg",state!="idle"} > 300
for: 5m
labels:
severity: warning
annotations:
summary: CNPG {{ $labels.pod }} 存在长事务
description: 事务持续超过五分钟并维持五分钟,检查阻塞与 idle in transaction;先确认业务再处理。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: NatsJetStreamStorageHigh
expr: nats_varz_jetstream_stats_storage{job="nats/nats"} / nats_varz_jetstream_config_max_storage{job="nats/nats"}
> 0.8
for: 10m
labels:
severity: warning
annotations:
summary: NATS JetStream 文件容量超过 80%
description: 检查服务端配额与消息保留策略;该指标不代表单个 Account 或 stream 配额。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: NatsJetStreamMemoryHigh
expr: nats_varz_jetstream_stats_memory{job="nats/nats"} / nats_varz_jetstream_config_max_memory{job="nats/nats"}
> 0.8
for: 10m
labels:
severity: warning
annotations:
summary: NATS JetStream 内存容量超过 80%
description: 检查 memory store 消息保留与服务端内存配额。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: NatsSlowConsumers
expr: increase(nats_varz_slow_consumers{job="nats/nats"}[10m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: NATS 检测到慢消费者
description: 检查消费者处理速率与网络;此规则不能代替 JetStream consumer 积压监控。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: SeaweedVolumeDiskLow
expr: SeaweedFS_volumeServer_resource{job="seaweedfs-volume",type="avail"} /
ignoring(type) SeaweedFS_volumeServer_resource{job="seaweedfs-volume",type="all"}
< 0.1
for: 10m
labels:
severity: warning
annotations:
summary: SeaweedFS {{ $labels.name }} 可用空间不足 10%
description: 检查 volume 文件系统容量、保留策略与底层 ZFS;不要直接删除卷文件。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: SeaweedVolumeDiskReadOnly
expr: SeaweedFS_volumeServer_read_only_volumes{job="seaweedfs-volume",type="isDiskSpaceLow"}
> 0
for: 5m
labels:
severity: critical
annotations:
summary: SeaweedFS 因磁盘空间不足限制卷写入
description: 检查磁盘容量和 volume 日志;主动只读或满卷切换不按此故障处理。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- alert: SeaweedVolumeWriteFailures
expr: increase(SeaweedFS_volumeServer_file_write_failures{job="seaweedfs-volume"}[5m])
> 0
for: 2m
labels:
severity: warning
annotations:
summary: SeaweedFS 卷写入失败
description: 检查 volume 日志、磁盘状态及上游请求;不代表已经验证 S3 端到端可用。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
@@ -0,0 +1,66 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: host-health
namespace: monitoring
labels:
app.kubernetes.io/part-of: victoria-metrics
spec:
groups:
- name: host-health
interval: 30s
rules:
- alert: HostMemoryLow
expr: (node_memory_MemAvailable_bytes{job="node-exporter"} / node_memory_MemTotal_bytes{job="node-exporter"})
< 0.10
for: 10m
labels:
severity: warning
annotations:
summary: 主机 {{ $labels.instance }} 可用内存不足 10%
description: 检查主机内存、Swap、进程 PSS;仅使用 node-exporter job,避免重复采集统计。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: HostFilesystemSpaceLow
expr: (node_filesystem_avail_bytes{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
/ node_filesystem_size_bytes{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
< 0.10) and on(instance,device,mountpoint) (node_filesystem_readonly{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
== 0)
for: 15m
labels:
severity: warning
annotations:
summary: 主机 {{ $labels.instance }} {{ $labels.mountpoint }} 可用空间不足 10%
description: 检查文件系统和 ZFS dataset 容量,清理前确认数据归属。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: HostFilesystemInodesLow
expr: (node_filesystem_files_free{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
/ node_filesystem_files{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
< 0.10) and on(instance,device,mountpoint) (node_filesystem_files{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
> 0) and on(instance,device,mountpoint) (node_filesystem_readonly{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
== 0)
for: 15m
labels:
severity: warning
annotations:
summary: 主机 {{ $labels.instance }} {{ $labels.mountpoint }} inode 不足 10%
description: 检查小文件数量,确认 filesystem 是否耗尽 inode。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: HostFilesystemReadOnly
expr: node_filesystem_readonly{job="node-exporter",fstype!~"tmpfs|devtmpfs|overlay|squashfs|nsfs|fuse.*",mountpoint!~"/run(/.*)?|/var/lib/kubelet/.*|/var/lib/docker/.*"}
== 1
for: 5m
labels:
severity: critical
annotations:
summary: 主机 {{ $labels.instance }} {{ $labels.mountpoint }} 变为只读
description: 排查磁盘和文件系统错误;不要直接强制重新挂载。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: HostZpoolUnhealthy
expr: node_zfs_zpool_state{job="node-exporter",state!="online"} == 1
for: 5m
labels:
severity: critical
annotations:
summary: 主机 {{ $labels.instance }} ZFS 池 {{ $labels.zpool }} 状态 {{ $labels.state }}
description: 检查 zpool status、磁盘和冗余;零值状态不触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
@@ -0,0 +1,121 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: kubernetes-health
namespace: monitoring
labels:
app.kubernetes.io/part-of: victoria-metrics
spec:
groups:
- name: kubernetes-health
interval: 30s
rules:
- alert: KubeNodeNotReady
expr: max by (node) (kube_node_status_condition{job="kube-state-metrics",condition="Ready",status="true"})
== 0
for: 5m
labels:
severity: critical
annotations:
summary: 节点 {{ $labels.node }} 未就绪
description: 检查节点、kubelet 和网络;维护时按 node 精确静默。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubeNodePressure
expr: max by (node, condition) (kube_node_status_condition{job="kube-state-metrics",condition=~"MemoryPressure|DiskPressure|PIDPressure",status="true"})
== 1
for: 5m
labels:
severity: warning
annotations:
summary: 节点 {{ $labels.node }} 出现 {{ $labels.condition }}
description: 检查内存、磁盘/inode 或 PID 资源压力。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubePodCrashLooping
expr: max by (namespace,pod,container) (kube_pod_container_status_waiting_reason{job="kube-state-metrics",reason="CrashLoopBackOff"})
== 1
for: 10m
labels:
severity: warning
annotations:
summary: 容器 {{ $labels.namespace }}/{{ $labels.pod }}/{{ $labels.container }} 持续崩溃
description: 检查容器退出原因和日志;持续 10 分钟后通知,避免短暂重启噪声。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubePodFrequentRestarts
expr: sum by (namespace,pod,container) (increase(kube_pod_container_status_restarts_total{job="kube-state-metrics"}[15m]))
> 3
for: 5m
labels:
severity: warning
annotations:
summary: 容器 {{ $labels.namespace }}/{{ $labels.pod }}/{{ $labels.container }} 频繁重启
description: 15 分钟内重启超过 3 次,检查退出原因和资源限制。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubePodOOMKilled
expr: (max by (namespace,pod,container) (kube_pod_container_status_last_terminated_reason{job="kube-state-metrics",reason="OOMKilled"})
== 1) and on(namespace,pod,container) (sum by (namespace,pod,container) (increase(kube_pod_container_status_restarts_total{job="kube-state-metrics"}[10m]))
> 0)
for: 1m
labels:
severity: warning
annotations:
summary: 容器 {{ $labels.namespace }}/{{ $labels.pod }}/{{ $labels.container }} 发生 OOM 重启
description: 仅在近期有重启且最近终止原因为 OOMKilled 时触发,检查内存峰值和限制。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubePodPending
expr: max by (namespace,pod) (kube_pod_status_phase{job="kube-state-metrics",phase="Pending"}) == 1
for: 15m
labels:
severity: warning
annotations:
summary: Pod {{ $labels.namespace }}/{{ $labels.pod }} 长时间 Pending
description: 检查调度事件、资源、卷和镜像拉取。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubeDeploymentUnavailable
expr: (max by(namespace,deployment) (kube_deployment_spec_replicas{job="kube-state-metrics"}) - max by(namespace,deployment)
(kube_deployment_status_replicas_available{job="kube-state-metrics"})) > 0
for: 10m
labels:
severity: warning
annotations:
summary: Deployment {{ $labels.namespace }}/{{ $labels.deployment }} 副本不足
description: 可用副本持续 10 分钟低于声明值;缩容至零不会触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubeStatefulSetUnavailable
expr: (max by(namespace,statefulset) (kube_statefulset_replicas{job="kube-state-metrics"}) - max by(namespace,statefulset)
(kube_statefulset_status_replicas_ready{job="kube-state-metrics"})) > 0
for: 10m
labels:
severity: warning
annotations:
summary: StatefulSet {{ $labels.namespace }}/{{ $labels.statefulset }} 副本不足
description: 检查 Pod 就绪、存储和依赖;已知维护按工作负载精确静默。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubeDaemonSetUnavailable
expr: (max by(namespace,daemonset) (kube_daemonset_status_desired_number_scheduled{job="kube-state-metrics"})
- max by(namespace,daemonset) (kube_daemonset_status_number_ready{job="kube-state-metrics"})) > 0
for: 10m
labels:
severity: warning
annotations:
summary: DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} 副本不足
description: 检查节点和 Pod 就绪;不按整个 namespace 屏蔽。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubePVCPending
expr: max by(namespace,persistentvolumeclaim) (kube_persistentvolumeclaim_status_phase{job="kube-state-metrics",phase="Pending"})
== 1
for: 15m
labels:
severity: warning
annotations:
summary: PVC {{ $labels.namespace }}/{{ $labels.persistentvolumeclaim }} 长时间 Pending
description: 检查 StorageClass、调度拓扑、容量与 provisioner。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: KubeJobFailed
expr: max by(namespace,job_name) (kube_job_failed{job="kube-state-metrics",condition="true"}) == 1
for: 5m
labels:
severity: warning
annotations:
summary: Job {{ $labels.namespace }}/{{ $labels.job_name }} 已失败
description: 检查失败 Job 的 Pod 和任务日志;成功重试中的失败 Pod 计数不作为失败 Job。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
@@ -0,0 +1,58 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: monitoring-delivery
namespace: monitoring
labels:
app.kubernetes.io/part-of: victoria-metrics
spec:
groups:
- name: monitoring-delivery
interval: 30s
rules:
- alert: KubeStateMetricsUnavailable
expr: up{job="kube-state-metrics"} == 0 or absent(up{job="kube-state-metrics"})
for: 5m
labels:
severity: critical
annotations:
summary: kube-state-metrics 采集不可用
description: 检查 HelmRelease、ServiceMonitor 转换、targets 与 exporter;目标消失也会触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: NodeExporterUnavailable
expr: up{job="node-exporter"} == 0 or absent(up{job="node-exporter"})
for: 5m
labels:
severity: critical
annotations:
summary: node-exporter 采集不可用
description: 检查节点与 exporter,主机健康规则依赖此采集。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: NatsMetricsUnavailable
expr: up{job="nats/nats"} == 0 or absent(up{job="nats/nats"})
for: 5m
labels:
severity: warning
annotations:
summary: NATS 指标采集不可用
description: 依次检查 PodMonitor、转换后的 VMPodScrape、:7777 exporter 及 targets。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: AlertmanagerTelegramDeliveryFailed
expr: sum by(job,instance,integration) (increase(alertmanager_notifications_failed_total{job="vmalertmanager-main",integration="telegram"}[5m]))
> 0
for: 1m
labels:
severity: critical
annotations:
summary: Alertmanager 向 Telegram 发送失败
description: 检查网络、bot token 和频道权限。若 Telegram 完全不可达,本告警也无法经同一渠道送达;需在 Alertmanager/Grafana 排查,集群外心跳另行建设。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- alert: AlertmanagerConfigurationReloadFailed
expr: alertmanager_config_last_reload_successful{job="vmalertmanager-main"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: Alertmanager 配置加载失败
description: 检查 operator 和 Alertmanager 日志、配置格式及 Secret 引用。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
@@ -0,0 +1,161 @@
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: platform-controllers
namespace: monitoring
spec:
groups:
- name: platform-controllers
interval: 30s
rules:
- alert: PlatformControllerMetricsUnavailable
expr: up{job="cert-manager"} == 0 or absent(up{job="cert-manager"})
for: 5m
labels:
severity: warning
job: cert-manager
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="external-secrets"} == 0 or absent(up{job="external-secrets"})
for: 5m
labels:
severity: warning
job: external-secrets
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="external-secrets-cert-controller"} == 0 or absent(up{job="external-secrets-cert-controller"})
for: 5m
labels:
severity: warning
job: external-secrets-cert-controller
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="external-secrets-webhook"} == 0 or absent(up{job="external-secrets-webhook"})
for: 5m
labels:
severity: warning
job: external-secrets-webhook
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="helm-controller"} == 0 or absent(up{job="helm-controller"})
for: 5m
labels:
severity: warning
job: helm-controller
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="kustomize-controller"} == 0 or absent(up{job="kustomize-controller"})
for: 5m
labels:
severity: warning
job: kustomize-controller
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="source-controller"} == 0 or absent(up{job="source-controller"})
for: 5m
labels:
severity: warning
job: source-controller
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: PlatformControllerMetricsUnavailable
expr: up{job="notification-controller"} == 0 or absent(up{job="notification-controller"})
for: 5m
labels:
severity: warning
job: notification-controller
annotations:
summary: 控制器 {{ $labels.job }} 指标不可用
description: 检查对应 Pod、监控 CR 转换与 targets;目标消失同样触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: CertificateNotReady
expr: certmanager_certificate_ready_status{job="cert-manager",condition="True"}
== 0
for: 15m
labels:
severity: warning
annotations:
summary: 证书 {{ $labels.namespace }}/{{ $labels.name }} 未就绪
description: 检查 Certificate、CertificateRequest、Issuer、Order 与 Challenge;允许短暂签发过程。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: CertificateExpiringSoon
expr: (certmanager_certificate_expiration_timestamp_seconds{job="cert-manager"}
- time() < 7 * 86400) and (certmanager_certificate_expiration_timestamp_seconds{job="cert-manager"}
- time() >= 86400)
for: 15m
labels:
severity: warning
annotations:
summary: 证书 {{ $labels.namespace }}/{{ $labels.name }} 将在七天内到期
description: 检查自动续期链路及实际入口证书;一天内到期由 critical 规则接替。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: CertificateExpiryCritical
expr: certmanager_certificate_expiration_timestamp_seconds{job="cert-manager"}
- time() < 86400
for: 5m
labels:
severity: critical
annotations:
summary: 证书 {{ $labels.namespace }}/{{ $labels.name }} 即将到期或已过期
description: 不足一天或已经过期;立即检查续期与入口证书。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: ExternalSecretNotReady
expr: externalsecret_status_condition{job="external-secrets",condition="Ready",status="True"}
== 0
for: 10m
labels:
severity: warning
annotations:
summary: Secret 同步 {{ $labels.namespace }}/{{ $labels.name }} 未就绪
description: 检查 ExternalSecret 状态及 provider 权限、网络;不要输出 Secret 内容。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: ClusterSecretStoreNotReady
expr: clustersecretstore_status_condition{job="external-secrets",condition="Ready",status="True"}
== 0
for: 5m
labels:
severity: critical
annotations:
summary: ClusterSecretStore {{ $labels.name }} 未就绪
description: 检查 OpenBao 可达性与 ESO 身份鉴权;可能影响多个命名空间。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: FluxResourceNotReady
expr: gotk_resource_info{job="kube-state-metrics",ready!="True",suspended!="true",repository_type!="oci"}
== 1
for: 15m
labels:
severity: warning
annotations:
summary: Flux {{ $labels.customresource_kind }} {{ $labels.resource_namespace
}}/{{ $labels.name }} 未就绪
description: 检查对象 conditions、依赖和 controller 日志;主动 suspend 不触发,不自动解除暂停。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- alert: FluxStateMetricsMissing
expr: absent(gotk_resource_info{job="kube-state-metrics",customresource_kind="Kustomization",resource_namespace="flux-system",name="flux-system"})
for: 5m
labels:
severity: warning
annotations:
summary: Flux 对象状态指标缺失
description: 检查 kube-state-metrics 自定义资源配置、RBAC 与采集;不能把空结果当作健康。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
@@ -0,0 +1,22 @@
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: cnpg
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- shared-db
selector:
matchLabels:
cnpg.io/cluster: shared-postgresql
cnpg.io/podRole: instance
podTargetLabels:
- cnpg.io/cluster
podMetricsEndpoints:
- port: metrics
interval: 30s
honorLabels: true
relabelings:
- targetLabel: job
replacement: cnpg
@@ -1,6 +1,6 @@
# Pull metrics from Docker hosts running ../../docker-hosts/compose.yaml.
# vmagent scrapes each host's node-exporter (:9100) and cAdvisor (:8080) over the LAN.
# Add one target block per host; keep the `host` label in sync with its HOST_LABEL.
# 仅抓取已存在的宿主机 node-exporter。旧 :8080 目标实际返回 nginx 404,
# 独立 Docker cAdvisor 尚未部署;部署并确认端口后再添加其目标。
# Kubernetes 容器指标由 kubelet.yaml 的 /metrics/cadvisor 独立采集。
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMStaticScrape
metadata:
@@ -17,13 +17,6 @@ spec:
labels:
job: node-exporter
host: docker-01
- targets:
- "192.168.10.127:8080"
labels:
job: cadvisor
host: docker-01
# --- add more hosts below, mirroring the two blocks above ---
# --- 新增主机前确认 exporter 已部署且 /metrics 返回成功 ---
# - targets: ["192.168.10.x:9100"]
# labels: { job: node-exporter, host: docker-02 }
# - targets: ["192.168.10.x:8080"]
# labels: { job: cadvisor, host: docker-02 }
@@ -13,6 +13,9 @@ spec:
honorLabels: true
honorTimestamps: false
interval: 30s
# k3s 此端点包含 apiserver/etcd 指标,响应已超过默认 16 MiB。
# 仅放宽 kubelet 任务,其他采集目标保留默认限制。
max_scrape_size: "32MiB"
tlsConfig:
insecureSkipVerify: true
caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
@@ -0,0 +1,57 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- cert-manager
selector:
matchLabels:
app.kubernetes.io/name: cert-manager
app.kubernetes.io/component: controller
jobLabel: app.kubernetes.io/name
endpoints:
- port: http-metrics
interval: 30s
scrapeTimeout: 10s
honorLabels: true
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: external-secrets
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- external-secrets
selector:
matchLabels:
app.kubernetes.io/instance: external-secrets
jobLabel: app.kubernetes.io/name
podMetricsEndpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
honorLabels: true
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: flux-controllers
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- flux-system
selector:
matchLabels:
app.kubernetes.io/part-of: flux
jobLabel: app
podMetricsEndpoints:
- port: http-prom
interval: 30s
scrapeTimeout: 10s
honorLabels: true
@@ -0,0 +1,25 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: seaweedfs
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- seaweedfs
selector:
matchLabels:
app.kubernetes.io/name: seaweedfs
app.kubernetes.io/instance: seaweedfs
endpoints:
- port: metrics
interval: 30s
honorLabels: true
relabelings:
- sourceLabels:
- __meta_kubernetes_service_name
regex: seaweedfs-(master|volume|filer)
action: keep
- sourceLabels:
- __meta_kubernetes_service_name
targetLabel: job
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# 依赖 Python 3 + PyYAML,以及 PATH 中的 promtool(验证版本 3.5.0)。
set -euo pipefail
test_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
check_dir="$(mktemp -d)"
trap 'rm -rf "$check_dir"' EXIT
python3 - "$test_dir/../rules" "$check_dir/rules.yaml" <<'PY'
import pathlib
import sys
import yaml
groups = []
for name in ("kubernetes-health", "host-health", "monitoring-delivery", "platform-controllers", "data-services"):
path = pathlib.Path(sys.argv[1]) / f"{name}.yaml"
groups.extend(yaml.safe_load(path.read_text())["spec"]["groups"])
pathlib.Path(sys.argv[2]).write_text(yaml.safe_dump({"groups": groups}, allow_unicode=True))
PY
cp "$test_dir/"*.test.yaml "$check_dir/"
promtool check rules "$check_dir/rules.yaml"
promtool test rules "$check_dir/"*.test.yaml
@@ -0,0 +1,137 @@
rule_files:
- rules.yaml
evaluation_interval: 1m
tests:
- name: 健康 ZFS 的零值故障状态不报警
interval: 1m
input_series:
- series: node_zfs_zpool_state{job="node-exporter",instance="laptop",zpool="data",state="degraded"}
values: '0x20'
- series: node_zfs_zpool_state{job="node-exporter",instance="laptop",zpool="data",state="online"}
values: 1x20
alert_rule_test:
- eval_time: 10m
alertname: HostZpoolUnhealthy
exp_alerts: &id001 []
- name: ZFS 降级持续五分钟触发
interval: 1m
input_series:
- series: node_zfs_zpool_state{job="node-exporter",instance="laptop",zpool="data",state="degraded"}
values: 1x20
alert_rule_test:
- eval_time: 4m
alertname: HostZpoolUnhealthy
exp_alerts: *id001
- eval_time: 6m
alertname: HostZpoolUnhealthy
exp_alerts:
- exp_labels:
job: node-exporter
instance: laptop
zpool: data
state: degraded
severity: critical
exp_annotations:
summary: 主机 laptop ZFS 池 data 状态 degraded
description: 检查 zpool status、磁盘和冗余;零值状态不触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- name: 忽略旧 docker-hosts 重复主机指标
interval: 1m
input_series:
- series: node_memory_MemAvailable_bytes{job="node-exporter",instance="laptop"}
values: 50x20
- series: node_memory_MemTotal_bytes{job="node-exporter",instance="laptop"}
values: 100x20
- series: node_memory_MemAvailable_bytes{job="docker-hosts",instance="laptop"}
values: 1x20
- series: node_memory_MemTotal_bytes{job="docker-hosts",instance="laptop"}
values: 100x20
alert_rule_test:
- eval_time: 15m
alertname: HostMemoryLow
exp_alerts: *id001
- name: 临时文件系统耗尽不触发持久磁盘告警
interval: 1m
input_series:
- series: node_filesystem_avail_bytes{job="node-exporter",instance="laptop",device="tmpfs",mountpoint="/run",fstype="tmpfs"}
values: 1x20
- series: node_filesystem_size_bytes{job="node-exporter",instance="laptop",device="tmpfs",mountpoint="/run",fstype="tmpfs"}
values: 100x20
- series: node_filesystem_readonly{job="node-exporter",instance="laptop",device="tmpfs",mountpoint="/run",fstype="tmpfs"}
values: '0x20'
alert_rule_test:
- eval_time: 20m
alertname: HostFilesystemSpaceLow
exp_alerts: *id001
- name: Deployment 允许短暂滚动且缩零不报错
interval: 1m
input_series:
- series: kube_deployment_spec_replicas{job="kube-state-metrics",namespace="app",deployment="web"}
values: 2x20
- series: kube_deployment_status_replicas_available{job="kube-state-metrics",namespace="app",deployment="web"}
values: 1x20
- series: kube_deployment_spec_replicas{job="kube-state-metrics",namespace="app",deployment="scaled-down"}
values: '0x20'
- series: kube_deployment_status_replicas_available{job="kube-state-metrics",namespace="app",deployment="scaled-down"}
values: '0x20'
alert_rule_test:
- eval_time: 5m
alertname: KubeDeploymentUnavailable
exp_alerts: *id001
- eval_time: 11m
alertname: KubeDeploymentUnavailable
exp_alerts:
- exp_labels:
namespace: app
deployment: web
severity: warning
exp_annotations:
summary: Deployment app/web 副本不足
description: 可用副本持续 10 分钟低于声明值;缩容至零不会触发。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- name: NATS 发现集合完全消失也报警
interval: 1m
input_series: []
alert_rule_test:
- eval_time: 6m
alertname: NatsMetricsUnavailable
exp_alerts:
- exp_labels:
job: nats/nats
severity: warning
exp_annotations:
summary: NATS 指标采集不可用
description: 依次检查 PodMonitor、转换后的 VMPodScrape、:7777 exporter 及 targets。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
- name: 历史 OOM 没有新重启不反复报警
interval: 1m
input_series:
- series: kube_pod_container_status_last_terminated_reason{job="kube-state-metrics",namespace="app",pod="web",container="web",reason="OOMKilled"}
values: 1x20
- series: kube_pod_container_status_restarts_total{job="kube-state-metrics",namespace="app",pod="web",container="web"}
values: 5x20
alert_rule_test:
- eval_time: 10m
alertname: KubePodOOMKilled
exp_alerts: *id001
- name: Telegram 失败跨 reason 汇总为一条
interval: 1m
input_series:
- series: alertmanager_notifications_failed_total{job="vmalertmanager-main",instance="am",integration="telegram",reason="clientError"}
values: 0+1x20
- series: alertmanager_notifications_failed_total{job="vmalertmanager-main",instance="am",integration="telegram",reason="serverError"}
values: 0+1x20
alert_rule_test:
- eval_time: 6m
alertname: AlertmanagerTelegramDeliveryFailed
exp_alerts:
- exp_labels:
job: vmalertmanager-main
instance: am
integration: telegram
severity: critical
exp_annotations:
summary: Alertmanager 向 Telegram 发送失败
description: 检查网络、bot token 和频道权限。若 Telegram 完全不可达,本告警也无法经同一渠道送达;需在 Alertmanager/Grafana
排查,集群外心跳另行建设。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-foundation.md
@@ -0,0 +1,185 @@
rule_files:
- rules.yaml
evaluation_interval: 1m
tests:
- name: Flux 暂停的失败对象不报警
interval: 1m
input_series:
- series: gotk_resource_info{job="kube-state-metrics",ready="False",suspended="true",customresource_kind="HelmRelease",resource_namespace="app",name="paused"}
values: 1x30
alert_rule_test:
- eval_time: 20m
alertname: FluxResourceNotReady
exp_alerts: []
- name: Flux 缺省 suspend 仍检测失败
interval: 1m
input_series:
- series: gotk_resource_info{job="kube-state-metrics",ready="False",customresource_kind="HelmRelease",resource_namespace="app",name="broken"}
values: 1x30
alert_rule_test:
- eval_time: 10m
alertname: FluxResourceNotReady
exp_alerts: []
- eval_time: 16m
alertname: FluxResourceNotReady
exp_alerts:
- exp_labels:
job: kube-state-metrics
ready: 'False'
customresource_kind: HelmRelease
resource_namespace: app
name: broken
severity: warning
exp_annotations:
summary: Flux HelmRelease app/broken 未就绪
description: 检查对象 conditions、依赖和 controller 日志;主动 suspend 不触发,不自动解除暂停。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- name: 证书一天内到期只由 critical 接替
interval: 1m
input_series:
- series: certmanager_certificate_expiration_timestamp_seconds{job="cert-manager",namespace="app",name="tls"}
values: 3600x30
alert_rule_test:
- eval_time: 20m
alertname: CertificateExpiringSoon
exp_alerts: []
- name: 过期证书仍持续 critical
interval: 1m
input_series:
- series: certmanager_certificate_expiration_timestamp_seconds{job="cert-manager",namespace="app",name="tls"}
values: '0x30'
alert_rule_test:
- eval_time: 4m
alertname: CertificateExpiryCritical
exp_alerts: []
- eval_time: 6m
alertname: CertificateExpiryCritical
exp_alerts:
- exp_labels:
job: cert-manager
namespace: app
name: tls
severity: critical
exp_annotations:
summary: 证书 app/tls 即将到期或已过期
description: 不足一天或已经过期;立即检查续期与入口证书。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- name: ESO False 零值不能导致健康对象误报
interval: 1m
input_series:
- series: externalsecret_status_condition{job="external-secrets",condition="Ready",status="False",namespace="app",name="credentials"}
values: '0x30'
- series: externalsecret_status_condition{job="external-secrets",condition="Ready",status="True",namespace="app",name="credentials"}
values: 1x30
alert_rule_test:
- eval_time: 20m
alertname: ExternalSecretNotReady
exp_alerts: []
- name: ESO 失败持续十分钟报警
interval: 1m
input_series:
- series: externalsecret_status_condition{job="external-secrets",condition="Ready",status="True",namespace="app",name="credentials"}
values: '0x30'
alert_rule_test:
- eval_time: 9m
alertname: ExternalSecretNotReady
exp_alerts: []
- eval_time: 11m
alertname: ExternalSecretNotReady
exp_alerts:
- exp_labels:
job: external-secrets
condition: Ready
status: 'True'
namespace: app
name: credentials
severity: warning
exp_annotations:
summary: Secret 同步 app/credentials 未就绪
description: 检查 ExternalSecret 状态及 provider 权限、网络;不要输出 Secret 内容。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- name: CNPG 聚合数据库连接并对齐实例限额
interval: 1m
input_series:
- series: cnpg_backends_total{job="cnpg",namespace="db",pod="pg-1",datname="a"}
values: 50x30
- series: cnpg_backends_total{job="cnpg",namespace="db",pod="pg-1",datname="b"}
values: 40x30
- series: cnpg_pg_settings_setting{job="cnpg",namespace="db",pod="pg-1",name="max_connections"}
values: 100x30
alert_rule_test:
- eval_time: 9m
alertname: CnpgConnectionsHigh
exp_alerts: []
- eval_time: 11m
alertname: CnpgConnectionsHigh
exp_alerts:
- exp_labels:
job: cnpg
namespace: db
pod: pg-1
severity: warning
exp_annotations:
summary: CNPG pg-1 连接使用率超过 80%
description: 检查连接池、空闲连接和连接泄漏,不直接提高 max_connections。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- name: SeaweedFS 磁盘分母忽略 type 标签
interval: 1m
input_series:
- series: SeaweedFS_volumeServer_resource{job="seaweedfs-volume",name="/data",type="avail"}
values: 5x30
- series: SeaweedFS_volumeServer_resource{job="seaweedfs-volume",name="/data",type="all"}
values: 100x30
alert_rule_test:
- eval_time: 9m
alertname: SeaweedVolumeDiskLow
exp_alerts: []
- eval_time: 11m
alertname: SeaweedVolumeDiskLow
exp_alerts:
- exp_labels:
job: seaweedfs-volume
name: /data
severity: warning
exp_annotations:
summary: SeaweedFS /data 可用空间不足 10%
description: 检查 volume 文件系统容量、保留策略与底层 ZFS;不要直接删除卷文件。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-data-services.md
- name: NATS 历史慢消费者计数不持续报警
interval: 1m
input_series:
- series: nats_varz_slow_consumers{job="nats/nats"}
values: 10x30
alert_rule_test:
- eval_time: 20m
alertname: NatsSlowConsumers
exp_alerts: []
- name: Flux 根对象状态指标缺失报警
interval: 1m
input_series: []
alert_rule_test:
- eval_time: 4m
alertname: FluxStateMetricsMissing
exp_alerts: []
- eval_time: 6m
alertname: FluxStateMetricsMissing
exp_alerts:
- exp_labels:
job: kube-state-metrics
customresource_kind: Kustomization
resource_namespace: flux-system
name: flux-system
severity: warning
exp_annotations:
summary: Flux 对象状态指标缺失
description: 检查 kube-state-metrics 自定义资源配置、RBAC 与采集;不能把空结果当作健康。
runbook_url: https://git.ddupan.top/panxiao81/homelab-wiki/src/branch/main/guides/monitoring-controllers.md
- name: OCI HelmRepository 没有 Ready 条件仍不误报
interval: 1m
input_series:
- series: gotk_resource_info{job="kube-state-metrics",customresource_kind="HelmRepository",repository_type="oci",name="envoy-gateway"}
values: 1x30
alert_rule_test:
- eval_time: 20m
alertname: FluxResourceNotReady
exp_alerts: []
@@ -10,6 +10,11 @@ spec:
replicaCount: 1
selectAllByDefault: true
evaluationInterval: 30s
# 告警 Source 复用已认证的 Grafana 入口,携带表达式和触发时间。
# 整个 Explore JSON 一次性 URL 编码,避免表达式中的引号、&、+ 损坏链接。
extraArgs:
external.url: https://grafana.ad.ddupan.top
external.alert.source: 'explore?left={{ printf "{\"datasource\":\"VictoriaMetrics\",\"queries\":[{\"expr\":%s,\"refId\":\"A\"}],\"range\":{\"from\":\"%d\",\"to\":\"now\"}}" (.Expr | jsonEscape) .ActiveAt.UnixMilli | queryEscape }}'
datasource:
url: http://vmsingle-main.monitoring.svc:8428
remoteWrite:
@@ -1,6 +1,4 @@
# Alert router/notifier. Migrated from the retired Compose stack (see Git history),
# which currently blackholes everything. Wire real receivers here (email via the
# in-cluster smtp-relay, or a webhook) when you want notifications.
# Telegram token 由 ExternalSecret 从 OpenBao 投射,配置中仅引用文件。
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMAlertmanager
metadata:
@@ -8,19 +6,37 @@ metadata:
namespace: monitoring
spec:
replicaCount: 1
secrets:
- alertmanager-telegram
configRawYaml: |
route:
receiver: blackhole
group_by: [alertname, cluster, job, severity]
group_wait: 1m
group_interval: 5m
repeat_interval: 4h
routes:
- receiver: telegram
matchers:
- severity="critical"
group_wait: 10s
repeat_interval: 1h
- receiver: telegram
matchers:
- severity="warning"
inhibit_rules:
- source_matchers:
- alertname="KubePodCrashLooping"
target_matchers:
- alertname="KubePodFrequentRestarts"
equal: [namespace, pod, container]
receivers:
- name: blackhole
# Example email receiver via the in-cluster Postfix relay (smtp-relay/):
# receivers:
# - name: email
# email_configs:
# - to: '[email protected]'
# from: 'Alertmanager <[email protected]>'
# smarthost: 'smtp-relay.smtp-relay.svc.cluster.local:25'
# require_tls: false
- name: telegram
telegram_configs:
- bot_token_file: /etc/vm/secrets/alertmanager-telegram/telegram_bot_token
chat_id: -1003956377923
send_resolved: true
resources:
requests:
cpu: 25m
@@ -4,6 +4,8 @@ metadata:
name: vm-operator
namespace: monitoring
spec:
dependsOn:
- name: prometheus-operator-crds
chart:
spec:
chart: victoria-metrics-operator