简介

Prometheus 最初是 SoundCloud 构建的开源系统监控和报警工具,是一个独立的开源项目,于2016年加入了 CNCF 基金会,作为继 Kubernetes 之后的第二个托管项目。

特征

​ Prometheus 相比于其他传统监控工具主要有以下几个特点:
​ 具有由 metric 名称和键/值对标识的时间序列数据的多维数据模型
​ 有一个灵活的查询语言
​ 不依赖分布式存储,只和本地磁盘有关
​ 通过 HTTP 的服务拉取时间序列数据
​ 也支持推送的方式来添加时间序列数据
​ 还支持通过服务发现或静态配置发现目标
​ 多种图形和仪表板支持

组件

​ Prometheus 由多个组件组成,但是其中许多组件是可选的:
​ Prometheus Server:用于抓取指标、存储时间序列数据
​ exporter:暴露指标让任务来抓
​ pushgateway:push 的方式将指标数据推送到该网关
​ alertmanager:处理报警的报警组件
​ adhoc:用于数据查询
大多数 Prometheus 组件都是用 Go 编写的,因此很容易构建和部署为静态的二进制文件。

prometheus组件架构图

如上图,每个被监控的主机都可以通过专用的exporter程序提供输出监控数据的接口,并等待Prometheus服务器周期性的进行数据抓取。如果存在告警规则,则抓取到数据之后会根据规则进行计算,满足告警条件则会生成告警,并发送到Alertmanager完成告警的汇总和分发。当被监控的目标有主动推送数据的需求时,可以以Pushgateway组件进行接收并临时存储数据,然后等待Prometheus服务器完成数据的采集。

任何被监控的目标都需要事先纳入到监控系统中才能进行时序数据采集、存储、告警和展示,监控目标可以通过配置信息以静态形式指定,也可以让Prometheus通过服务发现的机制进行动态管理。下面是组件的一些解析:

  • 监控代理程序:如node_exporter:收集主机的指标数据,如平均负载、CPU、内存、磁盘、网络等等多个维度的指标数据。
  • kubelet(cAdvisor):收集容器指标数据,也是K8S的核心指标收集,每个容器的相关指标数据包括:CPU使用率、限额、文件系统读写限额、内存使用率和限额、网络报文发送、接收、丢弃速率等等。
  • API Server:收集API Server的性能指标数据,包括控制队列的性能、请求速率和延迟时长等等
  • etcd:收集etcd存储集群的相关指标数据
  • kube-state-metrics:该组件可以派生出k8s相关的多个指标数据,主要是资源类型相关的计数器和元数据信息,包括制定类型的对象总数、资源限额、容器状态以及Pod资源标签系列等。

Prometheus 能够 直接 把 Kubernetes API Server 作为 服务 发现 系统 使用 进而 动态 发现 和 监控 集群 中的 所有 可被 监控 的 对象。 这里 需要 特别 说明 的 是, Pod 资源 需要 添加 下列 注解 信息 才 能被 Prometheus 系统 自动 发现 并 抓取 其 内建 的 指标 数据。

  • 1) prometheus. io/ scrape: 用于 标识 是否 需要 被 采集 指标 数据, 布尔 型 值, true 或 false。
  • 2) prometheus. io/ path: 抓取 指标 数据 时 使用 的 URL 路径, 一般 为/ metrics。
  • 3) prometheus. io/ port: 抓取 指标 数据 时 使 用的 套 接 字 端口, 如 8080。

另外, 仅 期望 Prometheus 为 后端 生成 自定义 指标 时 仅 部署 Prometheus 服务器 即可, 它 甚至 也不 需要 数据 持久 功能。 但 若要 配置 完整 功能 的 监控 系统, 管理员 还需 要在 每个 主机 上 部署 node_ exporter、 按 需 部署 其他 特有 类型 的 exporter 以及 Alertmanager。

kube-state-metrics与metric-server的对比

metric-server(或heapster)是一个集群组件定期通过kubelet来获取集群节点的cpu、内存使用率这种监控指标,而且它只保留最新数据且存储在内存中,不负责发送给第三方,你可以通过其他方式把他们发送给存储后端,如influxdb或云厂商,他当前的核心作用是:为HPA等组件提供决策指标支持。

kube-state-metrics关注于获取k8s各种资源对象的最新状态,如deployment或者daemonset,它在内存中保留kubernetes集群状态的快照并且在随后的时间里基于这个快照生成新的指标,而且它也不负责发数据发给第三方。将kube-state-metrics作为单独的项目,还可以从Prometheus等监控系统访问这些指标。

之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为他们的关注点本质上是不一样的。metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统。而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但他没有能力导出这些指标 换个角度讲,kube-state-metrics本身是metric-server的一种数据来源,虽然现在没有这么做。 另外,像Prometheus这种监控系统,并不会去用metric-server中的数据,他都是自己做指标收集、集成的(Prometheus包含了metric-server的能力),但Prometheus可以监控metric-server本身组件的监控状态并适时报警,这里的监控就可以通过kube-state-metrics来实现,如metric-serverpod的运行状态。

部署前提

检查ceph集群状态

# ceph -s
......
    health: HEALTH_OK

检查kubernetes集群状态

# kubectl get nodes
NAME         STATUS                     ROLES    AGE    VERSION
20.0.0.201   Ready,SchedulingDisabled   master   4d9h   v1.17.2
20.0.0.202   Ready,SchedulingDisabled   master   4d9h   v1.17.2
20.0.0.203   Ready,SchedulingDisabled   master   4d9h   v1.17.2
20.0.0.204   Ready                      node     4d9h   v1.17.2
20.0.0.205   Ready                      node     4d9h   v1.17.2
20.0.0.206   Ready                      node     4d9h   v1.17.2

注:ceph 使用assembly poolprometheus集群的名称空间为assembly

这里我只给出具体配置,有关详细的理论解释请自行google。

建议:学习本篇之前,先搞通此篇:https://www.cnblogs.com/zisefeizhu/p/12519658.html

部署总述

# pwd
/data/k8s/prometheus
# tree ./
./
├── altermanager
│?? ├── alertmanager-conf.yaml
│?? ├── alertmanager-deployment.yaml
│?? └── alertmanager-svc.yaml
├── ceph-prometheus-storageclass.yaml
├── grafana
│?? ├── grafana-deployment.yaml
│?? ├── grafana-ingressroute.yaml
│?? ├── grafana-pvc.yaml
│?? └── grafana-svc.yaml
├── node-exporter
│?? └── node-exporter.yaml
└── prometheus
    ├── prometheus-cm.yaml
    ├── prometheus-deploy.yaml
    ├── prometheus-ingressroute.yaml
    ├── prometheus-pvc.yaml
    ├── prometheus-rbac.yaml
    └── prometheus-svc.yaml

4 directories, 15 files


# kubectl get pods -n assembly
NAME                              READY   STATUS    RESTARTS   AGE
alertmanager-76fd475999-l9pdh     1/1     Running   0          54m
grafana-866bbc647-2kxkk           1/1     Running   0          3h50m
node-exporter-7x5wb               1/1     Running   0          4h2m
node-exporter-8gfsn               1/1     Running   0          4h30m
node-exporter-dsk89               1/1     Running   0          4h30m
node-exporter-jw7ck               1/1     Running   0          4h30m
node-exporter-rcw6c               1/1     Running   0          4h30m
node-exporter-w5sz6               1/1     Running   0          4h30m
prometheus-7d844f7645-x75rp       1/1     Running   0          4h31m
rbd-provisioner-9cf46c856-mvtx5   1/1     Running   15         34h


# kubectl get pvc -n assembly
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
grafana-pvc          Bound    pvc-8b1550f9-9b7d-4884-b41d-ea10106f9321   5Gi        RWO            ceph-prometheus   4h46m
prometheus-pvc       Bound    pvc-3ae3ac53-537f-4641-b626-b74da48db053   10Gi       RWO            ceph-prometheus   4h31m

部署prometheus

# ll
总用量 4
-rw-r--r-- 1 root root 1018 3月  20 08:33 ceph-prometheus-storageclass.yaml
drwxr-xr-x 2 root root  180 3月  20 20:51 prometheus
# cat ceph-prometheus-storageclass.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   ceph-prometheus-storageclass.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-prometheus
  namespace: assembly
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: ceph.com/rbd
reclaimPolicy: Retain
parameters:
  monitors: 20.0.0.205:6789,20.0.0.206:6789,20.0.0.207:6789
  adminId: admin
  adminSecretName: ceph-admin-secret
  adminSecretNamespace: assembly
  pool: assembly
  fsType: xfs
  userId: assembly
  userSecretName: ceph-assembly-secret
  imageFormat: "2"
  imageFeatures: "layering"

# cat prometheus-cm.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-cm.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: assembly
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    alerting:
      alertmanagers:
      - static_configs:
        - targets: ["alertmanager:9093"]
   
    rule_files:
    -  /etc/prometheus/rules.yaml

    scrape_configs:
    - job_name: \'prometheus\'
      static_configs:
      - targets: [\'localhost:9090\']
    - job_name: \'traefik\'
      static_configs:
        - targets: [\'traefik.kube-system.svc.cluster.local:8080\']
    - job_name: "kubernetes-nodes"
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: \'(.*):10250\'
        replacement: \'${1}:9100\'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: \'kubernetes-kubelet\'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: \'kubernetes-pods\'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name

    - job_name: "kubernetes-apiserver"
      kubernetes_sd_configs:
      - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs: 
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https
    - job_name: "kubernetes-scheduler"
      kubernetes_sd_configs:
      - role: endpoints
     
    - job_name: \'kubernetes-service-endpoints\'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

  rules.yaml: |
    groups:
    - name: test-rule 
      rules:
      - alert: NodeMemoryUsage
        expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes+node_memory_Cached_bytes)) / sum(node_memory_MemTotal_bytes) * 100 > 5
        for: 2m
        labels:
          team: node
        annotations:
          summary: "{{$labels.instance}}: High Memory usage detected"
          description: "{{$labels.instance}}: Memory usage is above 80% (current value is: {{ $value }}"
          
# cat prometheus-deploy.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-deploy.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: assembly
  labels:
    app: prometheus
spec:
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      imagePullSecrets: 
        - name: k8s-harbor-login
      serviceAccountName: prometheus
      containers:
      - image: harbor.linux.com/prometheus/prometheus:v2.4.3
        name: prometheus
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=24h"
        - "--web.enable-admin-api"  # 控制对admin HTTP API的访问,其中包括删除时间序列等功能
        - "--web.enable-lifecycle"  # 支持热更新,直接执行localhost:9090/-/reload立即生效
        ports:
        - containerPort: 9090
          protocol: TCP
          name: http
        volumeMounts:
        - mountPath: "/prometheus"
          subPath: prometheus
          name: data
        - mountPath: "/etc/prometheus"
          name: config-volume
        resources:
          requests:
            cpu: 100m
            memory: 512Mi
          limits:
            cpu: 100m
            memory: 512Mi
      securityContext:
        runAsUser: 0
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: prometheus-pvc
      - configMap:
          name: prometheus-config
        name: config-volume
      nodeSelector:             ## 设置node筛选器,在特定label的节点上启动
        prometheus: "true"  

# cat prometheus-ingressroute.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-ingressroute.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: prometheus
  namespace: assembly
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`prometheus.linux.com`)
    kind: Rule
    services:
    - name: prometheus
      port: 9090

# cat prometheus-pvc.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-pvc.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus-pvc
  namespace: assembly
 # labels:
 #   app: gitlab
spec:
  storageClassName: ceph-prometheus
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi 

# cat prometheus-rbac.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-rbac.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: assembly
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  - services
  - endpoints
  - pods
  - nodes/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  - nodes/metrics
  verbs:
  - get
- nonResourceURLs:
  - /metrics
  verbs:
  - get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: assembly

# cat prometheus-svc.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   prometheus-svc.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: assembly
  labels:
    app: prometheus
spec:
  selector:
    app: prometheus
  type: NodePort
  ports:
    - name: web
      port: 9090
      targetPort: http
      
# kubectl get pods -n assembly
NAME                              READY   STATUS    RESTARTS   AGE
prometheus-7d844f7645-x75rp       1/1     Running   0          4h14m
rbd-provisioner-9cf46c856-mvtx5   1/1     Running   14         34h

部署node-exporter

# cat node-exporter.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   node_exporter.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: assembly
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
      name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v0.17.0
        ports:
        - containerPort: 9100
        resources:
          requests:
            cpu: 0.15
        securityContext:
          privileged: true
        args:
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --collector.filesystem.ignored-mount-points
        - \'"^/(sys|proc|dev|host|etc)($|/)"\'
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /
            
# kubectl get pods -n assembly
NAME                              READY   STATUS    RESTARTS   AGE
node-exporter-7x5wb               1/1     Running   0          3h45m
node-exporter-8gfsn               1/1     Running   0          4h13m
node-exporter-dsk89               1/1     Running   0          4h13m
node-exporter-jw7ck               1/1     Running   0          4h13m
node-exporter-rcw6c               1/1     Running   0          4h13m
node-exporter-w5sz6               1/1     Running   0          4h13m

grafana部署

# cat grafana-deployment.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   grafana-deployment.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: assembly
  labels:
    app: grafana
spec:
  selector:
    matchLabels:
      app: grafana
  revisionHistoryLimit: 10
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:6.6.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
          name: grafana
        env:
        - name: GF_SECURITY_ADMIN_USER
          value: admin
        - name: GF_SECURITY_ADMIN_PASSWORD
          value: zisefeizhu
        readinessProbe:
          failureThreshold: 10
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 30
        livenessProbe:
          failureThreshold: 10
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        volumeMounts:
        - mountPath: /var/lib/grafana
          subPath: grafana
          name: storage
      securityContext:
        fsGroup: 472
        runAsUser: 472
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: grafana-pvc
      nodeSelector:             ## 设置node筛选器,在特定label的节点上启动
        grafana: "true"  
        
# cat grafana-ingressroute.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   grafana-ingressroute.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: grafana
  namespace: assembly
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`grafana.linux.com`)
    kind: Rule
    services:
    - name: grafana
      port: 3000

# cat grafana-pvc.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   grafana-pvc.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pvc
  namespace: assembly
 # labels:
 #   app: gitlab
spec:
  storageClassName: ceph-prometheus
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi 

# cat grafana-svc.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   grafana-svc.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: assembly
  labels:
    app: grafana
spec:
  type: NodePort
  ports:
    - port: 3000
  selector:
    app: grafana

# kubectl get pods -n assembly
NAME                              READY   STATUS    RESTARTS   AGE
grafana-866bbc647-2kxkk           1/1     Running   0          3h41m

推荐模板

8919 9276 10000

altermanager部署

# cat alertmanager-conf.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   alertmanager-conf.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ConfigMap
metadata:
  name: alert-config
  namespace: assembly
data:
  config.yml: |-
    global:
      # 在没有报警的情况下声明为已解决的时间
      resolve_timeout: 5m
      # 配置邮件发送信息
      smtp_smarthost: \'smtp.163.com:25\'
      smtp_from: \'13xxxxxxx91@163.com\'
      smtp_auth_username: \'13xxxxxxx91@163.com\'
      smtp_auth_password: \'lkxx3x23\' #改成自己的密码
      smtp_hello: \'163.com\'
      smtp_require_tls: false
    # 所有报警信息进入后的根路由,用来设置报警的分发策略
    route:
      # 这里的标签列表是接收到报警信息后的重新分组标签,例如,接收到的报警信息里面有许多具有 cluster=A 和 alertname=LatncyHigh 这样的标签的报警信息将会批量被聚合到一个分组里面
      group_by: [\'alertname\', \'cluster\']
      # 当一个新的报警分组被创建后,需要等待至少group_wait时间来初始化通知,这种方式可以确保您能有足够的时间为同一分组来获取多个警报,然后一起触发这个报警信息。
      group_wait: 30s

      # 当第一个报警发送后,等待\'group_interval\'时间来发送新的一组报警信息。
      group_interval: 30m

      # 如果一个报警信息已经发送成功了,等待\'repeat_interval\'时间来重新发送他们
      repeat_interval: 30m

      # 默认的receiver:如果一个报警没有被一个route匹配,则发送给默认的接收器
      receiver: default

      # 上面所有的属性都由所有子路由继承,并且可以在每个子路由上进行覆盖。
      routes:
      - receiver: email
        group_wait: 10s
        match:
          team: node
    receivers:
    - name: \'default\'
      email_configs:
      - to: \'23xxxxxx0@qq.com\'
        send_resolved: true

# cat alertmanager-deployment.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   alertmanager-deployment.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: alertmanager
  namespace: assembly
spec:
  selector:
    matchLabels:
      app: alertmanager
  replicas: 1
  template:
    metadata:
      labels:
         app: alertmanager
    spec:
      containers:
      - name: alertmanager
        image: prom/alertmanager:v0.15.3
        imagePullPolicy: IfNotPresent
        args:
        - "--config.file=/etc/alertmanager/config.yml"
        - "--storage.path=/alertmanager/data"
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 100m
            memory: 256Mi
        volumeMounts:
        - name: alert-config
          mountPath: /etc/alertmanager
        ports:
        - name: http
          containerPort: 9093
      volumes:
      - name: alert-config
        configMap:
          name: alert-config
      nodeSelector:             ## 设置node筛选器,在特定label的节点上启动
        alter: "true" 
        
# cat alertmanager-svc.yaml 
##########################################################################
#Author:                     zisefeizhu
#QQ:                         2********0
#Date:                       2020-03-20
#FileName:                   alertmanager-svc.yaml
#URL:                        https://www.cnblogs.com/zisefeizhu/
#Description:                The test script
#Copyright (C):              2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
  name: alertmanager
  namespace: assembly
  annotations:
    prometheus.io/scrape: "true"
spec:
  selector:
    app: alertmanager
  ports:
  - name: http
    port: 9093    

Prometheus配置文件说明

# Kubernetes的API SERVER会暴露API服务,Promethues集成了对Kubernetes的自动发现,它有5种模式:Node、Service
# 、Pod、Endpoints、ingress,下面是Prometheus官方给出的对Kubernetes服务发现的实例。这里你会看到大量的relabel_configs,
# 其实你就是把所有的relabel_configs去掉一样可以对kubernetes做服务发现。relabel_configs仅仅是对采集过来的指标做二次处理,比如
# 要什么不要什么以及替换什么等等。而以__meta_开头的这些元数据标签都是实例中包含的,而relabel则是动态的修改、覆盖、添加删除这些标签
# 或者这些标签对应的值。而且以__开头的标签通常是系统内部使用的,因此这些标签不会被写入样本数据中,如果我们要收集这些东西那么则要进行
# relabel操作。当然reabel操作也不仅限于操作__开头的标签。
# 
# action的行为:
#   replace:默认行为,不配置action的话就采用这种行为,它会根据regex来去匹配source_labels标签上的值,并将并将匹配到的值写入target_label中
#   labelmap:它会根据regex去匹配标签名称,并将匹配到的内容作为新标签的名称,其值作为新标签的值
#   keep:仅收集匹配到regex的源标签,而会丢弃没有匹配到的所有标签,用于选择
#   drop:丢弃匹配到regex的源标签,而会收集没有匹配到的所有标签,用于排除
#   labeldrop:使用regex匹配标签,符合regex规则的标签将从target实例中移除,其实也就是不收集不保存
#   labelkeep:使用regex匹配标签,仅收集符合regex规则的标签,不符合的不收集
# 
global:
  scrape_interval: 10s
  evaluation_interval: 30s
scrape_configs:
  # 用于发现API SERVER
- job_name: \'kubernetes-apiservers\'

 kubernetes_sd_configs:
  # 发现endpoints,它是从列出的服务端点发现目标,这个endpoints来自于Kubernetes中的service,每一个service都有对应的endpoints,这里是一个列表
  # 可以是一个IP:PORT也可以是多个,这些IP:PORT就是service通过标签选择器选择的POD的IP和端口。所以endpoints角色就是用来发现server对应的pod的IP的
  # kubernetes会有一个默认的service,通过找到这个service的endpoints就找到了api server的IP:PORT,那endpoints有很多,我怎么知道哪个是api server呢
  # 这个就靠source_labels指定的标签名称了。
  - role: endpoints
  # 通过什么形式来连接,默认是https
  scheme: https
  # 下面这个ca_file和token_file的路径都是默认的,你可能默认设置能用么?其实可以,因为每一个运行起来的POD kubernetes都会为其
  # 创建一个serviceaccout的Secret并且挂载到下面的目录上,里面就有ca.crt和token这两个文件,你可以自己启动一个POD,然后通过
  # kubectl describe pods 来查看,一定会在Volumes下面有一个default-token-XXX的东西,并且Mounts里面有下面的目录。
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

 # 下面的含义是源标签__meta_kubernetes_namespace等如果其值为default;kubernetes;https标签顺序和值要对应。换句话说就是
  # 当__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name三者对应的
  # 值为default、kubernetes、https则进行保留,而且该endpoints对应的地址为api server的地址。
  # 
  # __meta_kubernetes_namespace 端点对象的命名空间,在不同对象上这个标签的含义不同,在角色是endpoints中这个是端点对象的名称空间
  # __meta_kubernetes_service_name 端点对象的服务名称
  # __meta_kubernetes_endpoint_port_name 端点的端口名称
  # 
  # kubernetes默认在default名称空间有一个叫做kubernetes的service,所以这个service的有3个设置对应的就是下面三个标签
  # __meta_kubernetes_namespace 值为default
  # __meta_kubernetes_service_name 值为kubernetes
  # __meta_kubernetes_endpoint_port_name 值为https
  relabel_configs:
  - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
    action: keep
    regex: default;kubernetes;https

# 配置针对kubelet的服务发现以及对标签的处理,是获取kubelet上/metrics接口数据来获取node的资源使用情况
- job_name: \'kubernetes-nodes-kubelet\'
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    # 跳过CA验证
    # insecure_skip_verify: true
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

 kubernetes_sd_configs:
  # 使用node角色,它使用默认的kubelet提供的http端口来发现集群中每个node节点。那具体地址是什么呢?
  # 地址类型有四种NodeInternalIP, NodeExternalIP, NodeLegacyHostIP 和 NodeHostName,默认为这四个中第一个可用的地址。
  # 那么这里为什么使用node角色呢?因为node角色就是用来发现kubelet的
  # __meta_kubernetes_node_name:节点对象的名字
  # __meta_kubernetes_node_label_<labelname>:表示节点对象上的每一个标签
  # __meta_kubernetes_node_annotation_<annotationname>:表示节点对象上的每一个annotation
  # __meta_kubernetes_node_address_<address_type>:如果存在,那么将是每一个节点地址类型的第一个地址
  # Node模式,Prometheus会自动发现Kubernetes中所有Node节点的信息并作为监控的目标Target。 
  # 而这些Target的访问地址实际上就是Kubelet的访问地址,并且Kubelet实际上直接内置了对Promtheus的支持
  - role: node

 relabel_configs:
  # 保留(.+)匹配到的内容,去掉__meta_kubernetes_node_label_,实际上就是把(.+)当做新标签,然后老标签的值给这个新标签,
  # 这里没有设置source_labels,则表示匹配所有标签
  - action: labelmap
    # 匹配节点对象上的每一个标签
    regex: __meta_kubernetes_node_label_(.+)

# 抓取cAdvisor数据,是获取kubelet上/metrics/cadvisor接口数据来获取容器的资源使用情况
- job_name: \'kubernetes-nodes-cadvisor\'
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

 kubernetes_sd_configs:
  # 使用角色为node
  - role: node

 relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
  # 把__metrics_path__的值替换为/metrics/cadvisor,因为默认是/metrics
  - target_label: __metrics_path__
    replacement: /metrics/cadvisor

# 抓取服务端点,整个这个任务都是用来发现node-exporter和kube-state-metrics-service的,这里用的是endpoints角色,这是通过这两者的service来发现
# 的后端endpoints。另外需要说明的是如果满足采集条件,那么在service、POD中定义的labels也会被采集进去
- job_name: \'kubernetes-service-endpoints\'

 kubernetes_sd_configs:
  - role: endpoints

 relabel_configs:
  # 重新打标仅抓取到的具有 "prometheus.io/scrape: true" 的annotation的端点,意思是说如果某个service具有prometheus.io/scrape = true annotation声明则抓取
  # annotation本身也是键值结构,所以这里的源标签设置为键,而regex设置值,当值匹配到regex设定的内容时则执行keep动作也就是保留,其余则丢弃.
  # node-exporter这个POD的service里面就有一个叫做prometheus.io/scrape = true的annotations所以就找到了node-exporter这个POD
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  
  # 应用中自定义暴露的指标,也许你暴露的API接口不是/metrics这个路径,那么你可以在这个POD对应的service中做一个
  # "prometheus.io/path = /mymetrics" 声明,下面的意思就是把你声明的这个路径赋值给__metrics_path__
  # 其实就是让prometheus来获取自定义应用暴露的metrices的具体路径,不过这里写的要和service中做好约定
  # 如果service中这样写 prometheus.io/app-metrics-path: \'/metrics\' 那么你这里就要
  # __meta_kubernetes_service_annotation_prometheus_io_app_metrics_path这样写
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)
  
  # 暴露自定义的应用的端口,就是把地址和你在service中定义的 "prometheus.io/port = <port>" 声明做一个拼接
  # 然后赋值给__address__,这样prometheus就能获取自定义应用的端口,然后通过这个端口再结合__metrics_path__来获取
  # 指标,如果__metrics_path__值不是默认的/metrics那么就要使用上面的标签替换来获取真正暴露的具体路径
  - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
    action: replace
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
    target_label: __address__
  
  # 重新设置scheme
  # 匹配源标签__meta_kubernetes_service_annotation_prometheus_io_scheme也就是prometheus.io/scheme annotation
  # 如果源标签的值匹配到regex则把值替换为__scheme__对应的值
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
    action: replace
    target_label: __scheme__
    regex: (https?)

 # 下面主要是为了给样本添加额外信息
  - action: labelmap
    regex: __meta_kubernetes_service_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    action: replace
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_service_name]
    action: replace
    target_label: kubernetes_name

# 下面是自动发现service,不过如果要想监控service则需要安装blackbox-exporter
- job_name: \'kubernetes-services-http\'

 metrics_path: /probe
  # 生成__param_module="http_2xx"的label,如果是TCP探测则使用 module: [tcp_connect]
  params:
    module: [http_2xx]

 kubernetes_sd_configs:
  - role: service

 relabel_configs:
  # 为了让service可以被探测到,那需要在service的annotation中增加 prometheus.io/scrape: true 声明
  # 也就是只保留prometheus.io/scrape: true的service
  - action: keep
    regex: true
    source_labels:
    - __meta_kubernetes_service_annotation_prometheus_io_scrape
  # 用__address__这个label的值创建一个名为__param_target的label为blackbox-exporter,值为内部service的访问地址,作为blackbox-exporter采集用
  - source_labels: [__address__]
    target_label: __param_target

 # 用blackbox-exporter的service地址值”prometheus-blackbox-exporter:9115"替换原__address__的值
  - target_label: __address__
    replacement: blackbox-exporter.example.com:9115
  - source_labels: [__param_target]
    target_label: instance
  
  # 下面主要是为了给样本添加额外信息
  - action: labelmap
    regex: __meta_kubernetes_service_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_service_name]
    target_label: kubernetes_name

# 下面是对ingresses监控,不过如果要想监控ingresses则需要安装blackbox-exporter
- job_name: \'kubernetes-ingresses\'

 metrics_path: /probe
  # 生成__param_module="http_2xx"的label
  params:
    module: [http_2xx]

 kubernetes_sd_configs:
  - role: ingress

 relabel_configs:
  # Example relabel to probe only some ingresses that have "example.io/should_be_probed = true" annotation
  #  - source_labels: [__meta_kubernetes_ingress_annotation_example_io_should_be_probed]
  #    action: keep
  #    regex: true
  - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
    regex: (.+);(.+);(.+)
    replacement: ${1}://${2}${3}
    target_label: __param_target
  - target_label: __address__
    replacement: blackbox-exporter.example.com:9115
  - source_labels: [__param_target]
    target_label: instance
  # 下面主要是为了给样本添加额外信息
  - action: labelmap
    regex: __meta_kubernetes_ingress_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_ingress_name]
    target_label: kubernetes_name

# 抓取POD进行监控
- job_name: \'kubernetes-pods\'

 kubernetes_sd_configs:
  - role: pod
  relabel_configs:
  # POD的 annotation 中含有"prometheus.io/scrape: true" 的则保留,意思就是会被Prometheus抓取,不具有这个的POD则不会被抓取
  - action: keep
    regex: true
    source_labels:
    - __meta_kubernetes_pod_annotation_prometheus_io_scrape
  # 获取POD的 annotation 中定义的"prometheus.io/path: XXX"定义的值,这个值就是你的程序暴露符合prometheus规范的metrics的地址
  # 如果你的metrics的地址不是 /metrics 的话,通过这个标签说,那么这里就会把这个值赋值给 __metrics_path__这个变量,因为prometheus
  # 是通过这个变量获取路径然后进行拼接出来一个完整的URL,并通过这个URL来获取metrics值的,因为prometheus默认使用的就是 http(s)://X.X.X.X/metrics
  # 这样一个路径来获取的。
  - action: replace
    regex: (.+)
    source_labels:
    - __meta_kubernetes_pod_annotation_prometheus_io_path
    target_label: __metrics_path__
  # 这里是端口信息,因为你的程序很有可能在容器中并不是以80端口运行的,那么就需要做一个拼接http(s)://x.x.x.x:xx/metrics
  # __address__在prometheus中代表的就是实例的IP地址,而POD中的annotation 中定义的"prometheus.io/port: XX"就是你程序
  # 被访问到的端口,最终在prometheus中将会被显示为 instance=X.X.X.X:XX这样
  - action: replace
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
    source_labels:
    - __address__
    - __meta_kubernetes_pod_annotation_prometheus_io_port
    target_label: __address__

 - action: labelmap
    regex: __meta_kubernetes_pod_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    action: replace
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_pod_name]
    action: replace
    target_label: kubernetes_pod_name

后续:

本篇严格来说是完成了一部分,还有些监控项、监控策略、告警平台没有加入,会补的。

版权声明:本文为zisefeizhu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zisefeizhu/p/12535048.html