使用Helm 3在Kubernetes集群部署Prometheus和Grafana

Prometheus 社区提供了 kube-prometheus-stack helm chart,一个完整的Kubernetes manifests,包含 Grafana通用可视分析平台 dashboard,以及结合了文档和脚本的 Prometheus 规则 以方便通过 Prometheus Operator

备注

kube-prometheus runbooks 是社区提供的排查运行手册,非常适合学习案例以及排查问题参考

备注

SysEleven: Kube-Prometheus-Stack 提供了一个快速配置的精要手册,可以参考学习

helm3

  • helm 提供方便部署:

使用官方脚本安装 helm
curl -LO https://git.io/get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh

安装Prometheus 和 Grafana

  • 添加 Prometheus 社区helm chart:

添加 Prometheus 社区helm chart
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

备注

参考 在Kuternetes集成GPU可观测能力 可以看到NVIDIA文档中对 helm 部署社区 prometheus-community/kube-prometheus-stack 做了一些定制修改,方法值得参考。后续我部署会做一些改进,例如:

  • 传递 --namespace prometheus 指定部署到 prometheus 名字空间

  • 通过 --values /tmp/kube-prometheus-stack.values 添加定制的 additionalScrapeConfigs

不过,即使已经部署好的集群,也可以通过 更新Kubernetes集群的Prometheus配置 修订

  • 安装:

使用helm install安装prometheus
helm install stable prometheus-community/kube-prometheus-stack --debug

如果一切正常,最后会输出:

使用helm install安装prometheus最后输出信息
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace default get pods -l "release=stable"

Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.
  • 检查:

检查部署完成的Prometheus Pods
kubectl --namespace default get pods

输出信息:

检查部署完成的Prometheus Pods可以看到每个节点都运行了 node-exporter 且已经运行起 Prometheus和Grafana
NAME                                                  READY   STATUS    RESTARTS   AGE
...
prometheus-stable-kube-prometheus-sta-prometheus-0       2/2     Running             0          11m
stable-grafana-6449bcb69b-rqhwz                          3/3     Running             0          42m
stable-kube-prometheus-sta-operator-f976f557d-bssn8      1/1     Running             0          42m
stable-kube-state-metrics-6cf78f5c5b-2cvrx               1/1     Running             0          42m
stable-prometheus-node-exporter-499cb                    1/1     Running             0          42m
stable-prometheus-node-exporter-4mmph                    1/1     Running             0          42m
stable-prometheus-node-exporter-4sb22                    1/1     Running             0          42m
...

排查和解决

实际上通过社区helm chart部署还是有一些困难的,这个困难不是社区的helm chart问题,而是GFW阻塞了镜像下载。

当你发现 helm list 显示 failed 时候,请使用 kubectl get pods XXXX -o yaml 检查错误原因,你可能会看到类似:

...
  containerStatuses:
  - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6
    imageID: ""
    lastState: {}
    name: create
    ready: false
    restartCount: 0
    started: false
    state:
      waiting:
        message: Back-off pulling image "registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20221220-controller-v1.5.1-58-g787ea74b6"
        reason: ImagePullBackOff

这种情况下,最好的解决方法是使用私有Registry: 通过翻墙将镜像 docker pull 下来,然后 docker push 到私有Registry中,然后修订 helm 部署的 deployments ,改成私有仓库镜像。

不过,还有一种方式(假如不方便使用Registry),就是在墙外使用 Docker Atlas ,然后在墙内将打包好的镜像搬运进来,再通过 nerdctlnerdctl load -i 加载到集群节点来完成部署。

服务输出

  • 检查 svc :

检查部署完成的服务 kubectl get svc
kubectl get svc

输出显示:

kubectl get svc 输出显示当前服务都是使用Cluster IP,也就是无法直接外部访问
NAME                                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
alertmanager-operated                     ClusterIP      None            <none>        9093/TCP,9094/TCP,9094/UDP   24h
kubernetes                                ClusterIP      10.233.0.1      <none>        443/TCP                      5d8h
prometheus-operated                       ClusterIP      None            <none>        9090/TCP                     24h
stable-grafana                            ClusterIP      10.233.19.177   <none>        80/TCP                       24h
stable-kube-prometheus-sta-alertmanager   ClusterIP      10.233.20.3     <none>        9093/TCP                     24h
stable-kube-prometheus-sta-operator       ClusterIP      10.233.13.186   <none>        443/TCP                      24h
stable-kube-prometheus-sta-prometheus     ClusterIP      10.233.30.214   <none>        9090/TCP                     24h
stable-kube-state-metrics                 ClusterIP      10.233.13.91    <none>        8080/TCP                     24h
stable-prometheus-node-exporter           ClusterIP      10.233.32.207   <none>        9100/TCP                     24h

默认情况下, prometheusgrafana 服务都是使用ClusterIP在集群内部,所以要能够在外部访问,需要使用 Kubernetes集群的Load Balancer和Ingress辨析 或者 NodePort (简单)

  • 修改 stable-kube-prometheus-sta-prometheus 服务和 stable-grafana 服务,将 typeClusterIP 修改为 NodePort 或者 LoadBalancer

kubectl edit svc 将ClusterIP类型改为NodePort或LoadBalancer(案例是 grafana )
kubectl edit svc stable-grafana

我在阿里云环境部署采用 LoadBalancer 似乎没有成功, kubectl get svc 一直显示外部IP pending

NAME                                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
...
stable-grafana                            LoadBalancer   10.233.19.177   <pending>     80:31365/TCP                 25h

所以我最终改为 NodePort 来绕过这个问题:

NAME                                      TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
...
stable-grafana                            NodePort       10.233.19.177   <none>        80:31365/TCP                 25h
stable-kube-prometheus-sta-alertmanager   NodePort       10.233.20.3     <none>        9093:32457/TCP               25h
stable-kube-prometheus-sta-prometheus     NodePort       10.233.30.214   <none>        9090:30536/TCP               25h

此时在调度上述3个pod的物理主机上执行 netstat -an 可以看到对外监听的服务端口:

tcp        0      0 0.0.0.0:31365           0.0.0.0:*               LISTEN
...
tcp        0      0 0.0.0.0:32457           0.0.0.0:*               LISTEN
...
tcp        0      0 0.0.0.0:30536           0.0.0.0:*               LISTEN

不过,这样外部访问的端口是随机的,有点麻烦。临时性解决方法,我采用 Nginx反向代理 将对外端口固定住,然后反向转发给 NodePort 的随机端口,至少能临时使用。

备注

我在采用 Nginx反向代理 到Grafana时遇到 在反向代理后面运行Grafana 问题,原因是Grafana新版本为了阻断跨站攻击,对客户端请求源和返回地址进行校验,所以必须对 Nginx 设置代理头部

访问使用

访问 Grafana 面板,初始账号 admin 密码是 prom-operator ,请立即修改

然后我们可以开始 Grafana配置快速起步

检查

使用 helm 可以见擦好所有安装的对象:

获取 kube-prometheus-stack 安装的对象
helm --namespace prometheus get manifest kube-prometheus-stack-1681228346 | kubectl get -f -

输出类似:

获取 kube-prometheus-stack 安装的对象内容输出
NAME                                                                       SECRETS   AGE
serviceaccount/kube-prometheus-stack-1681228346-grafana                    1         56d
serviceaccount/kube-prometheus-stack-1681228346-kube-state-metrics         1         56d
serviceaccount/kube-prometheus-stack-1681228346-prometheus-node-exporter   1         56d
serviceaccount/kube-prometheus-stack-1681-alertmanager                     1         56d
serviceaccount/kube-prometheus-stack-1681-operator                         1         56d
serviceaccount/kube-prometheus-stack-1681-prometheus                       1         56d

NAME                                                          TYPE     DATA   AGE
secret/kube-prometheus-stack-1681228346-grafana               Opaque   3      56d
secret/alertmanager-kube-prometheus-stack-1681-alertmanager   Opaque   1      56d
secret/kube-prometheus-stack-1681-prometheus-scrape-confg     Opaque   1      56d

NAME                                                                     DATA   AGE
configmap/kube-prometheus-stack-1681228346-grafana-config-dashboards     1      56d
configmap/kube-prometheus-stack-1681228346-grafana                       1      56d
configmap/kube-prometheus-stack-1681-grafana-datasource                  1      56d
configmap/kube-prometheus-stack-1681-alertmanager-overview               1      56d
configmap/kube-prometheus-stack-1681-apiserver                           1      56d
configmap/kube-prometheus-stack-1681-cluster-total                       1      56d
...

参考