prometheus監控kubenetes

服務發現

服務發現就是服務提供者和服務使用者之間的服務代理。服務提供者去服務代理註冊本身的服務,服務使用者去服務代理拿到可用的服務提供者列表,而後經過某種機制去選擇一個服務提供者。node

服務發現

kubernetes提供的服務發現

提供的服務發現主要是經過API rest 來提供,包含下面幾個rolegit

  • node
  • service
  • pod
  • endpoints
  • ingress

本質上是kubernetes中內置了一些exporer,prometheus能夠經過http請求抓取數據。
prometheus會經過不一樣的role的服務發現來獲取抓取數據的鏈接。github

抓取到的數據是time series格式,用於存放到prometheus中的時間序列數據庫。抓取到的數據中包含大量以 __meta 開頭的標籤,用於提供相關對象中的字段信息正則表達式

下面分別說明這些role提供的數據類型,數據庫

node

  • __meta_kubernetes_node_name
  • __meta_kubernetes_node_label_
  • __meta_kubernetes_node_labelpresent_
  • __meta_kubernetes_node_annotation_
  • __meta_kubernetes_node_annotationpresent_
  • __meta_kubernetes_node_address_<address_type>

經過看後面可發現,node對象是集羣資源,不是namespace資源,所以node類型的服務發現中沒有 __meta_kubernetes_namespace 標籤後端

service

  • __meta_kubernetes_namespace
  • __meta_kubernetes_service_annotation_
  • __meta_kubernetes_service_annotationpresent_
  • __meta_kubernetes_service_cluster_ip
  • __meta_kubernetes_service_external_name
  • __meta_kubernetes_service_label_
  • __meta_kubernetes_service_labelpresent_
  • __meta_kubernetes_service_name
  • __meta_kubernetes_service_port_name
  • __meta_kubernetes_service_port_number
  • __meta_kubernetes_service_port_protocol

pod

  • __meta_kubernetes_namespace
  • __meta_kubernetes_pod_name
  • __meta_kubernetes_pod_ip
  • __meta_kubernetes_pod_label_
  • __meta_kubernetes_pod_labelpresent_
  • __meta_kubernetes_pod_annotation_
  • __meta_kubernetes_pod_annotationpresent_
  • __meta_kubernetes_pod_container_name
  • __meta_kubernetes_pod_container_port_name
  • __meta_kubernetes_pod_container_port_number
  • __meta_kubernetes_pod_container_port_protocol
  • __meta_kubernetes_pod_ready
  • __meta_kubernetes_pod_phase
  • __meta_kubernetes_pod_node_name
  • __meta_kubernetes_pod_host_ip
  • __meta_kubernetes_pod_uid
  • __meta_kubernetes_pod_controller_kind
  • __meta_kubernetes_pod_controller_name

endpoints

  • __meta_kubernetes_namespace
  • __meta_kubernetes_endpoints_name
  • __meta_kubernetes_endpoint_ready
  • __meta_kubernetes_endpoint_port_name
  • __meta_kubernetes_endpoint_port_protocol
  • __meta_kubernetes_endpoint_address_target_kind
  • __meta_kubernetes_endpoint_address_target_name

若是一個endpoint屬於某個service內,這個endpoint所屬的service的標籤也會被附到樣本數據庫上抓取過來api

若是這個endpoint的後端是pod,相應的pod的標籤也會被抓取到安全

也就是說,若是endpoint標籤有四種類型session

  • endpoint後端爲外部服務,僅僅建立endpoint對象那麼標籤只有endpoint的
  • endpoint後端爲外部服務,建立了endpoint和與之相關的service對象,那麼標籤有endpoint和service的
  • endpoint後端爲pod,那麼endpoint的標籤有endpoint和pod的
  • endpoint後端爲pod,而且建立了service對象,那麼endpoint的標籤有endpoint和service以及pod的

ingress

  • __meta_kubernetes_namespace
  • __meta_kubernetes_ingress_name
  • __meta_kubernetes_ingress_label_
  • __meta_kubernetes_ingress_labelpresent_
  • __meta_kubernetes_ingress_annotation_
  • __meta_kubernetes_ingress_annotationpresent_
  • __meta_kubernetes_ingress_scheme
  • __meta_kubernetes_ingress_path

prometheus中使用

配置字段

prometheus中提供了 kubernetes_sd_config 的配置字段,主要的配置字段以下ide

複製

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
# 留空就是默認在kubernetes中部署
[ api_server: <host> ]

# 經過什麼樣的role來使用服務發現
role: <role>

# 下面主要是認證信息,用下面的認證信息去訪問API server

# http基本認證
basic_auth:
  [ username: <string> ]
  [ password: <secret> ]
  [ password_file: <string> ]

# token信息認證
[ bearer_token: <secret> ]

# 使用token文件認證
[ bearer_token_file: <filename> ]

# 使用代理訪問API server
[ proxy_url: <string> ]

# 配置訪問API server的ssl證書
tls_config:
  [ <tls_config> ]

# 在哪一個namespace中抓取數據,留空就是全部namespace
namespaces:
  names:
    [ - <string> ]

詳細使用

咱們基於prometheus提供的示例配置文件以及prometheus chart的配置文件來講明

對接kubernetes的服務發現須要下面幾個步驟:

  • prometheus獲取 API server 的鏈接信息
  • 經過APIserver和相應的role獲取服經過務發現獲得的採集數據服務地址
  • 對採集服務的服務地址作認證配置
  • 採集服務收到prometheus通過認證的請求後進行受權過程

經過上面的配置字段咱們知道,若是prometheus部署在kubernetes中就不用配置字段 api_server 的值。可是要配置訪問API server認證的信息。訪問API server中相關對象的信息須要經過受權來完成,在prometheus chart中默認會建立RBAC的受權配置yaml文件。

下面會分別介紹如何在prometheus中經過 relabel_configs 來抓取不一樣類型資源的監控數據

API server

集羣內獲取服務

二進制部署中,API server是宿主機的服務,也便是說並無在集羣service對象內。爲了讓集羣內的pod仿訪問到API server咱們須要將宿主機山的6443端口用endpoint的方式整到集羣裏面

複製

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
apiVersion: v1
kind: Endpoints
metadata:
  creationTimestamp: "2019-03-23T04:26:10Z"
  name: kubernetes
  namespace: default
  resourceVersion: "8"
subsets:
- addresses:
  - ip: 10.9.1.xxx
  ports:
  - name: https
    port: 6443
    protocol: TCP

---
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-03-23T04:26:10Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
spec:
  clusterIP: 10.68.0.1
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP

進行服務發現

由於咱們要獲取抓取數據的鏈接和端口,所以要獲取API server須要使用 endpoint role

但又由於kubernetes提供的服務發現中的role都是將全部該類型的服務提供者都獲取到,所以咱們須要經過 prometheus 中的 relabel_configs 配置字段和適當的正則表達式去篩選出符合要求的服務提供者

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- job_name: 'kubernetes-apiservers'
  # 獲取endpopit對象
  kubernetes_sd_configs:
    - role: endpoints
  # API server須要https訪問
  scheme: https
  # 引入每一個pod中的ca證書,用來完成 ssl認證
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    # 若是是對kubernetes使用的是自簽證書,可能須要將跳過安全認證打開
    insecure_skip_verify: true
  # 引入token文件 用來和serviceaccount綁定進行受權對集羣內資源信息的獲取
  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

  relabel_configs:
    #只保留與kubernetes相關的標籤
    - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
      action: keep
      #並對標籤的值進行過濾,進一步篩選
      regex: default;kubernetes;https

node

kubelet內置的模塊會提供prometeus來採集監控數據,所以訪問kubelet有兩個方法

  • 直接訪問kubelet的10250 https端口
  • 經過APIserver代理去訪問 相關認證配置複雜不推薦

經過API server代理去獲取

同API server代理訪問能夠避免node上的防火牆阻隔

複製

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
  
  # 此處獲取node role信息
  kubernetes_sd_configs:
  - role: node

  relabel_configs:
    #此處的labelmap用來對(.+)篩選出來的內容作標籤映射
    # 標籤 __meta_kubernetes_node_label_beta_kubernetes_io_arch="amd64" 會映射爲 beta_kubernetes_io_arch="amd64"
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
    #將內置的__address__的標籤值替換成kubernetes.default.svc:443
  - target_label: __address__
    replacement: kubernetes.default.svc:443
    #獲取到__meta_kubernetes_node_name的值,而後經過正則表達式(.+)獲取該值,由於只有一個正則分組,因此 $1 就是標籤__meta_kubernetes_node_name的值
  - source_labels: [__meta_kubernetes_node_name]
    regex: (.+)
    # 進行抓取的url路徑
    target_label: __metrics_path__
    replacement: /api/v1/nodes/${1}/proxy/metrics

容器

容器主要經過kubelet的cadvisor模塊獲取,所以他的方式和node相似。

複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- job_name: 'kubernetes-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:
  - role: node

  relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
  - target_label: __address__
    replacement: kubernetes.default.svc:443
  - source_labels: [__meta_kubernetes_node_name]
    regex: (.+)
    target_label: __metrics_path__
    #這裏和node不同
    replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor

service endpoints

服務發現配置

若是沒有對endpoint前面的服務進行配置,prometheus服務發現並不能發現他們。endpoint要想被服務發現發現本身,須要在前面的service對象中的annotation配置一些信息,這些信息包含

  • prometheus.io/scrape 布爾值 是否需容許服務發現找到本身
  • prometheus.io/scheme https或者http 默認http
  • prometheus.io/path 默認爲 /metrics
  • prometheus.io/port 默認爲service中的port

看個示例coredns服務

複製

1
2
3
4
5
6
apiVersion: v1
kind: Service
metadata:
  annotations:
    prometheus.io/port: "9153"
    prometheus.io/scrape: "true"

在進行服務發現的時候,上面添加的註釋會映射爲相應的服務發現標籤

複製

1
2
3
4
__meta_kubernetes_service_annotation_prometheus_io_scrape
__meta_kubernetes_service_annotation_prometheus_io_scheme
__meta_kubernetes_service_annotation_prometheus_io_path
__meta_kubernetes_service_annotation_prometheus_io_port

可是在prometeus中以 meta 開頭的標籤不會放到樣本數據裏面去,所以須要咱們將 meta 開頭的標籤經過 relabel_configs 字段進行標籤轉換映射等一系列操做。

經過這些操做能夠對服務發現的資源進行一些列的處理,來更好的爲咱們監控使用。

endpoint配置

複製

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
- job_name: 'kubernetes-service-endpoints'

  #指定role爲endpoint
  kubernetes_sd_configs:
    - role: endpoints

  relabel_configs:
   # 獲取service中annotation prometheus.io/scrape信息,
   #只有值爲 true 時纔將該信息的標籤保留
    - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
      action: keep
      regex: true
  #若是是https就將__scheme__加上https
    - 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
    #這裏是將標籤__meta_kubernetes_service_label_後面的內容map爲新的標籤,標籤的值不變
    - 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
    - source_labels: [__meta_kubernetes_pod_node_name]
      action: replace
      target_label: kubernetes_node

service 發現

這個是經過 blackbox exporter來實現的,須要在service註釋中添加

  • prometheus.io/probe: true

這樣就能夠經過 service role發現

複製

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-services'

    metrics_path: /probe
    #配置module模塊
    params:
      module: [http_2xx]

    kubernetes_sd_configs:
      - role: service

    relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
        action: keep
        regex: true
      - source_labels: [__address__]
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox
      - 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

pod發現

pod發現須要在pod中添加註釋

  • prometheus.io/scrape
  • prometheus.io/path
  • prometheus.io/port 默認爲9102

複製

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

ingress 發現

ingress監控是基於blackbox exporter的

複製

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
- job_name: 'kubernetes-ingresses'

  metrics_path: /probe
  params:
    module: [http_2xx]

  kubernetes_sd_configs:
  - role: ingress

  relabel_configs:

  #經過在ingress中添加定製標籤來選擇性的採集ingress對象
  - 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__
    #這裏要改成blackbox-exporter服務的服務名稱和端口號
    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
相關文章
相關標籤/搜索