k8s 监控(一)安装 Prometheus

11,493 阅读13分钟

本文属于 k8s 监控系列,其余文章为:

  1. k8s 监控(二)监控集群组件和 pod
  2. k8s 监控(三)prometheus-adapter
  3. k8s 监控(四)监控宿主机

k8s 监控我们要完成以下几点:

  • 监控 master/node 本身;
  • 监控集群组件 apiServer、etcd 等;
  • 监控需要关注的 pod;
  • 自定义的监控,包括 jmx 等。

有了这些监控指标之后,我们还需要做到以下几点:

  1. 制定相应的告警规则;
  2. 提供对应的 webhook 发出告警;
  3. 部署 grafana 进行图形展示;
  4. 监控相关组件的高可用;
  5. 和 k8s metrics-server 进行结合。

目前而言,k8s 的监控业界公认的标准就是使用 Prometheus,Prometheus 也能很好的完成 k8s 的监控工作。只不过如果使用原生 Prometheus 进行监控的话,还要完成上述操作,需要做的工作非常多,需要对 k8s 以及 Prometheus 本身有一定的理解。

为什么不使用 prometheus-operator

为了方便操作,coreos 提供了 prometheus-operator 这样一个产品,它包装了 Prometheus,并且还提供了四个自定义的 k8s 类型(CustomResourceDefinitions),让你通过定义 manifest 的方式还完成新监控(job)以及告警规则的添加,而无需手动操作 Prometheus 的配置文件,让整个过程更 k8s。

并且在此基础之上,coreos 还有推出了 kube-prometheus 这样的升级版,它在 prometheus-operator 的基础之上高可用了 Prometheus 和 Alertmanager,提供了 node-exporter 用于宿主机的监控,还有 Kubernetes Metrics APIs 的 Prometheus 适配器和 grafana,让你实现一键部署。

老外喜欢这么搞,是不是一定合适我不知道,但是肯定是存在问题的,毕竟这个 prometheus-operator 依然处于 bate 状态。并且它里面多出的很多组件都只是为了避免让你直接操作配置文件,而这些组件都是额外的消耗。

同时也是因为你不能直接操纵配置文件,所以一旦你想修改配置文件就非常困难了,因为配置文件是自动生成的,一旦你想要修改它的 relabel_config 配置,你只能在它生成的规则后面添加。

这样会出现一种情况,就是你可能想删掉它为你自动生成的标签,但是这个标签本来就没有,是它为你生成的,但是生成之后你又想删除,这样就平白多了两台规则。并且一旦你配置定义错了,因为是 prometheus-operator 帮你 reload 的,因此就算有错误你也收不到。

如果你只是简单使用的话可以直接使用 kube-prometheus。但是只要你想要了解其中的原理部分,或者有自己定制化的需求,那就搞原生的吧,所有 prometheus-operator 能够实现的,原生都能实现。

怎么做

本文会从 0 开始,一点一点完成一开始的监控需求。即使你还是想用 kube-prometheus,等你看完我的所有文章之后,你使用起来也就没有丝毫的障碍了。

我们要做的就是将 Prometheus 镜像部署到 k8s 中,然后使用 kubernetes_sd_config 对 k8s 进行完成监控。当然,prometheus-operator 也是这么做的。

虽然 Prometheus 可以做到对 k8s 集群中所有 pod 的发现,但是 pod 的 ip 会随时改变,而且你进行所有 pod 的发现让你无从对它们进行分类管理,这样就会非常乱。

因此,我这里会和 prometheus-operator 一样,只对 endpoint 进行发现。因为创建 service 就会创建对应的 endpoint,所以我们完全可以通过 service 对 pod 进行分类,然后针对一类 pod 我们使用一个 Prometheus 的 job,这样就非常简洁明了了。

文章中所有的文件我都已上传到 GitHub,你可以直接 clone 下来,而不需要频繁的复制粘贴。

本文中 k8s 版本为 1.14.2,采用 kubeadm 安装。此外,本文不会对 Prometheus 进行过多的介绍,也就是说你需要有一定的 Prometheus 基础。

查询 kubelet 指标页面

大家应该清楚,应用如果想要被 Prometheus 监控,就应该提供一个 url,一旦访问这个 url,那么所有监控项就会以文本的形式一行行打印出来,Prometheus 就通过访问这个 url 来获得所有的监控数据,这个 uri 默认为 http[s]://IP:PORT/metrics

因为 Prometheus 已经成为了一个标准,因此 k8s 的所有组件都提供了 /metrics 这个 url。对于一些主机层面或者没有提供这个 url 应用的监控,可以使用一个中间产品,这个产品收集应用相关的监控指标,然后提供这个 url,让 Prometheus 进行采集。

这种产品称为 XXX_exporter,比如 node_exporter、jmx_exporter 等,官方收录了很多的 exporter,有官方和非官方的,你也可以通过它们提供的客户端库自己实现一个。

既然 Prometheus 能够通过 http 收集,那通过 curl 一样也行。因此在使用 Prometheus 收集之前,我会使用 curl 命令将所有要收集的指标数据先输出出来,以便大家心中有数。

当然,因为是在 k8s 环境,监控指标在收取之后会附加上一些标签,比如它所在的名称空间、所属的 service、pod 名称,以及 ip 端口等,这些标签你也可以选择加还是不加。

话不多说,我们先看看 kubelet 的指标数据。先创建一个目录,用于存放后续所有的 manifest 文件:

mkdir -p /opt/kube/prometheus

首先创建一个名称空间,所有监控相关的资源都放在这个名称空间之下:

# vim 00namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring

# kubectl apply -f 00namespace.yml

我们知道,pod 都是由 kubelet 创建的,因此 pod 的相关指标(包括使用的 cpu、内存、流量等)是由 kubelet 提供的,我们现在就可以访问 kubelet 的指标页面,看看有哪些指标数据。

作为一个守护进程,kubelet 默认监听 10250 端口,因此可以在 master 或者 node 上直接访问:

# curl https://127.0.0.1:10250/metrics/cadvisor -k
Unauthorized

其中:

  • 必须使用 https;
  • metrics/cadvisor 是 kubelet pod 相关的监控指标,它还有一个 metrics,这是 kubelet 自身的监控指标;
  • -k 表示不验证 kubelet 证书,因为整个集群都是使用自签署证书,因此没必要验证;

上面提示我们没有认证,看不到指标数据。认证很简单,使用 token 即可,那么我们首先要创建这个 token。大家应该清楚,当我们创建一个 serviceAccount 之后,k8s 会自动为其生成一个 secret,这个 secret 中就有 token 信息。

因此我们需要创建了一个 clusterRole,并创建一个 clusterrolebinding 将权限绑定到一个 serviceAccount 上,那么我们就拿到了这个权限的 token 了。

那我们需要创建 prometheus-clusterRole.ymlprometheus-clusterRoleBinding.ymlprometheus-serviceAccount.yml 这三个文件,它们的内容如下。

prometheus-clusterRole.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-k8s
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/metrics
    verbs:
      - get
  - nonResourceURLs:
      - /metrics
    verbs:
      - get

prometheus-clusterRoleBinding.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus-k8s
subjects:
  - kind: ServiceAccount
    name: prometheus-k8s
    namespace: monitoring

prometheus-serviceAccount.yml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus-k8s
  namespace: monitoring

这样我们就创建了一个 ServiceAccount,名为 prometheus-k8s,这个 ServiceAccount 不仅现在可以用来获取 kubelet 的监控指标,后续 Prometheus 也会使用这个 serviceAccount 启动。

kubectl apply -f prometheus-clusterRole.yml
kubectl apply -f prometheus-clusterRoleBinding.yml
kubectl apply -f prometheus-serviceAccount.yml

创建完成后,会自动在生成一个 secret,里面包含了 token:

# kubectl -n monitoring get secret
NAME                         TYPE                                  DATA   AGE
prometheus-k8s-token-xmkd4   kubernetes.io/service-account-token   3      3h26m

获取 token:

token=`kubectl -n monitoring get secret prometheus-k8s-token-xmkd4 -o jsonpath={.data.token} | base64 -d`

然后使用这个 token 访问 kubelet 的指标页面:

curl https://127.0.0.1:10250/metrics/cadvisor -k -H "Authorization: Bearer $token"

只需要将这个 token 放到请求头中就行,然后就可以看到所有的监控指标了。

可以看到里面有很多这样的标签的指标存在:

{container="",container_name="",id="/system.slice/tuned.service",image="",name="",namespace="",pod="",pod_name="",state="stopped"}

我完全没有搞懂这些是干啥的,不知道有没有用,反正我是准备全删除的。使用 Prometheus 就是有这样的问题,什么样的指标数据都有,恨不得把所有的都暴露出来,如果你是默认使用而没有管里面到底有什么指标数据的话,你可能接收了几倍的无用数据(对于很多人来讲,确实是没用的,因为从来都不会关注),造成了大量的资源浪费。

kubelet 除了 /metrics/cadvisor 这个 url 之外,还有一个 /metrics,这是它本身的监控指标而非 pod 的。说实话,里面的数据我都看不懂,我在考虑要不要接收。

通过这种方式,其他几个 k8s 组件你应该都能够访问了,但是 etcd 不行,它需要验证客户端证书。

查询 etcd 指标页面

etcd 的指标页面的 url 也是 /metrics,但是你想要访问它需要提供证书,因为它会验证客户端证书。当然你可以在它的启动参数中通过 --listen-metrics-urls http://ip:port 让监控指标页使用 http 而非 https,这样就不用提供证书了。

etcd 虽然部署在容器中,但是由于使用了 hostNetwork,所以我们可以通过直接访问 master 的 2379 端口访问它。默认它会采用了 https,因此我们需要提供它的 peer 证书。如果 k8s 是使用 kubeadm 安装的,etcd 的证书在 /etc/kubernetes/pki/etcd/ 目录下。

因此访问 etcd 的命令为:

curl https://127.0.0.1:2379/metrics --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/healthcheck-client.crt --key /etc/kubernetes/pki/etcd/healthcheck-client.key

后面我们需要将这三个文件挂载到 Prometheus 容器中,以便它能收集 etcd 监控数据。

安装 Prometheus

Prometheus 本身会依赖一些东西,因此在安装之前我们必须做一些准备工作。

我们先创建两个 configmap,一个是 Prometheus 的配置文件,另一个是告警的规则文件。配置文件一定要使用 configmap 进行保存,不能直接放在容器中,不然容器挂了配置文件就没了。

Prometheus 配置文件

先创建 Prometheus 配置文件 configmap prometheus-config.yml,它的内容如下:

apiVersion: v1
data:
  prometheus.yml: |
    global:
      evaluation_interval: 30s
      scrape_interval: 30s
      external_labels:
        prometheus: monitoring/k8s
    rule_files:
    - /etc/prometheus/rules/*.yml
    scrape_configs:
    - job_name: prometheus
      honor_labels: false
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names:
          - monitoring
      scrape_interval: 30s
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_prometheus
        regex: k8s
      - source_labels:
        - __meta_kubernetes_endpoint_address_target_kind
        - __meta_kubernetes_endpoint_address_target_name
        separator: ;
        regex: Pod;(.*)
        replacement: ${1}
        target_label: pod
      - source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - source_labels:
        - __meta_kubernetes_service_name
        target_label: service
      - source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - source_labels:
        - __meta_kubernetes_service_name
        target_label: job
        replacement: ${1}
      - target_label: endpoint
        replacement: web
kind: ConfigMap
metadata:
  name: prometheus
  namespace: monitoring

简单的说明下这个配置文件的内容:这个配置文件只是一个初版,可以看到里面只有一个 job,就是监控 Prometheus 本身。可以看到,这里使用了 kubernetes_sd_configs,使用这个配置可以自动发现 k8s 中 node、service、pod、endpoint、ingress,并为其添加监控,更多的内容可以直接查看官方文档

这里使用的是 endpoint 的方式对 Prometheus 本身进行发现,你可以有疑问了,为什么不直接对自身的 127.0.0.1:9090 进行采集呢?因为考虑到 Prometheus 可能会有多台,这样即使有多台,它们也都在一个 job 下面。

当然,你如果嫌麻烦也可以直接对自身进行采集,没有任何问题。然后下面就是一堆的 relabel_configs 配置了,我一个个解释这些配置是干啥的。

首先看第一个配置:

- action: keep
  source_labels:
    - __meta_kubernetes_service_label_prometheus
  regex: k8s

大家应该知道,每创建一个 service 就会创建一个对应的 endpoint,但是 prometheus 的 endpoint 的发现会对 k8s 指定名称空间下所有 endpoint 进行发现,那么怎么保证 Prometheus 只发现我们需要的 endpoint 呢?答案是通过 relabel_configs,这里 keep 就是干这个的。

上面配置的意思是只有 service 的标签包含 prometheus=k8s,k8s 才会对其对应的 endpoint 进行采集。所以我们后面要为 Prometheus 创建一个 service,并且要为这个 service 加上 prometheus: k8s 这样的标签。

这里没有指定 url,Prometheus 会采集默认的 url /metrics

接着看下一段配置:

- source_labels:
    - __meta_kubernetes_endpoint_address_target_kind
    - __meta_kubernetes_endpoint_address_target_name
  separator: ;
  regex: Pod;(.*)
  replacement: ${1}
  target_label: pod

如果 __meta_kubernetes_endpoint_address_target_kind 的值为 Pod,__meta_kubernetes_endpoint_address_target_name 的值为 prometheus-0,在它们之间加上一个 ; 之后,它们合起来就是 Pod;prometheus-0。使用正则表达式 Pod;(.*) 对其进行匹配,那么 ${1} 就是取第一个分组,它值就是 prometheus-0,最后将这个值交给 pod 这个标签。

因此这一段配置就是为所有采集到的监控指标增加一个 pod=prometheus-0 的标签。

如果 __meta_kubernetes_endpoint_address_target_kind 的值不是 Pod,那么不会添加任何标签。

后面的配置我想就不用多说了,无非就是将指定的元标签转换为指定的标签,因为不转换的话,元标签会在 relabel 之后都会被干掉。

创建它:

kubectl apply -f prometheus-config.yml

Prometheus 规则文件

我们目前不需要任何规则文件,但是由于会将对应 configmap 挂载进容器中,所以我们创建一个空的规则文件。

先创建一个 prometheus-config-rulefiles.yml 文件,它的内容如下:

apiVersion: v1
data:
  k8s.yml: ""
kind: ConfigMap
metadata:
  name: prometheus-rulefiles
  namespace: monitoring

创建:

kubectl apply -f prometheus-config-rulefiles.yml

role 和 roleBinding

因为 Prometheus 会使用之前创建的 sa(serviceAccount)prometheus-k8s 运行,那么光现在 prometheus-k8s 这个 sa 的权限是没有办法查看 service 以及 endpoint 的。

我们使用 kubernetes_sd_config 主要会使用 endpoint 进行发现,因此 prometheus-k8s 必须具备更多的权限。

我们需要创建更多的 role,并通过 roleBinding 将这些权限绑定到 prometheus-k8s 这个 sa 上,之所以不使用 clusterRole 是为了权限最小化。

这里会创建 prometheus-roleConfig.ymlprometheus-roleBindingConfig.ymlprometheus-roleSpecificNamespaces.ymlprometheus-roleBindingSpecificNamespaces.yml 这四个文件,它们的内容如下。

prometheus-roleConfig.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: prometheus-k8s-config
  namespace: monitoring
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - get

prometheus-roleBindingConfig.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: prometheus-k8s-config
  namespace: monitoring
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: prometheus-k8s-config
subjects:
  - kind: ServiceAccount
    name: prometheus-k8s
    namespace: monitoring

prometheus-roleSpecificNamespaces.yml:

apiVersion: rbac.authorization.k8s.io/v1
items:
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: prometheus-k8s
      namespace: default
    rules:
      - apiGroups:
          - ""
        resources:
          - services
          - endpoints
          - pods
        verbs:
          - get
          - list
          - watch
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: prometheus-k8s
      namespace: kube-system
    rules:
      - apiGroups:
          - ""
        resources:
          - services
          - endpoints
          - pods
        verbs:
          - get
          - list
          - watch
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: prometheus-k8s
      namespace: monitoring
    rules:
      - apiGroups:
          - ""
        resources:
          - services
          - endpoints
          - pods
        verbs:
          - get
          - list
          - watch
kind: RoleList

prometheus-roleBindingSpecificNamespaces.yml:

apiVersion: rbac.authorization.k8s.io/v1
items:
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: prometheus-k8s
      namespace: default
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: prometheus-k8s
    subjects:
      - kind: ServiceAccount
        name: prometheus-k8s
        namespace: monitoring
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: prometheus-k8s
      namespace: kube-system
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: prometheus-k8s
    subjects:
      - kind: ServiceAccount
        name: prometheus-k8s
        namespace: monitoring
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: prometheus-k8s
      namespace: monitoring
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: prometheus-k8s
    subjects:
      - kind: ServiceAccount
        name: prometheus-k8s
        namespace: monitoring
kind: RoleBindingList

上面的权限中,config 是用来读 configmap 的,后面的就是 Prometheus 用来进行 k8s 发现时必须要的权限了,最后使用 rulebinding 将这些所有的权限都绑定到 prometheus-k8s 这个 sa 上。

这样后续 Prometheus 容器访问 api server 以及集群内的组件时,就会使用这些权限访问。

最后应用:

kubectl apply -f prometheus-roleBindingConfig.yml
kubectl apply -f prometheus-roleBindingSpecificNamespaces.yml
kubectl apply -f prometheus-roleConfig.yml
kubectl apply -f prometheus-roleSpecificNamespaces.yml

创建 pv

Prometheus 因为会将数据存储到磁盘上,因此我们必须使用 statefulset,这样就需要一个存储了,我这里就直接使用 nfs 了,你可能需要搭建一个,这里就不多提了。

先创建 prometheus-pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: prometheus
  labels:
    name: prometheus
spec:
  nfs:
    path: /data/prometheus
    server: 10.1.1.3
  accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  capacity:
    storage: 1Ti

然后应用:

kubectl apply -f prometheus-pv.yml

创建 service

statefulset 必须要一个无头的 service,同时我们要进行 endpoint 发现也需要创建 service,创建一个 service 正好满足它们,不过要为这个 service 添加 prometheus=k8s 这个标签。

因此创建文件 prometheus-service.yml,它的内容如下:

apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
  labels:
    prometheus: k8s
spec:
  clusterIP: None
  ports:
    - name: web
      port: 9090
      protocol: TCP
      targetPort: web
  selector:
    app: prometheus
  type: ClusterIP

上面定义了 app=prometheus 这样的标签选择器,因此 Prometheus 容器必须存在这个标签。

创建:

kubectl apply -f prometheus-service.yml

创建 etcd secret

如果你不打算监控 etcd,那么可以直接跳过,并且将下面 Prometheus yml 文件中的 secret 相关的挂载删掉。

直接创建一个 secret 就行:

kubectl -n monitoring create secret generic etcd-client-cert --from-file=/etc/kubernetes/pki/etcd/ca.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key

为了方便后续使用,建议你在这个命令之后加上 --dry-run -o yaml,然后将输出的内容保存在 prometheus-secret.yml 中。因为加了 --dry-run 之后不会执行,你还需要手动创建:

kubectl apply -f prometheus-secret.yml

部署 Prometheus

到此所有前置工作完成,接下来就可以直接部署 prometheus 了。先创建文件 prometheus.yml,它的内容如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: prometheus
    prometheus: k8s
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: prometheus
      prometheus: k8s
  serviceName: prometheus
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: prometheus
        prometheus: k8s
    spec:
      serviceAccount: prometheus-k8s
      containers:
        - args:
            - --web.console.templates=/etc/prometheus/consoles
            - --web.console.libraries=/etc/prometheus/console_libraries
            - --config.file=/etc/prometheus/config/prometheus.yml
            - --storage.tsdb.path=/prometheus
            - --web.enable-admin-api
            - --storage.tsdb.retention.time=20d
            - --web.enable-lifecycle
            - --storage.tsdb.no-lockfile
            - --web.external-url=http://example.com/
            - --web.route-prefix=/
          image: prom/prometheus:v2.11.1
          imagePullPolicy: IfNotPresent
          livenessProbe:
            failureThreshold: 6
            httpGet:
              path: /-/healthy
              port: web
              scheme: HTTP
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 3
          name: prometheus
          ports:
            - containerPort: 9090
              name: web
              protocol: TCP
          readinessProbe:
            failureThreshold: 120
            httpGet:
              path: /-/ready
              port: web
              scheme: HTTP
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 3
          resources:
            requests:
              memory: 400Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /etc/prometheus/config
              name: config
              readOnly: true
            - mountPath: /prometheus
              name: prometheus-data
              #subPath: prometheus-db
            - mountPath: /etc/prometheus/rules/
              name: prometheus-rulefiles
            - mountPath: /etc/prometheus/secrets/etcd-client-cert
              name: secret-etcd-client-cert
              readOnly: true
      volumes:
        - name: config
          configMap:
            defaultMode: 420
            name: prometheus
        - name: prometheus-rulefiles
          configMap:
            defaultMode: 420
            name: prometheus-rulefiles
        - name: secret-etcd-client-cert
          secret:
            defaultMode: 420
            secretName: etcd-client-cert
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
    - metadata:
        name: prometheus-data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Ti
        volumeMode: Filesystem

基础的 statfulset 相关的知识我就不多提了,说几个重点吧:

  • --storage.tsdb.retention.time=20d 这个启动选项表示 Prometheus 所收集的监控数据只保留 20 天,这个值最好不要太大。如果历史数据保存很久,建议写到持久存储中,比如 VictoriaMetrics、thanos、influxdb、opentsdb 等;
  • --web.enable-admin-api 这个启动选项表示启动管理员 api,你可以通过 api 对监控数据进行删除等;
  • serviceAccount 它的值必须是 prometheus-k8s,不然前面的赋权操作都白干了;
  • pod 必须存在 app: prometheus 这个标签,不然无法被前面创建的 service 选择到;
  • 挂载了两个 configmap、一个 secret 还有一个存储卷。

其他没有什么好说的了,直接干吧:

kubectl apply -f prometheus.yml

然后等待 Prometheus 启动成功:

kubectl -n monitoring get pod -w

访问 Prometheus

启动成功之后就可以直接访问了,我们先不创建 ingress,而是将 pod 的端口绑定到宿主机上:

kubectl -n monitoring port-forward --address 0.0.0.0 pod/prometheus-0 9090:9090

然后通过访问当前主机的 9090 端口就可以打开 Prometheus 页面。我们点开 Status,然后选择 Targets 就可以发现 Prometheus 自身已经被监控了。

可以看到,它显示了额外的 6 个标签,这些都是我们前面通过 relabel_configs 配置附加上去的,你现在只要在 Prometheus 查询任意一条监控指标,都会有这 6 个标签。如果你觉得这些标签中有你不需要的,只需要在前面的配置中删除对应的配置即可。

然后你将鼠标悬浮在这些标签之上,就能看到所有 relabel 之前所有的元标签,如果有你需要的,可以在前面的配置文件中添加响应的配置,将对应的标签加上去。

你可以选择点击左上角的 Prometheus 回到主页,然后在下面的查询框中,随便输入一个字母,然后在出现的所有监控指标中随便点击一个,就可以看到它的所有标签和其对应的值了。

可以看到,额外的 6 个标签都存在,今后你可以通过这些标签来进行查询了。

最后,给 Prometheus 创建一个 ingress,文件名为 prometheus-ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: prometheus
  namespace: monitoring
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: prometheus
              servicePort: 9090

注意将上面的 example.com 替换成你 Prometheus 的域名。