Prometheus 来自动发现 Kubernetes 集群的节点,用到了 Prometheus 针对 Kubernetes 的服务发现机制kubernetes_sd_configs
的使用,这节课咱们来和你们一块儿了解下怎样在 Prometheus 中来自动监控 Kubernetes 中的一些经常使用资源对象。node
前面咱们和你们介绍过了在 Prometheus 中用静态的方式来监控 Kubernetes 集群中的普通应用,可是若是针对集群中众多的资源对象都采用静态的方式来进行配置的话显然是不现实的,因此一样咱们须要使用到 Prometheus 提供的其余类型的服务发现机制。git
说到容器监控咱们天然会想到cAdvisor
,咱们前面也说过cAdvisor
已经内置在了 kubelet 组件之中,因此咱们不须要单独去安装,cAdvisor
的数据路径为/api/v1/nodes/<node>/proxy/metrics
,一样咱们这里使用 node 的服务发现模式,由于每个节点下面都有 kubelet,天然都有cAdvisor
采集到的数据指标,配置以下:github
- job_name: 'kubernetes-cadvisor' kubernetes_sd_configs: - role: node scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 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__ replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
上面的配置和咱们以前配置 node-exporter 的时候几乎是同样的,区别是咱们这里使用了 https 的协议,另外须要注意的是配置了 ca.cart 和 token 这两个文件,这两个文件是 Pod 启动后自动注入进来的,经过这两个文件咱们能够在 Pod 中访问 apiserver,好比咱们这里的__address__
不在是 nodeip 了,而是 kubernetes 在集群中的服务地址,而后加上__metrics_path__
的访问路径:/api/v1/nodes/${1}/proxy/metrics/cadvisor
,如今一样更新下配置,而后查看 Targets 路径: redis
而后咱们能够切换到 Graph 路径下面查询容器相关数据,好比咱们这里来查询集群中全部 Pod 的 CPU 使用状况,这里用的数据指标是 container_cpu_usage_seconds_total,而后去除一些无效的数据,查询1分钟内的数据,因为查询到的数据都是容器相关的,最好要安装 Pod 来进行聚合,对应的promQL
语句以下:shell
sum by (pod_name)(rate(container_cpu_usage_seconds_total{image!="", pod_name!=""}[1m] ))
prometheus cadvisor graphapi
咱们能够看到上面的结果就是集群中的全部 Pod 在1分钟以内的 CPU 使用状况的曲线图,固然还有不少数据能够获取到,咱们后面在须要的时候再和你们介绍。app
apiserver 做为 Kubernetes 最核心的组件,固然他的监控也是很是有必要的,对于 apiserver 的监控咱们能够直接经过 kubernetes 的 Service 来获取:curl
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 175d
上面这个 Service 就是咱们集群的 apiserver 在集群内部的 Service 地址,要自动发现 Service 类型的服务,咱们就须要用到 role 为 Endpoints 的 kubernetes_sd_configs,咱们能够在 ConfigMap 对象中添加上一个 Endpoints 类型的服务的监控任务:函数
- job_name: 'kubernetes-apiservers' kubernetes_sd_configs: - role: endpoints
上面这个任务是定义的一个类型为endpoints
的kubernetes_sd_configs
,添加到 Prometheus 的 ConfigMap 的配置文件中,而后更新配置:工具
$ kubectl delete -f prome-cm.yaml
$ kubectl create -f prome-cm.yaml
$ # 隔一下子执行reload操做 $ kubectl get svc -n kube-ops NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus NodePort 10.102.74.90 <none> 9090:30358/TCP 14d $ curl -X POST "http://10.102.74.90:9090/-/reload"
更新完成后,咱们再去查看 Prometheus 的 Dashboard 的 target 页面:
咱们能够看到 kubernetes-apiservers 下面出现了不少实例,这是由于这里咱们使用的是 Endpoints 类型的服务发现,因此 Prometheus 把全部的 Endpoints 服务都抓取过来了,一样的,上面咱们须要的服务名为kubernetes
这个 apiserver 的服务也在这个列表之中,那么咱们应该怎样来过滤出这个服务来呢?还记得上节课的relabel_configs
吗?没错,一样咱们须要使用这个配置,只是咱们这里不是使用replace
这个动做了,而是keep
,就是只把符合咱们要求的给保留下来,哪些才是符合咱们要求的呢?咱们能够把鼠标放置在任意一个 target 上,能够查看到Before relabeling
里面全部的元数据,好比咱们要过滤的服务是 default 这个 namespace 下面,服务名为 kubernetes 的元数据,因此这里咱们就能够根据对应的__meta_kubernetes_namespace
和__meta_kubernetes_service_name
这两个元数据来 relabel
prometheus before lable
另外因为 kubernetes 这个服务对应的端口是443,须要使用 https 协议,因此这里咱们须要使用 https 的协议,对应的就须要将对应的 ca 证书配置上,以下:
- job_name: 'kubernetes-apiservers' kubernetes_sd_configs: - role: endpoints scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] action: keep regex: default;kubernetes;https
如今从新更新配置文件、从新加载 Prometheus,切换到 Prometheus 的 Targets 路径下查看:
promethues apiserver
如今能够看到 kubernetes-apiserver 这个任务下面只有 apiserver 这一个实例了,证实咱们的 relabel 是成功的,如今咱们切换到 graph 路径下面查看下采集到数据,好比查询 apiserver 的总的请求数:
sum(rate(apiserver_request_count[1m]))
这里咱们使用到了 promql 里面的 rate 和 sum函数,表示的意思是 apiserver 在1分钟内总的请求数。
apiserver request count
这样咱们就完成了对 Kubernetes APIServer 的监控。
另外若是咱们要来监控其余系统组件,好比 kube-controller-manager、kube-scheduler 的话应该怎么作呢?因为 apiserver 服务 namespace 在 default 使用默认的 Service kubernetes,而其他组件服务在 kube-system 这个 namespace 下面,若是咱们想要来监控这些组件的话,须要手动建立单独的 Service,其中 kube-sheduler 的指标数据端口为 10251,kube-controller-manager 对应的端口为 10252,你们能够尝试下本身来配置下这几个系统组件。
上面的 apiserver 其实是一种特殊的 Service,如今咱们一样来配置一个任务用来专门发现普通类型的 Service:
- job_name: 'kubernetes-service-endpoints' kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] action: keep regex: true - 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 - 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
注意咱们这里在relabel_configs
区域作了大量的配置,特别是第一个保留__meta_kubernetes_service_annotation_prometheus_io_scrape
为true
的才保留下来,这就是说要想自动发现集群中的 Service,就须要咱们在 Service 的annotation
区域添加prometheus.io/scrape=true
的声明,如今咱们先将上面的配置更新,查看下效果:
service endpoints
咱们能够看到kubernetes-service-endpoints
这一个任务下面只发现了一个服务,这是由于咱们在relabel_configs
中过滤了 annotation 有prometheus.io/scrape=true
的 Service,而如今咱们系统中只有这样一个服务符合要求,因此只出现了一个实例。
如今咱们在以前建立的 redis 这个 Service 中添加上prometheus.io/scrape=true
这个 annotation:(prome-redis-exporter.yaml)
kind: Service apiVersion: v1 metadata: name: redis namespace: kube-ops annotations: prometheus.io/scrape: "true" prometheus.io/port: "9121" spec: selector: app: redis ports: - name: redis port: 6379 targetPort: 6379 - name: prom port: 9121 targetPort: 9121
因为 redis 服务的 metrics 接口在9121这个 redis-exporter 服务上面,因此咱们还须要添加一个prometheus.io/port=9121
这样的annotations
,而后更新这个 Service:
$ kubectl apply -f prome-redis-exporter.yaml
deployment.extensions "redis" unchanged service "redis" changed
更新完成后,去 Prometheus 查看 Targets 路径,能够看到 redis 服务自动出如今了kubernetes-service-endpoints
这个任务下面:
kubernetes service endpoints
这样之后咱们有了新的服务,服务自己提供了/metrics
接口,咱们就彻底不须要用静态的方式去配置了,到这里咱们就能够将以前配置的 redis 的静态配置去掉了。
你们能够尝试去将以前配置的 traefik 服务用动态发现的方式从新配置到上面的 service-endpoints 中。
一样的,你们能够本身去尝试下去配置下自动发现 Pod、ingress 这些资源对象。
上面咱们配置了自动发现 Service(Pod也是同样的)的监控,可是这些监控数据都是应用内部的监控,须要应用自己提供一个/metrics
接口,或者对应的 exporter 来暴露对应的指标数据,可是在 Kubernetes 集群上 Pod、DaemonSet、Deployment、Job、CronJob 等各类资源对象的状态也须要监控,这也反映了使用这些资源部署的应用的状态。但经过查看前面从集群中拉取的指标(这些指标主要来自 apiserver 和 kubelet 中集成的 cAdvisor),并无具体的各类资源对象的状态指标。对于 Prometheus 来讲,固然是须要引入新的 exporter 来暴露这些指标,Kubernetes 提供了一个kube-state-metrics就是咱们须要的。
kube-state-metrics 已经给出了在 Kubernetes 部署的 manifest 定义文件,咱们直接将代码 Clone 到集群中(能用 kubectl 工具操做就行):
$ git clone https://github.com/kubernetes/kube-state-metrics.git $ cd kube-state-metrics/kubernetes $ kubectl create -f . clusterrolebinding.rbac.authorization.k8s.io "kube-state-metrics" created clusterrole.rbac.authorization.k8s.io "kube-state-metrics" created deployment.apps "kube-state-metrics" created rolebinding.rbac.authorization.k8s.io "kube-state-metrics" created role.rbac.authorization.k8s.io "kube-state-metrics-resizer" created serviceaccount "kube-state-metrics" created service "kube-state-metrics" created
将 kube-state-metrics 部署到 Kubernetes 上以后,就会发现 Kubernetes 集群中的 Prometheus 会在kubernetes-service-endpoints 这个 job 下自动服务发现 kube-state-metrics,并开始拉取 metrics,这是由于部署 kube-state-metrics 的 manifest 定义文件 kube-state-metrics-service.yaml 对 Service 的定义包含prometheus.io/scrape: 'true'
这样的一个annotation
,所以 kube-state-metrics 的 endpoint 能够被 Prometheus 自动服务发现。
关于 kube-state-metrics 暴露的全部监控指标能够参考 kube-state-metrics 的文档kube-state-metrics Documentation。