Prometheus 服務發現 k8s

自從 上次 介紹了 Prometheus 以後,就想到要在 k8s 中使用了,不過,在這以前,先介紹下 k8s 的監控。node

k8s 的監控

k8s 默認以及推薦的監控體系是它本身的一套東西:Heapster + cAdvisor + Influxdb + Grafana,具體能夠看 這裏 。git

包括 k8s 自身的 HPA (Horizontal Pod Autoscaler),默認從 Heapster 中獲取數據進行自動伸縮。(順便提一句,當你部署完 k8s 集羣以後,若是從 Dashboard 中看不到監控數據,每每就是由於你沒有部署 Heapster,或者網絡層有問題, Dashboard 沒法訪問 Heapster。)github

那,這跟咱們介紹的 Prometheus 有什麼關係?後端

首先,它們都是一套監控解決方案,而 k8s 沒有把 Prometheus 做爲默認監控,所以,若是你想直接使用 HPA,你仍是須要部署 Heapster。api

其次,kubelet 中的 cAdvisor 實際上是支持 Prometheus 做爲存儲的後端的,只是相對於 Prometheus 本身的 SD 解決方案來講,太弱了點。網絡

最後,k8s 1.6 以後,在 annotations 中配置 custom metrics 的方式已經被移除了,而根據
Prometheus 的監控數據來進行自動伸縮仍是頗有可操做性的。app

部署

其實部署很簡單,關鍵是配置,所以這裏着重介紹下,如何配置。spa

Relabel

首先,先來了解下,什麼是 relabel_configdebug

就如字面意思而言,它的做用是 Prometheus 抓取 metrics 以前,就將對象相關的 labels 重寫。下面是它幾個重要的 label:對象

  • __address__:默認爲 host:port,也是以後抓取以後 instance 的值;
  • __scheme__:http or https ?;
  • __metrics_path__:就是 metrics path,默認爲 /metrics
  • __param_${name}:用來做爲 URL parameter,好比 http://.../metrics?name=value
  • __meta_:這個開頭的配置都是 SD 相關的配置;

Kubernetes SD

其次,上次提到,咱們能夠用到 Service Discovery 這個功能,其中就包含 Kubernetes SD

它包含四種角色:

  • node
  • service
  • pod
  • endpoints

因爲篇幅所限,這裏只是簡單介紹下其中的 node 還有 pod 角色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- job_name: 'kubernetes-nodes'
  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:
  - role: node
  
  relabel_configs:
    # 即從 __meta_kubernetes_node_label_<labelname> 這個配置中取出 labelname 以及 value
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
    
    # 配置 address 爲 k8s api 的地址,相關的 ca 證書以及 token 在上面配置
  - target_label: __address__
    replacement: kubernetes.default.svc:443
    
    # 取出全部的 node,而後設置 /api/v1/nodes/<node_name>/proxy/metrics 爲 metrics path
  - source_labels: 
    - __meta_kubernetes_node_name
    regex: (.+)
    target_label: __metrics_path__
    replacement: /api/v1/nodes/${1}/proxy/metrics

接下來的這個 pod 角色挺重要:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 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

在定義了這個角色以後,你只要在你部署的應用 Pod 描述中,加入如下 annotations 就能讓 Prometheus 自動發現此 Pod 並採集監控數據了:

1
2
3
annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "<your app port>"

其它詳細配置請看 這裏

Kubernetes Deployment

最後,部署 Prometheus,須要注意的是,咱們已經在 k8s 以外單獨部署了一套,爲了統一處理,在這裏是打算做爲中轉的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus
  namespace: kube-system
  labels:
    app: prometheus
data:
  prometheus.yml: |-
  # 省略,在這裏定義你須要的配置
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: prometheus
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:latest
        args:
          - '-config.file=/prometheus-data/prometheus.yml'
          # 顯然,這裏沒有用 `Stateful Sets`,存儲時間不用太長
          - '-storage.local.retention=48h0m0s'
        ports:
        - name: prometheus
          containerPort: 9090
        volumeMounts:
        - name: data-volume
          mountPath: /prometheus-data
      volumes:
      - name: data-volume
        configMap:
          name: prometheus
---
# 簡單處理,直接使用 NodePort 暴露服務,你也可使用 Ingress
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: kube-system
spec:
  selector:
    app: prometheus
  ports:
  - name: prometheus
    protocol: TCP
    port: 9090
    nodePort: 30090
  type: NodePort

Prometheus Federate

而在咱們外部單獨的 Prometheus 中,須要配置 Federate,將 k8s 中 Prometheus 採集的 metrics 所有同步出來。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- job_name: 'federate'
  scrape_interval: 15s

  honor_labels: true
  metrics_path: '/federate'

  params:
    'match[]':
      - '{job=~".+"}' # 取 k8s 裏面部署的  Prometheus 中全部的 job 數據

  static_configs:
    - targets:
      - '<k8s-node1>:30090'
      - '<k8s-node2>:30090'
      - '<k8s-node3>:30090'
相關文章
相關標籤/搜索