Prometheus监控运维实战十五:监控Kubernetes

网友投稿 265 2022-10-23

Prometheus监控运维实战十五:监控Kubernetes

Kuberentes是一款开源容器编排产品,由Google开发并发布到社区,并在 2015 年将该项目捐献给了云原生基金会(Cloud Native Computing Foundation)。从2014年第一个版本发布以来,Kubernetes便迅速获得开源社区的追捧,包括RedHat、VMware在内的很多知名企业都加入到开发和推广的阵营。目前,Kubernets已经成为发展最快、市场占有率最高的容器编排产品。

Promehteus是一款近年来非常火热的容器监控系统,它使用go语言开发,设计思路来源于Google的Borgmom(一个监控容器平台的系统)。2016年,云原生基金会将其纳入麾下,成为该基金会继Kubernetes后,第二大开源项目。因此,Prometheus天然具有对容器的适配性,可非常方便的满足容器的监控需求,目前已成为监控Kubernetes的主要工具。

本文将介绍如何通过Prometheus监控Kubernetes集群状态的方案。(对于Kubernetes的技术细节本文不做讲解,不熟悉的朋友可先自行查看相关资料。)

一.安装Prometheus

Prometheus通过自动发现的方式获取Kubernetes集群的资源信息,因此,需要在监控集群上安装Prometheus来实现。本文通过YAML文件的方式部署Prometheus。

1. 创建命名空间

创建namespace.yml文件,内容如下

apiVersion: v1kind: Namespacemetadata: name: monitoring

执行该yml文件

$ kubectl apply -f namespace.yml namespace/monitoring created

查看命名空间,已成功创建。

$ kubectl get ns monitoringNAME STATUS AGEmonitoring Active 2m53s

2. 创建RBAC规则

RBAC为Kubernetes的授权认证方式,包括 ServiceAccount、ClusterRole、ClusterRoleBinding三类YAML文件。该规则用于授权Prometheus获取资源信息。

创建prometheus-rbac.yml文件,内容如下:

apiVersion: v1kind: ServiceAccountmetadata: name: prometheus namespace: monitoring ---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: prometheusrules:- apiGroups: [""] resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"] verbs: ["get", "list", "watch"]- apiGroups: [""] resources: ["configmaps"] verbs: ["get"]- nonResourceURLs: ["/metrics"] verbs: ["get"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: prometheusroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheussubjects:- kind: ServiceAccount name: prometheus namespace: monitoring

执行该yml文件

$ kubectl apply -f prometheus-rbac.yml serviceaccount/prometheus createdclusterrole.rbac.authorization.k8s.io/prometheus createdclusterrolebinding.rbac.authorization.k8s.io/prometheus created

查看RBAC是否创建成功

$ kubectl get sa prometheus -n monitoringNAME SECRETS AGEprometheus 1 77s$ kubectl get ClusterRole prometheus NAME CREATED ATprometheus 2021-10-24T04:30:33Z$ kubectl get ClusterRoleBinding prometheus -n monitoringNAME ROLE AGEprometheus ClusterRole/prometheus 2m20s

3. 创建Configmap

我们使用Configmap来管理Prometheus的配置文件,此处先使用默认的配置,用于启动Prometheus,后面再根据需要进行修改。

创建prometheus-config.yml文件,内容如下

apiVersion: v1kind: ConfigMapmetadata: name: prometheus-config namespace: monitoringdata: prometheus.yml: | global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090']

执行该yml文件

$ kubectl apply -f prometheus-config.yml configmap/prometheus-config created

查看configmap资源是否生成

$ kubectl get configmap prometheus-config -n monitoring NAME DATA AGEprometheus-config 1 84s

4. 部署Deployment

在完成Configmap资源创建后,我们可以开始部署Prometheus的实例了。此处,我们使用Deployment来部署Prometheus,并通过Volume挂载的方式,将Prometheus的配置文件挂载到Pod中。另外,在正式环境中建议通过PVC的方法,将收集的监控数据挂载到外部存储,避免因Pod被删除而造成数据丢失。

创建prometheus-deployment.yml文件,内容如下

apiVersion: apps/v1kind: Deploymentmetadata: name: prometheus namespace: monitoring labels: app: prometheusspec: strategy: type: Recreate replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: containers: - image: prom/prometheus:v2.20.0 name: prometheus command: - "/bin/prometheus" args: - "--config.file=/etc/prometheus/config/prometheus.yml" - "--storage.tsdb.path=/data" - "--web.enable-lifecycle" securityContext: runAsUser: 0 ports: - containerPort: 9090 protocol: TCP volumeMounts: - mountPath: "/etc/prometheus/config/" name: config - name: host-time mountPath: /etc/localtime serviceAccountName: prometheus volumes: - name: config configMap: name: prometheus-config - name: host-time hostPath: path: /etc/localtime

执行该yml文件

$ kubectl apply -f prometheus-deployment.yml deployment.apps/prometheus created

查看Prometheus实例状态

$ kubectl get deploy -n monitoringNAME READY UP-TO-DATE AVAILABLE AGEprometheus 1/1 1 1 4m53s$ kubectl get pod -n monitoring NAME READY STATUS RESTARTS AGEprometheus-fcfb4bbd7-4vgl9 1/1 Running 0 69s

5. 创建Service

创建Prometheus的Service,用于集群内外部访问。默认情况下,Service只能在集群内访问,如果希望开放给集群外部,可选方案有Ingress、NodePort、ExternalIPs、LoadBalancer等几种,此处使用LoadBalancer方式。

创建prometheus-service.yml,内容如下:

apiVersion: v1kind: Servicemetadata: labels: app: prometheus name: prometheus namespace: monitoringspec: ports: - name: "web" port: 9090 protocol: TCP targetPort: 9090 selector: app: prometheus type: LoadBalancer

执行该yml文件

$ kubectl apply -f prometheus-service.yml service/prometheus created

查看Service状态,Service已创建完成,其中Cluster-ip用于集群内部访问,External-ip则是给到集群外部访问。

$ kubectl get service prometheus -n monitoring NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEprometheus LoadBalancer 10.220.57.72 10.12.61.202 9090:31183/TCP 56s

6. 访问Prometheus界面

浏览器打开REST API 检索抓取目标,并始终与集群状态保持同步,这点非常有用。

以下几种类型的资源可被配置为服务发现的目标,对于集群的监控方案有不少,关键是看如何灵活应用这些角色发现的功能和标签。

node

该node 角色发现用于发现集群中的节点目标信息,其地址默认为节点kubelet的HTTP访问端口。目标地址默认类型顺序为NodeInternalIP,NodeExternalIP, NodeLegacyHostIP,和NodeHostName中的第一个现有地址。​

可使用的元数据标签如下:

• __meta_kubernetes_node_name:节点对象的名称。

• __meta_kubernetes_node_label_:节点对象所定义的各个label

• __meta_kubernetes_node_labelpresent_:节点对象所定义的各个label,value固定为true。

• _meta_kubernetes_node_annotation_:来自节点对象的每个注释

• _meta_kubernetes_node_annotationpresent_:来自节点对象的每个注释,value固定为true。

• _meta_kubernetes_node_address_:每个节点地址类型的第一个地址(如果存在)

此外,节点的实例标签将被设置为从API服务检索到的节点名称。

service

该Service角色发现用于发现集群中每个服务目标,并且将该服务开放的端口做为目标端口。该地址将设置为服务的Kubernetes DNS名称以及相应的服务端口。

可使用的元数据标签如下:

​​__meta_kubernetes_namespace​​: 服务对象的名称空间。 ​​__meta_kubernetes_service_annotation_​​:服务对象的每个注释。 ​​__meta_kubernetes_service_annotationpresent_​​: 服务对象的每个注释,value固定为true。 ​​__meta_kubernetes_service_cluster_ip​​:  服务对象的集群IP。 (不适用于"外部名称"类型的服务) ​​__meta_kubernetes_service_external_name​​: 服务的DNS名称。(适用于"外部名称"类型的服务) ​​__meta_kubernetes_service_label_​​: 服务对象中的每个label。 ​​__meta_kubernetes_service_labelpresent_​​: 服务对象中的每个label,value固定为true。 ​​__meta_kubernetes_service_name​​: 服务对象的名称。 ​​__meta_kubernetes_service_port_name​​: 目标服务端口的名称。 ​​__meta_kubernetes_service_port_protocol​​: 目标服务端口的协议。 ​​__meta_kubernetes_service_type​​: 服务的类型。

Pod

可使用的元数据标签如下:

​​__meta_kubernetes_namespace​​: pod对象的名称空间。 ​​__meta_kubernetes_pod_name​​: pod对象的名称。 ​​__meta_kubernetes_pod_ip​​: pod对象的pod IP。 ​​__meta_kubernetes_pod_label_​​: 来自pod对象的每个标签。 ​​__meta_kubernetes_pod_labelpresent_​​: 来自pod对象的每个标签,value固定为true。 ​​__meta_kubernetes_pod_annotation_​​: 来自pod对象的每个注释。 ​​__meta_kubernetes_pod_annotationpresent_​​: 来自pod对象的每个注释,value固定为true。 ​​__meta_kubernetes_pod_container_init​​: 如果容器是初始化容器,则value为true。 ​​__meta_kubernetes_pod_container_name​​: 目标地址指向的容器的名称。 ​​__meta_kubernetes_pod_container_port_name​​: 容器端口的名称。 ​​__meta_kubernetes_pod_container_port_number​​: 容器端口号。 ​​__meta_kubernetes_pod_container_port_protocol​​: 容器端口的协议。 ​​__meta_kubernetes_pod_ready​​: 代表pod状态是否就绪,value为true或false。 ​​__meta_kubernetes_pod_phase​​: Pod的生命周期,Value值为Pending,Running,Succeeded,Failed或Unknown 。 ​​__meta_kubernetes_pod_node_name​​: 将Pod调度到的节点的名称。 ​​__meta_kubernetes_pod_host_ip​​: pod对象的当前主机IP。 ​​__meta_kubernetes_pod_uid​​: pod对象的UID。 ​​__meta_kubernetes_pod_controller_kind​​: pod控制器的对象种类。 ​​__meta_kubernetes_pod_controller_name​​: pod控制器的名称。​

endpoints

该endpoints角色发现用于发现服务的endpoints目标,且每个endpoints的port地址会生成一个目标。如果端点由Pod支持,则该Pod的所有其他容器端口(包括未绑定到endpoints的端口)也将作为目标。

可使用的元数据标签如下:

​​__meta_kubernetes_namespace​​: endpoints对象的命名空间 ​​__meta_kubernetes_endpoints_name​​: endpoints对象的名称

对于直接从端点列表中发现的所有目标(不包括由底层pod推断出来的目标),将附加以下标签:

​​__meta_kubernetes_endpoint_hostname​​: 端点的主机名 ​​__meta_kubernetes_endpoint_node_name​​: 托管endpoints的节点名称  ​​__meta_kubernetes_endpoint_ready​​:  代表endpoint 状态是否就绪,value为true或false。 ​​__meta_kubernetes_endpoint_port_name​​: endpoint 端口的名称。 ​​__meta_kubernetes_endpoint_port_protocol​​: endpoint 端口的协议。 ​​__meta_kubernetes_endpoint_address_target_kind​​: endpo int地址目标的类型,如deployment、DaemonSet等。  ​​__meta_kubernetes_endpoint_address_target_name​​:  endpoint地址目标的名称。

ingress​

该ingress角色发现用于发现ingress的每个地址目标。该地址将设置为ingress的spec配置中指定的host。

可使用的元数据标签如下:

​​__meta_kubernetes_namespace​​: ingress 对外的命名空间。 ​​__meta_kubernetes_ingress_name​​: ingress 对象的名称。 ​​__meta_kubernetes_ingress_label_​​: ingress 对象的各个标签。 ​​__meta_kubernetes_ingress_labelpresent_​​: ingress 对象的各个标签,value为true或false。 ​​__meta_kubernetes_ingress_annotation_​​: ingress 对象的各个注释。 ​​__meta_kubernetes_ingress_annotationpresent_​​: ingress 对象的各个注释,value为true或false。 ​​__meta_kubernetes_ingress_class_name​​: ingress的spec配置中的Class名称,如果存在的话。 ​​__meta_kubernetes_ingress_scheme​​: ingress使用的协议 ,http或https。 ​​__meta_kubernetes_ingress_path​​:  ingress的spec配置中指定的路径,默认为 /

三.监控kubernetes节点

1. Daemonset部署node-exporter

创建node_exporter-daemonset.yml文件,内容如下。在spec配置中添加了tolerations,用于污点容忍,保证master节点也会部署。

apiVersion: apps/v1kind: DaemonSetmetadata: name: node-exporter namespace: monitoring labels: app: node-exporterspec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - image: prom/node-exporter name: node-exporter ports: - name: scrape containerPort: 9100 hostPort: 9100 hostNetwork: true hostPID: true securityContext: runAsUser: 0

执行该yml文件

$ kubectl apply -f node_exporter-daemonset.yml daemonset.apps/prometheus-node-exporter created

确认Daemonset及Pod状态正常

$ kubectl get daemonset -n monitoring NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEnode-exporter 3 3 3 3 3 13m$ kubectl get pod -n monitoring |grep node-exporternode-exporter-76qz8 1/1 Running 0 14mnode-exporter-8fqmm 1/1 Running 0 14mnode-exporter-w9jxd 1/1 Running 0 2m6s

2. Prometheus配置任务

在prometheus-config.yml文件中添下如下任务,并执行生效。

- job_name: 'kubernetes-node' kubernetes_sd_configs: - role: node relabel_configs: - source_labels: [__address__] regex: '(.*):10250' replacement: '${1}:9100' target_label: __address__ action: replace - action: labelmap regex: __meta_kubernetes_node_label_(.+)

注解:该任务通过node角色发现动态获取节点地址信息,并使用标签重写(Relabeling)功能重写targets目标端口为node-expoerter端口,从而实现自动监控集群节点功能。

任务生效后,可看到Prometheus已自动获取到节点信息并监控。

四. 监控容器资源

Kubernetes各节点的kubelet除包含自身的监控指标信息以外,还内置了对CAdviosr的支持。在前面的容器监控篇章中,我们知道可以通过安装CAdviosr来监控节点上的容器状态。而在Kuberentes集群中,通过Kubelet可实现类似的效果,不需要再额外安装CAdviosr。

Prometheus配置任务

prometheus-config.yml文件中添下如下任务,并执行生效。

- job_name: 'kubernetes-cadvisor' scheme: 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: - 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 - action: labelmap regex: __meta_kubernetes_node_label_(.+)

注解:该任务通过node角色发现动态获取节点地址信息。由于直接访问kubelet地址会有证书验证问题,这里使用标签重写(Relabeling)功能重写targets目标地址和地址,通过API Server提供的代理地址访问kubelet的/metrics/cadvisor。

任务生效后,可看到Prometheus已自动生成相关目标信息。

五. 监控Kube API Server

Kube API Server做为整个Kubernetes集群管理的入口服务,负责对外暴露Kuberentes API,服务的稳定与否影响着集群的可用性。通过对Kube API Server的监控,我们能够清楚API的请求处理延迟、错误和可用性等参数。

Kube API Server组件一般独立部署集群外部,运行在Master的主机上,为了能够让集群内部的应用能够与API进行交互,Kubernetes会在default的命名空间下创建一个kubernetes的Service,用于集群内部访问。

$ kubectl get service kubernetes -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORkubernetes ClusterIP 10.220.0.1 443/TCP 77d

该kubernetes服务代理的后端实际地址通过endpoints进行维护,该endpoints代理地址指向了master节点的6443端口,也即是Master上运行的Kube API Server服务端口。

$ kubectl get endpoints kubernetesNAME ENDPOINTS AGEkubernetes 10.12.61.1:6443 77d$ netstat -lnpt |grep 6443tcp6 0 0 :::6443 :::* LISTEN 30458/kube-apiserve

​因此,我们可通过Prometheus的endpoints角色发现功能,来实现Kube API Server的目标发现并监控。

Prometheus配置任务

prometheus-config.yml文件中添下如下任务,并执行生效。

- job_name: 'kubernetes-apiservers' kubernetes_sd_configs: - role: endpoints scheme: 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; - target_label: __address__ replacement: kubernetes.default.svc:443

注解:该任务通过endpoints角色发现动态获取endpoints信息,并使用标签重写(Relabeling)功能只保留符合正则表达式匹配的endpoints目标。

任务生效后,查看Prometheus已自动生成相关目标信息。

六. 监控Kubelet组件

Kubelet组件运行在集群中每个worker节点上,用于处理Master下发到本节点的任务,包括管理Pod和其中的容器。Kubelet会在Kube API Server上注册节点信息,并定期向集群汇报节点资源使用情况。Kubelet的运行状态关乎着该节点的是否可以正常工作,基于该组件的重要性,我们有必要对各个节点的kubelet进行监控。

Prometheus配置任务

prometheus-config.yml文件中添下如下任务,并执行生效。

- job_name: 'k8s-kubelet' scheme: 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__ replacement: /api/v1/nodes/${1}/proxy/metrics

​注解:该任务通过node角色发现动态获取节点地址信息。由于直接访问kubelet地址会有证书验证问题,这里使用标签重写(Relabeling)功能重写targets目标地址和地址,通过API Server提供的代理地址访问kubelet的/metrics路径。

任务生效后,查看Prometheus已自动生成相关目标信息。

七. 监控Kubernetes资源

Kubernetes资源对象包括Pod、Deployment、StatefulSets等,我们需要知道相关资源的使用情况和状态,如Pod是否正常运行。由于并不是所有资源都支持Prometheus的监控, 因此,我们需要使用开源的kube-state-metrics方案来完成获取监控指标。 kube-state-metrics是Kubernetes组织下的一个项目,它通过监听Kube API收集相关资源和对象的最新信息,并提供接口地址给到Prometheus获取指标。

1. 部署kube-state-metrics

kube-state-metrics对Kubernetes有版本要求,如下图。我们环境的Kubernetes为1.18,所以需要下载V2.0.0及以上版本。

下载项目仓库

$ git clone cd kube-state-metrics/$ kubectl apply -f examples/standard/clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics createdclusterrole.rbac.authorization.k8s.io/kube-state-metrics createddeployment.apps/kube-state-metrics createdserviceaccount/kube-state-metrics createdservice/kube-state-metrics created

​查看服务状态

$ kubectl get deploy kube-state-metrics -n kube-systemNAME READY UP-TO-DATE AVAILABLE AGEkube-state-metrics 1/1 1 1 6m20s

2. Prometheus配置任务

prometheus-config.yml文件中添下如下任务,并执行生效。

- job_name: kube-state-metrics kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name] regex: kube-state-metrics replacement: $1 action: keep - source_labels: [__address__] regex: '(.*):8080' action: keep

​任务生效后,查看Prometheus已自动生成相关目标信息。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Xilinx FPGA JTAG接口转换成USB接口的方法
下一篇:用户案例 | 腾讯医疗资讯平台云原生容器化之路
相关文章

 发表评论

暂时没有评论,来抢沙发吧~