# 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
