服務發現就是服務提供者和服務使用者之間的服務代理。服務提供者去服務代理註冊本身的服務,服務使用者去服務代理拿到可用的服務提供者列表,而後經過某種機制去選擇一個服務提供者。node
提供的服務發現主要是經過API rest 來提供,包含下面幾個rolegit
本質上是kubernetes中內置了一些exporer,prometheus能夠經過http請求抓取數據。
prometheus會經過不一樣的role的服務發現來獲取抓取數據的鏈接。github
抓取到的數據是time series格式,用於存放到prometheus中的時間序列數據庫。抓取到的數據中包含大量以 __meta 開頭的標籤,用於提供相關對象中的字段信息正則表達式
下面分別說明這些role提供的數據類型,數據庫
經過看後面可發現,node對象是集羣資源,不是namespace資源,所以node類型的服務發現中沒有 __meta_kubernetes_namespace 標籤後端
若是一個endpoint屬於某個service內,這個endpoint所屬的service的標籤也會被附到樣本數據庫上抓取過來api
若是這個endpoint的後端是pod,相應的pod的標籤也會被抓取到安全
也就是說,若是endpoint標籤有四種類型session
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部署在kubernetes中就不用配置字段 api_server 的值。可是要配置訪問API server認證的信息。訪問API server中相關對象的信息須要經過受權來完成,在prometheus chart中默認會建立RBAC的受權配置yaml文件。
下面會分別介紹如何在prometheus中經過 relabel_configs 來抓取不一樣類型資源的監控數據
二進制部署中,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 |
kubelet內置的模塊會提供prometeus來採集監控數據,所以訪問kubelet有兩個方法
同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 |
若是沒有對endpoint前面的服務進行配置,prometheus服務發現並不能發現他們。endpoint要想被服務發現發現本身,須要在前面的service對象中的annotation配置一些信息,這些信息包含
看個示例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 字段進行標籤轉換映射等一系列操做。
經過這些操做能夠對服務發現的資源進行一些列的處理,來更好的爲咱們監控使用。
複製
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 |
這個是經過 blackbox exporter來實現的,須要在service註釋中添加
這樣就能夠經過 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中添加註釋
複製
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監控是基於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 |