kube-prometheus-stack 87.21.0 部署记录
一、部署结果
本次使用 Helm 部署:
text
kube-prometheus-stack
部署信息:
text
Chart 版本:87.21.0
Helm Release:monitoring
命名空间:monitoring
最终状态:deployed
主要组件包括:
- Prometheus
- Alertmanager
- Grafana
- Prometheus Operator
- kube-state-metrics
- node-exporter
二、本次部署中的镜像处理方式
普通镜像通过 image-rewrite.py 转换为 DaoCloud 国内镜像地址,例如:
text
quay.io/prometheus/prometheus
转换为:
text
m.daocloud.io/quay.io/prometheus/prometheus
但是 Admission Webhook 使用的镜像:
text
ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
通过下面两个 DaoCloud 地址拉取都会返回 403 Forbidden:
text
m.daocloud.io/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
m.daocloud.io/docker.io/jkroepke/kube-webhook-certgen:1.8.5
因此,本次最终改用已经实测可以正常拉取的华为云 SWR 地址:
text
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
最终镜像策略:
text
普通镜像:DaoCloud
Webhook 镜像:华为云 SWR
三、进入部署目录
以下命令在 k8s-master01 执行。
bash
mkdir -p ~/monitoring-install
cd ~/monitoring-install
确认当前位置:
bash
pwd
正常应为:
text
/home/leecurry/monitoring-install
四、设置 Chart 版本
bash
export CHART_VERSION=87.21.0
检查变量:
bash
echo "CHART_VERSION=[$CHART_VERSION]"
正常输出:
text
CHART_VERSION=[87.21.0]
注意:
export 设置的变量只在当前终端会话中有效。
如果重新登录服务器,需要再次执行:
bash
export CHART_VERSION=87.21.0
五、下载 Helm Chart
1. 删除之前可能下载失败的文件
bash
rm -f "kube-prometheus-stack-${CHART_VERSION}.tgz"
2. 使用 DaoCloud 加速 GitHub Release
bash
curl -fL --retry 5 --retry-delay 5 \
"https://files.m.daocloud.io/github.com/prometheus-community/helm-charts/releases/download/kube-prometheus-stack-${CHART_VERSION}/kube-prometheus-stack-${CHART_VERSION}.tgz" \
-o "kube-prometheus-stack-${CHART_VERSION}.tgz"
不要再使用下面这个已经返回 404 的旧地址:
text
https://files.m.daocloud.io/prometheus-community.github.io/helm-charts/kube-prometheus-stack-87.21.0.tgz
3. 检查文件
bash
ls -lh "kube-prometheus-stack-${CHART_VERSION}.tgz"
4. 验证 Helm Chart
bash
helm show chart \
"kube-prometheus-stack-${CHART_VERSION}.tgz" \
| grep -E '^(name|version|appVersion):'
重点确认:
text
name: kube-prometheus-stack
version: 87.21.0
只要 helm show chart 能正常读取并显示 Chart 信息,就说明下载到的是正确安装包,而不是 HTML 错误页面。
六、确认 values-lab.yaml
本次部署使用已经准备好的:
text
values-lab.yaml
确认文件存在:
bash
ls -lh values-lab.yaml
查看内容:
bash
cat values-lab.yaml
本记录不重新生成 values-lab.yaml,继续使用本次成功安装时使用的原文件。
不要使用一份新的空文件覆盖它。
七、创建镜像转换脚本
1. 删除错误或损坏的旧脚本
bash
rm -f image-rewrite.py
2. 重新创建脚本
bash
cat > image-rewrite.py <<'PY'
#!/usr/bin/env python3
import re
import sys
MIRROR = "m.daocloud.io"
KNOWN_PUBLIC_REGISTRIES = {
"docker.io",
"registry-1.docker.io",
"quay.io",
"ghcr.io",
"registry.k8s.io",
"gcr.io",
"k8s.gcr.io",
"us.gcr.io",
"eu.gcr.io",
"asia.gcr.io",
}
IMAGE_PATTERN = re.compile(
r'^(?P<prefix>\s*image:\s*)'
r'(?P<quote>["\']?)'
r'(?P<image>[^"\'\s#]+)'
r'(?P=quote)'
r'(?P<suffix>\s*(?:#.*)?)$'
)
def rewrite_image(image: str) -> str:
# 已经是 DaoCloud 地址,不再重复处理
if image.startswith(f"{MIRROR}/"):
return image
first_part = image.split("/", 1)[0]
# 已明确写出公网镜像仓库
if first_part in KNOWN_PUBLIC_REGISTRIES:
return f"{MIRROR}/{image}"
# 没有斜杠,例如 busybox:1.36
if "/" not in image:
return f"{MIRROR}/docker.io/library/{image}"
# 没有显式仓库,例如 grafana/grafana:13.1.1
if (
"." not in first_part
and ":" not in first_part
and first_part != "localhost"
):
return f"{MIRROR}/docker.io/{image}"
# 私有仓库、华为云 SWR 或 localhost 保持不变
return image
def main() -> None:
for line in sys.stdin:
stripped_line = line.rstrip("\n")
match = IMAGE_PATTERN.match(stripped_line)
if not match:
sys.stdout.write(line)
continue
original_image = match.group("image")
rewritten_image = rewrite_image(original_image)
output = (
f'{match.group("prefix")}'
f'{match.group("quote")}'
f'{rewritten_image}'
f'{match.group("quote")}'
f'{match.group("suffix")}'
)
sys.stdout.write(output + "\n")
if __name__ == "__main__":
main()
PY
注意最后的:
text
PY
必须单独占一行,并且必须从行首开始,不能和 Python 代码写在同一行。
3. 添加执行权限
bash
chmod +x image-rewrite.py
4. 检查 Python 语法
bash
python3 -m py_compile image-rewrite.py
没有任何输出,说明语法正确。
八、测试镜像转换脚本
bash
printf '%s\n' \
' image: quay.io/prometheus/prometheus:v3.13.1' \
' image: grafana/grafana:13.1.1' \
' image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.1' \
| ./image-rewrite.py
正常应输出:
text
image: m.daocloud.io/quay.io/prometheus/prometheus:v3.13.1
image: m.daocloud.io/docker.io/grafana/grafana:13.1.1
image: m.daocloud.io/registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.19.1
前面的空格数量可能不同,不影响结果。
九、测试 Webhook 特殊镜像
本次需要单独使用的镜像:
text
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
本次失败 Pod 被调度到 k8s-worker01,因此先在 k8s-worker01 测试:
bash
sudo crictl pull \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
本次实际成功输出:
text
Image is up to date for sha256:...
这表示该镜像可以正常拉取。
不要求必须提前在所有节点下载。
只要其他节点也可以访问该 SWR 地址,Pod 调度过去后会自动拉取。
十、预渲染并检查镜像
1. 生成完整渲染结果
bash
helm template monitoring \
"./kube-prometheus-stack-${CHART_VERSION}.tgz" \
--namespace monitoring \
-f values-lab.yaml \
--set prometheusOperator.admissionWebhooks.patch.image.registry=swr.cn-north-4.myhuaweicloud.com \
--set prometheusOperator.admissionWebhooks.patch.image.repository=ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen \
--post-renderer ./image-rewrite.py \
> monitoring-rendered.yaml
2. 检查渲染文件是否生成
bash
ls -lh monitoring-rendered.yaml
3. 查看最终镜像地址
bash
grep -E '^[[:space:]]*image:' monitoring-rendered.yaml \
| sed -E 's/^[[:space:]]*image:[[:space:]]*//; s/^"//; s/"$//' \
| sort -u
普通组件应主要显示为:
text
m.daocloud.io/docker.io/...
m.daocloud.io/quay.io/...
m.daocloud.io/registry.k8s.io/...
Webhook 镜像应显示为:
text
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
不能再出现:
text
m.daocloud.io/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
也不能出现:
text
m.daocloud.io/docker.io/jkroepke/kube-webhook-certgen:1.8.5
4. 自动检查未处理镜像
bash
UNACCELERATED_IMAGES="$(
grep -E '^[[:space:]]*image:' monitoring-rendered.yaml \
| sed -E 's/^[[:space:]]*image:[[:space:]]*//; s/^"//; s/"$//' \
| sort -u \
| grep -Ev '^(m\.daocloud\.io/|swr\.cn-north-4\.myhuaweicloud\.com/)' \
|| true
)"
if [ -n "$UNACCELERATED_IMAGES" ]; then
echo "发现尚未处理的镜像:"
echo "$UNACCELERATED_IMAGES"
else
echo "检查通过:所有镜像均已切换为本次使用的国内地址"
fi
正常输出:
text
检查通过:所有镜像均已切换为本次使用的国内地址
这里不能只允许 m.daocloud.io,因为 Webhook 镜像使用的是华为云 SWR。
十一、清理之前失败的安装
只有之前存在失败的 monitoring Release 时,才需要执行本节。
1. 查看状态
bash
helm status monitoring -n monitoring
如果显示:
text
STATUS: failed
执行卸载。
2. 卸载失败 Release
bash
helm uninstall monitoring -n monitoring
3. 删除可能残留的 Hook Job
bash
kubectl delete job \
monitoring-kube-prometheus-admission-create \
monitoring-kube-prometheus-admission-patch \
-n monitoring \
--ignore-not-found
4. 检查清理结果
bash
helm list -n monitoring -a
bash
kubectl get pods,jobs -n monitoring
如果 helm list 中没有 monitoring,即可重新安装。
不需要专门删除 monitoring 命名空间。
十二、正式安装
在 k8s-master01 的 ~/monitoring-install 目录执行:
bash
helm upgrade --install monitoring \
"./kube-prometheus-stack-${CHART_VERSION}.tgz" \
--namespace monitoring \
--create-namespace \
-f values-lab.yaml \
--set prometheusOperator.admissionWebhooks.patch.image.registry=swr.cn-north-4.myhuaweicloud.com \
--set prometheusOperator.admissionWebhooks.patch.image.repository=ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen \
--post-renderer ./image-rewrite.py \
--timeout 30m \
--wait
参数说明:
text
monitoring
第一个 monitoring 是 Helm Release 名称。
text
--namespace monitoring
这是 Kubernetes 命名空间。
Release 名称和命名空间不是同一个概念,只是本次都取名为 monitoring。
text
--create-namespace
命名空间不存在时自动创建。
text
-f values-lab.yaml
加载本次实验环境配置。
text
--post-renderer ./image-rewrite.py
转换普通 Kubernetes 资源中的公网镜像地址。
text
--set prometheusOperator.admissionWebhooks.patch.image...
单独覆盖 Admission Webhook Hook Job 使用的镜像。
text
--timeout 30m
最长等待 30 分钟。
text
--wait
等待主要 Kubernetes 资源达到就绪状态。
首次安装出现:
text
Release "monitoring" does not exist. Installing it now.
属于正常提示,意思是 Helm 没找到已有 Release,因此执行首次安装。
十三、安装成功标志
本次最终显示:
text
STATUS: deployed
REVISION: 1
这表示:
text
Helm Release 已经成功部署
检查 Helm:
bash
helm list -n monitoring
应看到:
text
NAME NAMESPACE STATUS
monitoring monitoring deployed
查看详细状态:
bash
helm status monitoring -n monitoring
重点确认:
text
STATUS: deployed
十四、检查 Pod
bash
kubectl get pods -n monitoring -o wide
持续观察:
bash
kubectl get pods -n monitoring -w
退出持续观察:
text
Ctrl+C
主要长期运行组件应为:
text
Running
Admission Webhook 的创建和修补 Job 属于一次性任务,成功后可能显示:
text
Completed
也可能因为清理策略自动消失。
以下状态表示异常:
text
ImagePullBackOff
ErrImagePull
CrashLoopBackOff
Pending
Error
十五、检查实际运行镜像
bash
kubectl get pods -n monitoring \
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .spec.initContainers[*]}{" init: "}{.image}{"\n"}{end}{range .spec.containers[*]}{" container: "}{.image}{"\n"}{end}{end}'
主要镜像应来自:
text
m.daocloud.io
特殊 Webhook 镜像来自:
text
swr.cn-north-4.myhuaweicloud.com
十六、检查 Deployment、StatefulSet 和 DaemonSet
bash
kubectl get deployment,statefulset,daemonset -n monitoring
Deployment
主要用于:
- Grafana
- Prometheus Operator
- kube-state-metrics
特点:
text
保证指定数量的普通 Pod 正常运行
StatefulSet
主要用于:
- Prometheus
- Alertmanager
特点:
text
Pod 名称和身份稳定
适合需要稳定存储或稳定网络身份的组件
DaemonSet
主要用于:
- node-exporter
特点:
text
在每个符合调度条件的节点上运行一个 Pod
简单记忆:
text
Deployment :运行指定数量的普通 Pod
StatefulSet :运行具有稳定身份的 Pod
DaemonSet :每台符合条件的节点运行一个 Pod
十七、检查 Service
bash
kubectl get svc -n monitoring
svc 是 Service 的缩写。
下面两条命令含义相同:
bash
kubectl get svc -n monitoring
bash
kubectl get services -n monitoring
常见 Service 类型:
text
ClusterIP
只能在 Kubernetes 集群内部访问。
text
NodePort
可以通过下面的形式从集群外访问:
text
节点IP:NodePort
text
LoadBalancer
通过外部负载均衡器提供访问入口。
十八、检查 CRD
执行:
bash
kubectl get crd | grep monitoring.coreos.com
可能看到:
text
alertmanagers.monitoring.coreos.com
podmonitors.monitoring.coreos.com
prometheuses.monitoring.coreos.com
prometheusrules.monitoring.coreos.com
servicemonitors.monitoring.coreos.com
CRD 全称:
text
CustomResourceDefinition
中文可以理解为:
text
自定义资源类型定义
本次安装中,CRD 由 kube-prometheus-stack Chart 通过 Helm 安装。
不是 Prometheus Operator Pod 启动后才创建 CRD。
关系如下:
text
Helm Chart
↓ 安装 CRD
Kubernetes 认识 Prometheus、ServiceMonitor 等资源
↓
Prometheus Operator 监听这些自定义资源
↓
Operator 创建或调整 Prometheus、Alertmanager 等组件
查看自定义资源:
bash
kubectl get prometheus -A
bash
kubectl get alertmanager -A
bash
kubectl get servicemonitor -A
bash
kubectl get prometheusrule -A
十九、获取 Grafana 管理员密码
默认管理员用户名:
text
admin
获取初始密码:
bash
kubectl -n monitoring get secret monitoring-grafana \
-o jsonpath='{.data.admin-password}' \
| base64 -d
echo
也可以使用一行命令:
bash
kubectl -n monitoring get secret monitoring-grafana \
-o jsonpath='{.data.admin-password}' \
| base64 -d; echo
复制输出结果用于登录。
二十、访问 Grafana
查看 Grafana Service:
bash
kubectl get svc monitoring-grafana -n monitoring
情况一:Grafana 是 NodePort
如果看到类似:
text
80:31440/TCP
则:
text
80 是 Service 端口
31440 是 NodePort
浏览器访问:
text
http://任意节点IP:实际NodePort
必须使用命令实际查询到的 NodePort,不要直接照抄示例端口。
情况二:Grafana 是 ClusterIP
可以临时执行端口转发:
bash
kubectl -n monitoring port-forward \
svc/monitoring-grafana \
3000:80 \
--address=0.0.0.0
然后浏览器访问:
text
http://k8s-master01的IP:3000
结束端口转发:
text
Ctrl+C
二十一、修改 Grafana 管理员密码
登录 Grafana 后:
- 点击右上角用户头像。
- 打开个人资料或安全设置。
- 选择
Change password。 - 输入当前密码。
- 输入两次新密码。
- 保存修改。
以后使用:
text
用户名:admin
密码:新设置的密码
注意:
通过 Kubernetes Secret 查询的是部署时设置的初始管理员密码。
在 Grafana 页面修改密码后,新密码保存在 Grafana 自己的数据中,Kubernetes Secret 不一定同步变化。
二十二、本次失败原因记录
第一次安装最终报错:
text
Error: failed pre-install: 1 error occurred:
* timed out waiting for the condition
这只是 Helm 最终等待超时的表现。
进一步检查:
bash
kubectl get pods -n monitoring -o wide
发现:
text
monitoring-kube-prometheus-admission-create-xxxxx
ImagePullBackOff
查看事件:
bash
kubectl get events -n monitoring \
--sort-by=.lastTimestamp \
| tail -80
真正原因是:
text
403 Forbidden
失败镜像:
text
m.daocloud.io/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
改成 DaoCloud Docker Hub 路径后仍然失败:
text
m.daocloud.io/docker.io/jkroepke/kube-webhook-certgen:1.8.5
最终使用:
text
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/ghcr.io/jkroepke/kube-webhook-certgen:1.8.5
测试拉取成功后,重新安装成功:
text
STATUS: deployed
二十三、常用排查命令
查看节点
bash
kubectl get nodes -o wide
查看 Helm Release
bash
helm list -A
查看 monitoring 状态
bash
helm status monitoring -n monitoring
查看 Pod
bash
kubectl get pods -n monitoring -o wide
查看 Job
bash
kubectl get jobs -n monitoring -o wide
查看事件
bash
kubectl get events -n monitoring \
--sort-by=.lastTimestamp \
| tail -80
查看 Pod 详情
bash
kubectl describe pod <Pod名称> -n monitoring
查看 Pod 日志
bash
kubectl logs <Pod名称> \
-n monitoring \
--all-containers \
--tail=200
查看 Service
bash
kubectl get svc -n monitoring
查看 CRD
bash
kubectl get crd | grep monitoring.coreos.com
二十四、卸载
卸载 Helm Release:
bash
helm uninstall monitoring -n monitoring
删除可能残留的 Hook Job:
bash
kubectl delete job \
monitoring-kube-prometheus-admission-create \
monitoring-kube-prometheus-admission-patch \
-n monitoring \
--ignore-not-found
如需删除整个命名空间:
bash
kubectl delete namespace monitoring
注意:
CRD 是集群级资源,卸载 Release 后可能继续存在。
除非确定集群不再使用 Prometheus Operator,否则不要随意删除:
text
*.monitoring.coreos.com
二十五、最终验收
执行:
bash
helm status monitoring -n monitoring
应显示:
text
STATUS: deployed
执行:
bash
kubectl get pods -n monitoring
长期运行组件应为:
text
Running
执行:
bash
kubectl get svc monitoring-grafana -n monitoring
确认 Grafana Service 存在,并能够通过 NodePort 或端口转发访问。
满足以上条件,表示本次 kube-prometheus-stack 部署成功。