部署prometheus監控kubernetes集群並存儲到ceph


簡介

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

后續:

本篇嚴格來說是完成了一部分,還有些監控項、監控策略、告警平台沒有加入,會補的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM