前面已经安装好了 Kubernetes 三主节点集群、MetalLB、ingress-nginx、cert-manager、Longhorn 和 Headlamp。Headlamp 适合查看和管理 Kubernetes 资源,Prometheus + Grafana 更适合做长期监控、趋势分析和告警。

本文使用 prometheus-community/kube-prometheus-stack 一次性安装:

  • Prometheus
  • Grafana
  • Alertmanager
  • kube-state-metrics
  • node-exporter
  • Prometheus Operator

前置条件

确认 Helm、StorageClass、ingress-nginx 都正常:

helm version
kubectl get storageclass
kubectl -n ingress-nginx get svc ingress-nginx-controller -o wide

当前集群已经使用 Longhorn 作为默认存储:

longhorn (default)

如果是学习环境,节点磁盘比较小,建议额外创建一个单副本 StorageClass 给监控组件使用。Prometheus 会持续写入时序数据,使用 Longhorn 默认 3 副本时,一个 10Gi 的 Prometheus PVC 实际需要在多个节点上调度多个 10Gi 副本,很容易因为磁盘空间不足而卡住。

创建学习环境用的单副本 StorageClass:

cat <<'EOF' | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-single
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "1"
  staleReplicaTimeout: "2880"
  fromBackup: ""
EOF

生产环境更推荐继续使用 Longhorn 默认 3 副本,并给每个节点准备足够的独立数据盘。

Grafana 域名准备使用:

grafana.jihw.top

DNS 或本机 hosts 需要解析到 ingress-nginx 的 LoadBalancer IP:

192.168.3.230 grafana.jihw.top

添加 Helm 仓库

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

查看 chart:

helm search repo prometheus-community/kube-prometheus-stack

配置 quay.io 镜像加速

kube-prometheus-stack 会从 quay.io 拉取多个镜像,例如 Prometheus、Alertmanager、node-exporter、prometheus-config-reloader。如果网络比较慢,可能会看到 Prometheus Pod 长时间停在:

PodInitializing
Pulling image "quay.io/prometheus/prometheus:v3.12.0-distroless"

可以给 containerd 增加 quay.io 镜像加速配置。三台节点都执行:

sudo mkdir -p /etc/containerd/certs.d/quay.io

cat <<'EOF' | sudo tee /etc/containerd/certs.d/quay.io/hosts.toml
server = "https://quay.io"

[host."https://quay.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

重启 containerd 让配置生效。建议一台一台执行:

sudo systemctl restart containerd

验证镜像可以正常拉取:

sudo crictl pull quay.io/prometheus/prometheus:v3.12.0-distroless

创建配置文件

创建命名空间:

kubectl create namespace monitoring

创建 values-monitoring.yaml

cat > values-monitoring.yaml <<'EOF'
grafana:
  enabled: true
  adminUser: admin
  adminPassword: "ChangeMe_Grafana_2026"

  persistence:
    enabled: true
    type: pvc
    storageClassName: longhorn-single
    accessModes:
      - ReadWriteOnce
    size: 5Gi

  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-alidns-prod
    hosts:
      - grafana.jihw.top
    tls:
      - secretName: grafana-jihw-top-tls
        hosts:
          - grafana.jihw.top

prometheus:
  prometheusSpec:
    retention: 3d
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: longhorn-single
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 5Gi

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: longhorn-single
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 2Gi
EOF

adminPassword 建议改成自己的强密码。第一次安装完成后,也可以在 Grafana 页面里修改密码。

安装 kube-prometheus-stack

helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f values-monitoring.yaml

等待 Pod 启动:

kubectl -n monitoring get pod -o wide

正常情况下会看到 Prometheus、Grafana、Alertmanager、node-exporter、kube-state-metrics 等组件:

kubectl -n monitoring get pod
kubectl -n monitoring get svc
kubectl -n monitoring get pvc

查看证书和 Ingress

Grafana 的 HTTPS 证书由 cert-manager 自动申请:

kubectl -n monitoring get ingress,certificate -o wide

证书正常时可以看到:

certificate.cert-manager.io/grafana-jihw-top-tls   True   grafana-jihw-top-tls

如果还没有变成 True,查看申请过程:

kubectl -n monitoring get certificaterequest,order,challenge
kubectl -n monitoring describe certificate grafana-jihw-top-tls

访问 Grafana

确认本机可以解析并连通:

nslookup grafana.jihw.top
Test-NetConnection grafana.jihw.top -Port 443

浏览器访问:

https://grafana.jihw.top

默认账号:

用户名:admin
密码:ChangeMe_Grafana_2026

登录后建议立即修改密码。

查看默认监控面板

kube-prometheus-stack 会自动导入一批 Kubernetes 监控面板。进入 Grafana 后可以查看:

Dashboards -> Kubernetes / Compute Resources / Cluster
Dashboards -> Kubernetes / Compute Resources / Namespace
Dashboards -> Kubernetes / Compute Resources / Pod
Dashboards -> Node Exporter / Nodes

Prometheus 数据源也会自动配置好,一般不需要手动添加。

入门案例:创建一个新手巡检面板

默认的 Kubernetes 面板内容很多,刚开始可能不知道看哪里。可以先创建一个简化版 Dashboard,只看最常用的 6 个指标:

  • Ready 节点数
  • Running Pod 数
  • 节点 CPU 使用率
  • 节点内存使用率
  • 根分区磁盘使用率
  • 各命名空间 Running Pod 数

登录 Grafana 后,进入:

Dashboards -> New -> New dashboard

点击 Add visualization,选择 Prometheus 数据源。

第一个面板可以做 Ready 节点数,查询语句:

sum(kube_node_status_condition{condition="Ready",status="true"})

面板类型选择 Stat,标题填写:

Ready 节点数

第二个面板做 Running Pod 数

sum(kube_pod_status_phase{phase="Running"})

面板类型同样选择 Stat

第三个面板做 节点 CPU 使用率

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

面板类型选择 Time series,单位选择 Percent (0-100)

第四个面板做 节点内存使用率

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

第五个面板做 根分区磁盘使用率

(1 - (node_filesystem_avail_bytes{mountpoint="/",fstype!="rootfs"} / node_filesystem_size_bytes{mountpoint="/",fstype!="rootfs"})) * 100

第六个面板做 各命名空间 Running Pod 数

sum by (namespace) (kube_pod_status_phase{phase="Running"})

面板类型可以选择 Bar chart

我在当前 Grafana 中已经创建了一个示例 Dashboard:

新手巡检示例 / Kubernetes Overview

可以直接访问:

https://grafana.jihw.top/d/k8s-beginner-overview/0f0711f

new-api 业务看板

安装好 new-api 后,也可以为它单独创建一个 Dashboard。当前 new-api 没有单独暴露应用级 /metrics,所以先使用 Kubernetes 指标做运行状态监控。

我在 Grafana 中已经创建了:

new-api 监控看板

访问地址:

https://grafana.jihw.top/d/new-api-overview/new-api-e79b91-e68ea7-e79c8b-e69dbf

这个看板包含:

  • new-api 可用副本:看 Deployment 是否至少有 1 个可用副本。
  • new-api Running Pod:看 new-api 命名空间当前运行中的 Pod 数。
  • 1小时容器重启次数:如果大于 0,需要检查 Pod 日志和事件。
  • PVC 最大使用率:看 PostgreSQL、Redis、new-api 数据卷是否接近满盘。
  • CPU 使用量 by Pod:按 Pod 查看 CPU 消耗。
  • 内存使用量 by Pod:按 Pod 查看内存占用。
  • 网络接收/发送流量 by Pod:看应用、PostgreSQL、Redis 的流量变化。
  • PVC 使用率:分别查看 data-postgresql-0redis-data-redis-master-0new-api-data
  • Pod Ready 状态:每个 Pod 为 1 表示 Ready。

常用 PromQL 示例:

kube_deployment_status_replicas_available{namespace="new-api",deployment="new-api"}
sum(increase(kube_pod_container_status_restarts_total{namespace="new-api"}[1h]))
sum(rate(container_cpu_usage_seconds_total{namespace="new-api",container!="",image!=""}[5m])) by (pod)
sum(container_memory_working_set_bytes{namespace="new-api",container!="",image!=""}) by (pod)
(kubelet_volume_stats_used_bytes{namespace="new-api"} / kubelet_volume_stats_capacity_bytes{namespace="new-api"}) * 100

如果后续希望看到 k8s-ai.jihw.top 的 HTTP 请求数、状态码、响应耗时,需要给 ingress-nginx 开启 metrics 并让 Prometheus 采集 ingress-nginx 的指标。

本地临时访问 Prometheus

Prometheus 默认不建议直接暴露到公网或局域网。如果只是临时排查,可以使用端口转发:

kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 9090:9090 --address 0.0.0.0

然后访问:

http://服务器IP:9090

Alertmanager 也可以临时端口转发:

kubectl -n monitoring port-forward svc/kube-prometheus-stack-alertmanager 9093:9093 --address 0.0.0.0

访问:

http://服务器IP:9093

常用排查命令

查看 Helm 安装状态:

helm -n monitoring list
helm -n monitoring status kube-prometheus-stack

查看所有组件:

kubectl -n monitoring get all

查看 PVC:

kubectl -n monitoring get pvc

查看 Grafana 日志:

kubectl -n monitoring logs deploy/kube-prometheus-stack-grafana --tail=100

查看 Prometheus 状态:

kubectl -n monitoring get prometheus
kubectl -n monitoring describe prometheus kube-prometheus-stack-prometheus

查看 Prometheus Operator 日志:

kubectl -n monitoring logs deploy/kube-prometheus-stack-operator --tail=100

查看证书申请状态:

kubectl -n monitoring get certificate,certificaterequest,order,challenge

Prometheus 卡在 Init:0/1

如果 prometheus-kube-prometheus-stack-prometheus-0 一直卡在 Init:0/1

kubectl -n monitoring get pod prometheus-kube-prometheus-stack-prometheus-0 -o wide
kubectl -n monitoring describe pod prometheus-kube-prometheus-stack-prometheus-0

如果事件中出现:

AttachVolume.Attach failed
volume ... is not ready for workloads

继续查看 Longhorn 卷:

kubectl -n longhorn-system get volumes.longhorn.io -o wide
kubectl -n longhorn-system logs -l app=longhorn-manager --since=10m | grep -i 'insufficient storage\|not ready\|failed'

如果日志里出现:

insufficient storage

说明不是 Prometheus 镜像问题,而是 Longhorn 没有足够空间创建该 PVC 的副本。解决办法有三个:

  • 给每个节点扩容磁盘,生产环境推荐这种方式。
  • 降低 Prometheus PVC 容量和保留时间,例如 storage: 5Giretention: 3d。PVC 不能原地缩容,已经创建过 10Gi PVC 时,需要删除旧 PVC 后重新安装。
  • 学习环境使用上面创建的 longhorn-single 单副本 StorageClass。

如果是刚安装的测试环境,确认不需要保留监控数据后,可以删除旧 PVC 并重新安装:

helm -n monitoring uninstall kube-prometheus-stack
kubectl -n monitoring delete pvc --all

helm upgrade --install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f values-monitoring.yaml

删除 PVC 会删除 Prometheus、Grafana、Alertmanager 的持久化数据,已经有重要面板或历史监控数据时不要直接执行。

如果 PVC 和 Longhorn 卷都正常,但 Pod 一直停在 PodInitializing,并且事件里只有:

Pulling image "quay.io/prometheus/prometheus:v3.12.0-distroless"

说明多半是 quay.io 镜像拉取慢。按上面的“配置 quay.io 镜像加速”处理,然后重新拉取或等待 kubelet 自动重试即可。

升级

更新 Helm 仓库:

helm repo update

升级:

helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f values-monitoring.yaml

卸载

卸载 chart:

helm -n monitoring uninstall kube-prometheus-stack

如果确认不再需要监控数据,再删除 PVC:

kubectl -n monitoring delete pvc --all

最后删除命名空间:

kubectl delete namespace monitoring

生产环境卸载前一定要先确认是否还需要 Prometheus 历史数据和 Grafana 面板配置。