Operator 部署Prometheus

安装说明

kube-prometheus

  • https://prometheus-operator.dev/docs/
  • https://github.com/prometheus-operator/kube-prometheus

该存储库收集 Kubernetes 清单、Grafana仪表板和Prometheus 规则以及文档和脚本,以使用 Prometheus Operator 通过Prometheus提供易于操作的端到端 Kubernetes 集群监控。
该项目的内容是用jsonnet编写的。该项目既可以被描述为一个包,也可以被描述为一个库。

该软件包中包含的组件:

  • The Prometheus Operator
  • Highly available Prometheus
  • Highly available Alertmanager
  • Prometheus node-exporter
  • Prometheus blackbox-exporter
  • Prometheus Adapter for Kubernetes Metrics APIs
  • kube-state-metrics
  • Grafana

该堆栈用于集群监控,因此它被预先配置为从所有 Kubernetes 组件收集指标。除此之外,它还提供一组默认的仪表板和警报规则。许多有用的仪表板和警报都来自kubernetes-mixin 项目,与该项目类似,它提供可组合的 jsonnet 作为库,供用户根据自己的需求进行自定义。

先决条件

Prometheus Operator 的版本>=0.39.0需要 版本 的 Kubernetes 集群>=1.16.0。如果您刚刚开始使用 Prometheus Operator,强烈建议使用最新版本。

如果您运行的是旧版本的 Kubernetes 和 Prometheus Operator,我们建议先升级 Kubernetes,然后再升级 Prometheus Operator。

兼容性

以下 Kubernetes 版本受支持,并且在我们在各自分支中针对这些版本进行测试时可以正常工作。但请注意,其他版本也可能有效!

kube-prometheus stack Kubernetes 1.22 Kubernetes 1.23 Kubernetes 1.24 Kubernetes 1.25 Kubernetes 1.26 Kubernetes 1.27 Kubernetes 1.28
release-0.10 x x x
release-0.11 x x x
release-0.12 x x x
release-0.13 x
main x x

部署 Operator

注意:对于 Kubernetes v1.21.z 之前的版本,请参考Kubernetes 兼容性矩阵以选择兼容的分支。

创建需要的命名空间和 CRDs

首先 clone 项目代码,我们这里直接使用默认的 main 分支即可:

git clone https://github.com/prometheus-operator/kube-prometheus.git
cd kube-prometheus

使用manifests目录中的配置创建监控堆栈:

# Create the namespace and CRDs, and then wait for them to be available before creating the remaining resources
# Note that due to some CRD size we are using kubectl server-side apply feature which is generally available since kubernetes 1.22.
# If you are using previous kubernetes versions this feature may not be available and you would need to use kubectl create instead.
kubectl apply --server-side -f manifests/setup

安装 Operator 控制器

当我们声明完 CRD 过后,就可以来自定义资源清单了,但是要让我们声明的自定义资源对象生效就需要安装对应的 Operator 控制器,在 manifests 目录下面就包含了 Operator 的资源清单以及各种监控对象声明,比如 Prometheus、Alertmanager 等,直接应用即可:

# 进入Operator 资源清单目录
cd kube-prometheus/manifests

# 新建对应的服务目录
mkdir -p operator node-exporter alertmanager grafana kube-state-metrics blackbox_exporter prometheus prometheusRules serviceMonitor adapter service

# 把对应的服务配置文件移动到相应的服务目录
mv prometheus-* prometheus/
mv prometheusOperator* operator/
mv grafana-* grafana/
mv prometheusAdapter-* adapter/
mv *-serviceMonitor* serviceMonitor/
mv kubeStateMetrics-* kube-state-metrics/
mv alertmanager-* alertmanager/
mv nodeExporter-* node-exporter/
mv blackboxExporter-* blackbox_exporter/
find . -name "*Rule.yaml" -exec mv {
   } ./prometheusRules/ \;

# 新创建了两个目录,存放钉钉配置和其它配置
mkdir other dingtalk-hook
kubectl wait \
	--for condition=Established \
	--all CustomResourceDefinition \
	--namespace=monitoring
	
kubectl apply -f operator/

这会创建一个名为 monitoring 的命名空间,以及相关的 CRD 资源对象声明,以避免部署监控组件时的竞争条件。

查看是否正常部署

$ kubectl -n monitoring get pod

NAME                                   READY   STATUS    RESTARTS   AGE
prometheus-operator-586f75fb74-hzj24   2/2     Running   0          82s

查看是否正常部署自定义资源定义(CRD)

$ kubectl get crd -n monitoring

NAME                                    CREATED AT
alertmanagers.monitoring.coreos.com     2019-04-16T06:22:20Z
prometheuses.monitoring.coreos.com      2019-04-16T06:22:20Z
prometheusrules.monitoring.coreos.com   2019-04-16T06:22:20Z
servicemonitors.monitoring.coreos.com   2019-04-16T06:22:21Z

部署服务

需要注意有一些资源的镜像来自于 k8s.gcr.io,如果不能正常拉取,则可以将镜像替换成可拉取的。

  • prometheusAdapter-deployment.yaml
  • kubeStateMetrics-deployment.yaml

替换Docker镜像加速地址

sed -i 's/registry.k8s.io/k8s.m.daocloud.io/g'  adapter/prometheusAdapter-deployment.yaml
sed -i 's/registry.k8s.io/k8s.m.daocloud.io/g'  kube-state-metrics/kubeStateMetrics-deployment.yaml
sed -i 's/quay.io/quay.m.daocloud.io/g'  kube-state-metrics/kubeStateMetrics-deployment.yaml

部署整套CRD

kubectl apply -f prometheus/
kubectl apply -f grafana/
kubectl apply -f adapter/
kubectl apply -f alertmanager/
kubectl apply -f node-exporter/
kubectl apply -f kube-state-metrics/
kubectl apply -f serviceMonitor/
kubectl apply -f blackbox_exporter/
kubectl apply -f prometheusRules/

这会自动安装 prometheus-operator、node-exporter、kube-state-metrics、grafana、prometheus-adapter 以及 prometheus 和 alertmanager 等大量组件,如果没成功可以多次执行上面的安装命令。

检查是否正常部署

$ kubectl get pods -n monitoring
NAME                                   READY   STATUS    RESTARTS   AGE
alertmanager-main-0                    2/2     Running   0          73m
alertmanager-main-1                    2/2     Running   0          73m
alertmanager-main-2                    2/2     Running   0          73m
blackbox-exporter-d46f55658-jjrjf      3/3     Running   0          72m
grafana-55dfb44658-gjhvw               1/1     Running   0          73m
kube-state-metrics-54b8f57bc9-wkcr2    3/3     Running   0          36m
node-exporter-267nz                    2/2     Running   0          73m
node-exporter-6bfhs                    2/2     Running   0          73m
node-exporter-9t4lj                    2/2     Running   0          73m
node-exporter-nd5gh                    2/2     Running   0          73m
prometheus-adapter-6f5fc7b689-24dph    1/1     Running   0          36m
prometheus-adapter-6f5fc7b689-ngcgn    1/1     Running   0          36m
prometheus-k8s-0                       2/2     Running   0          73m
prometheus-k8s-1                       2/2     Running   0          73m
prometheus-operator-586f75fb74-hzj24   2/2     Running   0          85m
$ kubectl get svc -o wide -n monitoring
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE     SELECTOR
alertmanager-main       ClusterIP   10.247.60.19             9093/TCP,8080/TCP            3m56s   app.kubernetes.io/component=alert-router,app.kubernetes.io/instance=main,app.kubernetes.io/name=alertmanager,app.kubernetes.io/part-of=kube-prometheus
alertmanager-operated   ClusterIP   None                     9093/TCP,9094/TCP,9094/UDP   3m56s   app.kubernetes.io/name=alertmanager
blackbox-exporter       ClusterIP   10.247.22.106            9115/TCP,19115/TCP           3m54s   app.kubernetes.io/component=exporter,app.kubernetes.io/name=blackbox-exporter,app.kubernetes.io/part-of=kube-prometheus
grafana                 ClusterIP   10.247.27.27             3000/TCP                     3m57s   app.kubernetes.io/component=grafana,app.kubernetes.io/name=grafana,app.kubernetes.io/part-of=kube-prometheus
kube-state-metrics      ClusterIP   None                     8443/TCP,9443/TCP            3m55s   app.kubernetes.io/component=exporter,app.kubernetes.io/name=kube-state-metrics,app.kubernetes.io/part-of=kube-prometheus
node-exporter           ClusterIP   None                     9100/TCP                     3m56s   app.kubernetes.io/component=exporter,app.kubernetes.io/name=node-exporter,app.kubernetes.io/part-of=kube-prometheus
prometheus-adapter      ClusterIP   10.247.207.100           443/TCP                      3m57s   app.kubernetes.io/component=metrics-adapter,app.kubernetes.io/name=prometheus-adapter,app.kubernetes.io/part-of=kube-prometheus
prometheus-k8s          ClusterIP   10.247.87.202            9090/TCP,8080/TCP            4m1s    app.kubernetes.io/component=prometheus,app.kubernetes.io/instance=k8s,app.kubernetes.io/name=prometheus,app.kubernetes.io/part-of=kube-prometheus
prometheus-operated     ClusterIP   None                     9090/TCP                     4m1s    app.kubernetes.io/name=prometheus
prometheus-operator     ClusterIP   None                     8443/TCP                     15m     app.kubernetes.io/component=controller,app.kubernetes.io/name=prometheus-operator,app.kubernetes.io/part-of=kube-prometheus

访问 prometheus UI

如果我们想要在外网访问这两个服务的话,可以通过创建对应的 Ingress 对象或者使用 NodePort 类型的 Service,我们这里为了简单,直接使用 NodePort 类型的服务即可,编辑 grafana、alertmanager-main 和 prometheus-k8s 这 3 个 Service,将服务类型更改为 NodePort:

# 将 type: ClusterIP 更改为 type: NodePort
$ kubectl edit svc grafana -n monitoring
$ kubectl edit svc alertmanager-main -n monitoring
$ kubectl edit svc prometheus-k8s -n monitoring
$ kubectl get svc -n monitoring
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
alertmanager-main       NodePort    10.102.174.254           9093:32660/TCP,8080:31615/TCP   49m
grafana                 NodePort    10.105.33.193            3000:31837/TCP                  49m
prometheus-k8s          NodePort    10.109.250.233           9090:31664/TCP,8080:31756/TCP   49m
......

更改完成后,我们就可以通过上面的 NodePort 去访问对应的服务了,比如查看 prometheus 的服务发现页面:
Operator 部署Prometheus_第1张图片

可以看到已经监控上了很多指标数据了,上面我们可以看到 Prometheus 是两个副本,我们这里通过 Service 去访问,按正常来说请求是会去轮询访问后端的两个 Prometheus 实例的,但实际上我们这里访问的时候始终是路由到后端的一个实例上去,因为这里的 Service 在创建的时候添加了 sessionAffinity: ClientIP 这样的属性,会根据 ClientIP 来做 session 亲和性,所以我们不用担心请求会到不同的副本上去:
https://kubernetes.renkeju.com/chapter_6/6.2.3.Service_session_stickiness.html

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: prometheus
    app.kubernetes.io/instance: k8s
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 2.52.0
  name: prometheus-k8s
  namespace: monitoring
spec:
  ports:
    - name: web
      port: 9090
      targetPort: web
    - name: reloader-web
      port: 8080
      targetPort: reloader-web
  type: NodePort
  selector:
    app.kubernetes.io/component: prometheus
    app.kubernetes.io/instance: k8s
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: kube-prometheus
  sessionAffinity: ClientIP

为什么会担心请求会到不同的副本上去呢?正常多副本应该是看成高可用的常用方案,理论上来说不同副本本地的数据是一致的,但是需要注意的是 Prometheus 的主动 Pull 拉取监控指标的方式,由于抓取时间不能完全一致,即使一致也不一定就能保证网络没什么问题,所以最终不同副本下存储的数据很大可能是不一样的,所以这里我们配置了 session 亲和性,可以保证我们在访问数据的时候始终是一致的。

卸载Stack

如果要清理 Prometheus-Operator,可以直接删除对应的资源清单即可:

kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup

Prometheus 配置

数据持久化

上面我们在修改完权限的时候,重启了 Prometheus 的 Pod,如果我们仔细观察的话会发现我们之前采集的数据已经没有了,这是因为我们通过 prometheus 这个 CRD 创建的 Prometheus 并没有做数据的持久化。

我们可以直接查看生成的 Prometheus Pod 的挂载情况就清楚了:

$ kubectl get pod prometheus-k8s-0 -n monitoring -o yaml
......
    volumeMounts:
    - mountPath: /etc/prometheus/config_out
      name: config-out
      readOnly: true
    - mountPath: /etc/prometheus/certs
      name: tls-assets
      readOnly: true
    - mountPath: /prometheus
      name: prometheus-k8s-db
......
  volumes:
......
  - emptyDir: {
   }
    name: prometheus-k8s-db
......
  • 如果未指定存储选项,Prometheus 的数据目录 /prometheus 默认情况下将使用EmptyDir 。
  • 如果指定了多个存储选项,则优先级如下: 1. emptyDir 2. ephemeral 3. volumeClaimTemplate
创建一个 StorageClass 对象:

emptyDir 挂载的数据的生命周期和 Pod 生命周期一致的,如果 Pod 挂掉了,数据也就丢失了,对应线上的监控数据肯定需要做数据的持久化的,由于我们的 Prometheus 最终是通过 Statefulset 控制器进行部署的,所以我们这里需要通过 storageclass 来做数据持久化。

$ cat prometheus-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: prometheus-data-db
provisioner: fuseim.pri/ifs
$ kubectl create -f prometheus-storageclass.yaml
storageclass.storage.k8s.io "prometheus-data-db" created
配置 CRD 资源对象中 storage 属性

然后在 prometheus 的 CRD 资源对象中通过 storage 属性配置 volumeClaimTemplate 对象即可,更多配置项见API reference。

# vim prometheus/prometheus-prometheus.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
......
  replicas: 2
  storage:
    volumeClaimTemplate:
      metadata:
        name: prometheus-data-db
      spec:
        storageClassName: prometheus-data-db
        resources:
          requests:
            storage: 50Gi

然后更新 prometheus 这个 CRD 资源,更新完成后会自动生成两个 PVC 和 PV 资源对象:

$ kubectl apply -f prometheus-prometheus.yaml
prometheus.monitoring.coreos.com/k8s configured

$ kubectl get pvc -n monitoring
NAME                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
prometheus-k8s-db-prometheus-k8s-0   Bound    pvc-4c67d0a9-e97c-4820-9c66-340a7da3c53f   20Gi       RWO            local-path     4s
prometheus-k8s-db-prometheus-k8s-1   Bound    pvc-6f26e85c-01c6-483c-9d42-55166f77e5d0   20Gi       RWO            local-path     4s

$ kubectl get pv |grep monitoring
pvc-4c67d0a9-e97c-4820-9c66-340a7da3c53f   20Gi       RWO            Delete           Bound    monitoring/prometheus-k8s-db-prometheus-k8s-0                       local-path               17s
pvc-6f26e85c-01c6-483c-9d42-55166f77e5d0   20Gi       RWO            Delete           Bound    monitoring/prometheus-k8s-db-prometheus-k8s-1                       local-path      
         17s

现在即使我们的 Pod 挂掉了,数据也不会丢失了。

自动发现配置​

如果在我们的 Kubernetes 集群中有了很多的 Service/Pod,那么我们都需要一个一个的去建立一个对应的 ServiceMonitor 或 PodMonitor 对象来进行监控吗?这样岂不是又变得麻烦起来了?

为解决上面的问题,Prometheus Operator 为我们提供了一个额外的抓取配置来解决这个问题,我们可以通过添加额外的配置来进行服务发现进行自动监控。

Service服务监控指标采集

我们可以在 Prometheus Operator 当中去自动发现并监控具有 prometheus.io/scrape=true 这个 annotations 的 Service加入到endpoints这个target中,否则就会被删除。之前我们定义的 Prometheus 的配置如下:

$ vim ./prometheus/prometheus-additional.yaml
- job_name: 'kubernetes-nodes'
  kubernetes_sd_configs:
    - role: node
  scheme: https
  tls_config:
    insecure_skip_verify: true
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
  relabel_configs:
    - source_labels: [__address__]
      target_label: __address__
      regex: "(.*):10250"

你可能感兴趣的:(日志监控,Operator,prometheus,grafana)