服务发现就是服务提供者和服务使用者之间的服务代理。服务提供者去服务代理注册本身的服务,服务使用者去服务代理拿到可用的服务提供者列表,而后经过某种机制去选择一个服务提供者。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 |