天天看點

部署prometheus監控kubernetes叢集并存儲到ceph

簡介

Prometheus 最初是 SoundCloud 建構的開源系統監控和報警工具,是一個獨立的開源項目,于2016年加入了 CNCF 基金會,作為繼 Kubernetes 之後的第二個托管項目。

特征

​ Prometheus 相比于其他傳統監控工具主要有以下幾個特點:

​ 具有由 metric 名稱和鍵/值對辨別的時間序列資料的多元資料模型

​ 有一個靈活的查詢語言

​ 不依賴分布式存儲,隻和本地磁盤有關

​ 通過 HTTP 的服務拉取時間序列資料

​ 也支援推送的方式來添加時間序列資料

​ 還支援通過服務發現或靜态配置發現目标

​ 多種圖形和儀表闆支援

元件

​ Prometheus 由多個元件組成,但是其中許多元件是可選的:

​ Prometheus Server:用于抓取名額、存儲時間序列資料

​ exporter:暴露名額讓任務來抓

​ pushgateway:push 的方式将名額資料推送到該網關

​ alertmanager:處理報警的報警元件

​ adhoc:用于資料查詢

大多數 Prometheus 元件都是用 Go 編寫的,是以很容易建構和部署為靜态的二進制檔案。

prometheus元件架構圖

部署prometheus監控kubernetes叢集并存儲到ceph

如上圖,每個被監控的主機都可以通過專用的

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 pool,prometheus叢集的名稱空間為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
           
部署prometheus監控kubernetes叢集并存儲到ceph

部署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

部署prometheus監控kubernetes叢集并存儲到ceph
部署prometheus監控kubernetes叢集并存儲到ceph

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: '[email protected]'
      smtp_auth_username: '[email protected]'
      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: '[email protected]'
        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叢集并存儲到ceph
部署prometheus監控kubernetes叢集并存儲到ceph

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
           

後續:

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

過手如登山,一步一重天