Appearance
K3s部署监控栈
K3s 上部署 Prometheus 监控栈,核心检查点是采集链路是否覆盖 Kubernetes 对象、节点、容器和控制平面入口。kube-prometheus-stack 会同时安装 Prometheus Operator、Prometheus、Alertmanager、Grafana、node-exporter、kube-state-metrics 和相关 CRD。
监控栈部署在 K3s 上。Prometheus、Grafana、Alertmanager、kube-state-metrics、node-exporter 都会长期占用内存,日志、链路追踪和 CI/CD 组件也会继续叠加。K3s 保留 Kubernetes 资源模型,同时减少控制平面和基础组件的维护负担,更适合小规格集群承载这些平台。K3s 环境部署参考 Kubernetes 系列里的 K3s 安装部署。
当前 K3s 集群是三节点单 server 架构:
| 节点 | IP | 角色 |
|---|---|---|
k3s-server01 | 192.168.10.11 | control-plane |
k3s-agent01 | 192.168.10.12 | agent |
k3s-agent02 | 192.168.10.13 | agent |
这套 K3s 默认使用 SQLite,不存在 etcd 采集端点。etcd 监控归到 embedded etcd 场景单独处理。
一、资源控制
默认 kube-prometheus-stack 会创建大量规则和 Grafana dashboard,小机器上容易把内存打满。当前三台机器内存并不宽裕,k3s-server01 约 3.5Gi,k3s-agent01 约 2.4Gi,k3s-agent02 约 1.9Gi。部署时做了几项收口:
| 项目 | 处理 |
|---|---|
| 默认规则 | 关闭 defaultRules.create,按场景单独补规则 |
| Grafana 默认看板 | 关闭默认 dashboard,减少 ConfigMap 和 sidecar 压力 |
| Grafana sidecar | 关闭 dashboard/datasource sidecar,改成静态数据源 |
| Prometheus 保留周期 | 12h,retentionSize 限制为 1000MB |
| Prometheus 采集周期 | 60s,小环境先降低抓取频率 |
| Prometheus 存储 | local-path PVC 5Gi |
| Alertmanager 存储 | local-path PVC 1Gi |
| Grafana 存储 | local-path PVC 1Gi |
| etcd/scheduler/controller-manager/kube-proxy | 当前 K3s 形态先关闭对应抓取项 |
local-path PVC 会绑定到首次运行 Pod 的节点。Grafana 如果已经在某个节点创建过 PVC,再直接改 nodeSelector 到另一个节点,Pod 会因为本地卷节点亲和性卡在 Pending。当前 Grafana 固定到 k3s-agent01,避免继续占用内存更小的 k3s-agent02。
二、镜像源
监控栈常用镜像分布在 quay.io、registry.k8s.io、docker.io、ghcr.io。国内环境直接拉取经常不稳定,三台节点都配置 containerd mirror。
bash
base=/var/lib/rancher/k3s/agent/etc/containerd/certs.d
mkdir -p "$base/docker.io" "$base/quay.io" "$base/registry.k8s.io" "$base/ghcr.io" "$base/gcr.io"
cat >"$base/docker.io/hosts.toml" <<'EOF'
server = "https://registry-1.docker.io"
[host."https://docker.1ms.run"]
capabilities = ["pull", "resolve"]
EOF
cat >"$base/quay.io/hosts.toml" <<'EOF'
server = "https://quay.io"
[host."https://quay.m.daocloud.io"]
capabilities = ["pull", "resolve"]
EOF
cat >"$base/registry.k8s.io/hosts.toml" <<'EOF'
server = "https://registry.k8s.io"
[host."https://k8s.m.daocloud.io"]
capabilities = ["pull", "resolve"]
EOF
cat >"$base/ghcr.io/hosts.toml" <<'EOF'
server = "https://ghcr.io"
[host."https://ghcr.m.daocloud.io"]
capabilities = ["pull", "resolve"]
EOF
cat >"$base/gcr.io/hosts.toml" <<'EOF'
server = "https://gcr.io"
[host."https://gcr.m.daocloud.io"]
capabilities = ["pull", "resolve"]
EOF重启 K3s 服务让 containerd 重新读取配置:
bash
# server 节点
systemctl restart k3s
# agent 节点
systemctl restart k3s-agent三、安装 Helm
bash
cd /tmp
# Helm 安装在执行部署的管理节点上
curl -L --connect-timeout 10 --retry 3 \
https://get.helm.sh/helm-v3.18.6-linux-amd64.tar.gz \
-o helm-v3.18.6-linux-amd64.tar.gz
tar -zxf helm-v3.18.6-linux-amd64.tar.gz
install -m 0755 linux-amd64/helm /usr/local/bin/helm
helm version --shortK3s 的 kubeconfig 在 /etc/rancher/k3s/k3s.yaml。Helm 执行前设置:
bash
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml四、values 配置
/root/monitoring/kps-lite-values.yaml:
yaml
fullnameOverride: kps
crds:
enabled: true
defaultRules:
create: false
kubeEtcd:
enabled: false
kubeControllerManager:
enabled: false
kubeScheduler:
enabled: false
kubeProxy:
enabled: false
kubeApiServer:
enabled: true
coreDns:
enabled: true
kubelet:
enabled: true
nodeExporter:
enabled: true
kubeStateMetrics:
enabled: true
prometheusOperator:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
nodeSelector:
kubernetes.io/hostname: k3s-server01
prometheus-node-exporter:
resources:
requests:
cpu: 20m
memory: 32Mi
limits:
memory: 128Mi
kube-state-metrics:
resources:
requests:
cpu: 30m
memory: 96Mi
limits:
memory: 192Mi
nodeSelector:
kubernetes.io/hostname: k3s-server01
grafana:
enabled: true
adminPassword: "admin123"
defaultDashboardsEnabled: false
defaultDashboardsTimezone: Asia/Shanghai
service:
type: NodePort
nodePort: 30300
nodeSelector:
kubernetes.io/hostname: k3s-agent01
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 384Mi
persistence:
enabled: true
type: pvc
storageClassName: local-path
accessModes:
- ReadWriteOnce
size: 1Gi
sidecar:
dashboards:
enabled: false
datasources:
enabled: false
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus
access: proxy
url: http://kps-prometheus.monitoring:9090
isDefault: true
editable: true
alertmanager:
service:
type: NodePort
nodePort: 30903
alertmanagerSpec:
replicas: 1
nodeSelector:
kubernetes.io/hostname: k3s-server01
resources:
requests:
cpu: 30m
memory: 64Mi
limits:
memory: 192Mi
storage:
volumeClaimTemplate:
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
prometheus:
service:
type: NodePort
nodePort: 30900
prometheusSpec:
replicas: 1
retention: 12h
retentionSize: 1000MB
scrapeInterval: 60s
evaluationInterval: 60s
nodeSelector:
kubernetes.io/hostname: k3s-server01
resources:
requests:
cpu: 100m
memory: 384Mi
limits:
memory: 768Mi
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
serviceMonitorSelectorNilUsesHelmValues: false
podMonitorSelectorNilUsesHelmValues: false
ruleSelectorNilUsesHelmValues: false
probeSelectorNilUsesHelmValues: false这份配置偏向小环境。Grafana 默认 dashboard 和 sidecar 关闭后,Grafana 只保留一个主容器,内存占用明显更低。Prometheus 保留 12h,抓取周期放到 60s,适合当前集群先验证采集链路;长期保留通常要配远端存储,或者把 Prometheus 单独放到资源更宽裕的节点。
五、安装监控栈
bash
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm upgrade --install kps prometheus-community/kube-prometheus-stack \
--namespace monitoring --create-namespace \
--version 85.3.3 \
-f /root/monitoring/kps-lite-values.yaml \
--timeout 15m网络不稳定时,可以提前下载 chart 包,再用本地包升级:
bash
helm upgrade --install kps /root/monitoring/kube-prometheus-stack-85.3.3.tgz \
--namespace monitoring --create-namespace \
-f /root/monitoring/kps-lite-values.yaml \
--timeout 15m六、组件状态
bash
kubectl -n monitoring get pods -o wide
kubectl -n monitoring get svc -o wide
kubectl -n monitoring get pvc
kubectl -n monitoring top pods本次部署后的核心 Pod:
text
alertmanager-kps-alertmanager-0 2/2 Running
kps-grafana-56fb658cf7-l2tfh 1/1 Running
kps-kube-state-metrics-7845f765c4-szf5z 1/1 Running
kps-operator-5c67bb6dd7-5gdbp 1/1 Running
kps-prometheus-node-exporter-78cnk 1/1 Running
kps-prometheus-node-exporter-mnnb5 1/1 Running
kps-prometheus-node-exporter-mxjsm 1/1 Running
prometheus-kps-prometheus-0 2/2 RunningNodePort:
| 组件 | 地址 |
|---|---|
| Grafana | http://192.168.10.11:30300 |
| Prometheus | http://192.168.10.11:30900 |
| Alertmanager | http://192.168.10.11:30903 |
Grafana 账号:
| 用户 | 密码 |
|---|---|
admin | admin123 |
PVC:
text
alertmanager-kps-alertmanager-db-alertmanager-kps-alertmanager-0 1Gi
kps-grafana 1Gi
prometheus-kps-prometheus-db-prometheus-kps-prometheus-0 5Gi七、Target 验证
Prometheus ready:
bash
# Prometheus ready 接口返回 200,说明服务已经能处理请求
curl -sS -o /dev/null -w 'prometheus %{http_code}\n' \
http://192.168.10.11:30900/-/readyGrafana ready:
bash
# Grafana 登录页返回 200,只用于验证 Web 入口可访问
curl -sS -o /dev/null -w 'grafana %{http_code}\n' \
http://192.168.10.11:30300/loginAlertmanager ready:
bash
# Alertmanager ready 接口返回 200,说明告警接收服务已经就绪
curl -sS -o /dev/null -w 'alertmanager %{http_code}\n' \
http://192.168.10.11:30903/-/ready三者都返回 200。Prometheus Status -> Targets 里已经有这些 target:
| job | 说明 |
|---|---|
apiserver | K3s API Server |
coredns | 集群 DNS |
kubelet | 三台节点 kubelet、cAdvisor、probes |
node-exporter | 三台节点主机指标 |
kube-state-metrics | K8s 对象状态 |
kps-prometheus | Prometheus 自身 |
kps-alertmanager | Alertmanager |
kps-grafana | Grafana |
几个查询验证:
bash
# 当前抓取目标数量
curl -sG http://127.0.0.1:30900/api/v1/query \
--data-urlencode 'query=count(up)'
# K8s Pod 对象指标
curl -sG http://127.0.0.1:30900/api/v1/query \
--data-urlencode 'query=count(kube_pod_info)'
# 三台节点 node-exporter 指标
curl -sG http://127.0.0.1:30900/api/v1/query \
--data-urlencode 'query=count(node_uname_info)'
# 容器 CPU 指标,来自 kubelet/cAdvisor
curl -sG http://127.0.0.1:30900/api/v1/query \
--data-urlencode 'query=count(container_cpu_usage_seconds_total)'
# API Server 请求指标
curl -sG http://127.0.0.1:30900/api/v1/query \
--data-urlencode 'query=count(apiserver_request_total)'本次验证结果里,count(up) 是 21,count(node_uname_info) 是 3,说明三台节点都被 node-exporter 覆盖。kube_pod_info、container_cpu_usage_seconds_total、apiserver_request_total 都能查到数据,说明对象状态、容器资源和 API Server 指标已经进入 Prometheus。
资源占用也要同时看一下:
bash
# 看节点整体资源压力
kubectl top nodes
# 看 monitoring 命名空间里每个容器的 CPU 和内存
kubectl -n monitoring top pods --containers当前 Prometheus 主容器约 289Mi,Grafana 约 349Mi,Alertmanager 主容器约 45Mi。Grafana 启动时会有一段镜像拉取和 readiness 探测失败记录,只要最终 Pod 进入 Running,访问 /login 返回 200,就不是内存把服务打崩。
八、当前未启用项
当前 values 里关闭了几类 target:
| 项目 | 原因 |
|---|---|
kubeEtcd | 当前 K3s 是 SQLite,不存在 etcd 指标端点 |
kubeScheduler | K3s 将控制面组件打包在 k3s server 进程里,默认监听回环地址 |
kubeControllerManager | 同上,控制平面监控单独处理 |
kubeProxy | K3s 默认不一定按独立 kube-proxy 形态暴露指标 |
| default rules | 小环境先降低规则数量和内存压力 |
| default dashboards | 手动导入或按截图需要创建看板 |
这些关闭项和当前 K3s 形态有关。当前集群先保留已经能稳定采到的指标,控制平面、节点组件、对象状态、应用指标和告警规则分别展开;etcd 放到 embedded etcd 场景处理。