# 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