本文属于 k8s 监控系列,其他文章为:node
在上一篇文章中,咱们已经在 k8s 中安装了 Prometheus,而且收集了它自身的监控指标。而在这篇文章,咱们将收集 k8s 全部组件和 pod 的监控指标。linux
在这以前须要先修改下以前监控 Prometheus 自身使用的一个配置,由于它来源于 prometheus-operator,更多的是我对它使用这个配置的理解。而咱们本身直接使用的话,没有必要搞这么麻烦,下面是修改后的内容。web
- job_name: prometheus honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - monitoring scrape_interval: 30s relabel_configs: - action: keep source_labels: - __meta_kubernetes_service_label_prometheus regex: k8s - source_labels: - __meta_kubernetes_namespace target_label: namespace - source_labels: - __meta_kubernetes_service_name target_label: service - source_labels: - __meta_kubernetes_pod_name target_label: pod - target_label: endpoint replacement: web 复制代码
这一看就懂,我也就很少作解释了。下面咱们开始进入正题,首先监控 etcd。正则表达式
以前咱们经过 curl 命令访问到了 etcd 监控指标所在的 URL,知道了它的监控指标有哪些,如今咱们要配置 Prometheus,让其收集这些监控数据。docker
以前也提到过,k8s 中 Prometheus 的监控是经过发现 endpoint 的方式进行,而 endpoint 又是 service 建立的,因此咱们须要先建立一个 etcd 的 service。centos
咱们新建一个名为 kube-etcd-service.yml
的文件,内容以下:api
apiVersion: v1 kind: Service metadata: name: kube-etcd labels: k8s-app: kube-etcd namespace: kube-system spec: clusterIP: None ports: - name: http-metrics port: 2379 protocol: TCP targetPort: 2379 selector: component: etcd type: ClusterIP 复制代码
说明:bash
component=etcd
这个标签,因此这里的选择器使用的就是这个。kubectl apply -f kube-etcd-service.yml 复制代码
建立成功后,能够经过以下命令查看它建立的 endpoint:markdown
kubectl -n kube-system get endpoints kube-etcd
复制代码
如今经过这个 endpoint 就可以访问到后面三台 etcd,如今只须要在 Prometheus 中添加对应的配置便可,配置内容以下。app
- job_name: kube-etcd honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - kube-system scheme: https tls_config: insecure_skip_verify: false ca_file: /etc/prometheus/secrets/etcd-client-cert/ca.crt cert_file: /etc/prometheus/secrets/etcd-client-cert/healthcheck-client.crt key_file: /etc/prometheus/secrets/etcd-client-cert/healthcheck-client.key relabel_configs: - action: keep source_labels: - __meta_kubernetes_service_label_k8s_app regex: kube-etcd - source_labels: - __meta_kubernetes_namespace target_label: namespace - source_labels: - __meta_kubernetes_service_name target_label: service - source_labels: - __meta_kubernetes_pod_name target_label: pod - target_label: endpoint replacement: http-metrics metric_relabel_configs: - action: drop regex: (etcd_debugging|etcd_disk|etcd_request|etcd_server|grpc_server).* source_labels: - __name__ 复制代码
由于访问 etcd 须要验证客户端证书,因此这里须要提供证书和私钥文件。这三个文件以前都已挂载到 Prometheus 容器中,直接拿来用就行。
下面的 relabel_configs
就很少提了,和前面监控 Prometheus 自身的配置差很少,最主要的仍是 metric_relabel_configs
,它是用来删除咱们不须要的监控指标的。
这里将以 etcd_debugging|etcd_disk|etcd_request|etcd_server|grpc_server
这些开头的监控指标都删掉了,大家不要学我,最好搞清楚它的做用来决定是否是将其删掉,我纯粹是看不懂因此才删的。
最后将上面的内容粘贴进 prometheus-config.yml
。当你 apply 配置文件后,不要急着 reload,由于 Prometheus 中可能没有当即更新,你能够经过 kubectl exec -it 链接到 Prometheus 的 pod 中验证下配置文件是否已经更新。
若是更新了,就直接经过下面命令让其 reload:
curl -XPOST PROMETHEUS_IP:9090/-/reload
复制代码
而后访问 Prometheus 的 web 页面,就能够在 targets 中看到 etcd 了。
apiserver 的监控方式更简单,由于它的 service 已经自动建立了。但你须要注意的是,它的 service 建立在 default 名称空间,名为 kubernetes
。
没什么好说的,直接放出 Prometheus 监控 apiserver 的配置。
- job_name: kube-apiserver honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default scrape_interval: 30s scheme: https tls_config: insecure_skip_verify: false ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt server_name: kubernetes bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: keep source_labels: - __meta_kubernetes_service_label_component regex: apiserver metric_relabel_configs: - source_labels: - __name__ action: drop regex: (apiserver_storage_data_key_generation_latencies_microseconds_bucket|apiserver_admission_controller_admission_latencies_milliseconds_bucket|apiserver_admission_step_admission_latencies_milliseconds_bucket|apiserver_admission_step_admission_latencies_milliseconds_summary|apiserver_request_latencies_bucket|apiserver_request_latencies_summary|apiserver_storage_data_key_generation_latencies_microseconds_bucket|rest_client_request_latency_seconds_bucket) 复制代码
这里由于 insecure_skip_verify
设为了 false,也就是校验服务端证书,因此这里提供了 ca 文件和 server_name。一样,这个证书事先已经挂载到了容器中,因此直接指定就行。
由于我不想关注的指标太多,因此删了一批。先声明,我是瞎删的,并不懂它们的确切意义,只是以为没啥用,因此就删了,大家别学我!
最后你看着 reload 吧。
pod 的监控指标是 kubelet 提供的,前面也已经使用 curl 命令看到了,所以这里也是直接干。
prometheus-operator 使用的一样是 endpoints 发现的方式,可是 kubelet 是操做系统的进程,并非 pod,所以经过建立 service 的方式是不可能建立对应的 endpoint 的,也不知道它为啥能够作到。
为了更通用,咱们这里是经过 node 发现的方式进行的。使用 node 发现,你没法指定端口,prometheus 会自动访问发现 node 的 10250 端口。
prometheus 的配置以下:
- job_name: pods honor_labels: true kubernetes_sd_configs: - role: node scrape_interval: 30s metrics_path: /metrics/cadvisor scheme: https tls_config: insecure_skip_verify: true bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token metric_relabel_configs: - source_labels: - __name__ regex: container_(cpu_cfs_periods_total|fs_inodes_total|fs_sector_reads_total|fs_sector_writes_total|last_seen|memory_mapped_file|spec_memory_reservation_limit_bytes|spec_memory_swap_limit_bytes|tasks_state) action: drop - source_labels: - container regex: "" action: drop - action: labeldrop regex: (id|name|pod_name|image) 复制代码
后面的 metric_relabel_configs
中,除了删除了一些我认为没用的监控指标外,还删除了全部 container 标签为空的监控指标,就像这些:
container_memory_cache{container="",container_name="",id="/",image="",name="",namespace="",pod="",pod_name=""} 2.144395264e+09 1565777155746 container_memory_cache{container="",container_name="",id="/kubepods.slice",image="",name="",namespace="",pod="",pod_name=""} 7.14027008e+08 1565777155757 container_memory_cache{container="",container_name="",id="/kubepods.slice/kubepods-besteffort.slice",image="",name="",namespace="",pod="",pod_name=""} 3.5053568e+08 1565777145294 container_memory_cache{container="",container_name="",id="/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-poda213e57700fd1325c59a70dd70f1a07d.slice",image="",name="",namespace="kube-system",pod="etcd-ops.k8s.master.01.sit",pod_name="etcd-ops.k8s.master.01.sit"} 3.09784576e+08 1565777149076 container_memory_cache{container="",container_name="",id="/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podcfdbebf5_8211_11e9_8699_005056a7c0c5.slice",image="",name="",namespace="kube-system",pod="kube-proxy-xw8sw",pod_name="kube-proxy-xw8sw"} 4.0767488e+07 1565777147425 复制代码
实在不知道这些是干啥的,并且数量很是多,干脆直接删掉。同时还删除了一些标签,好比下面这种的:
container_fs_io_current{container="coredns",container_name="coredns",device="/dev/mapper/centos-root",endpoint="https-metrics",id="/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poda9693624_85e3_11e9_80cb_005056a7c0c5.slice/docker-9b95ca870a0e7a8fde7ce116b07fc696bd91bea75f6bc61478f3ecc98f36f131.scope",image="sha256:eb516548c180f8a6e0235034ccee2428027896af16a509786da13022fe95fe8c",instance="10.99.100.2:10250",job="pods",name="k8s_coredns_coredns-fb8b8dccf-9dvh7_kube-system_a9693624-85e3-11e9-80cb-005056a7c0c5_2",namespace="kube-system",pod="coredns-fb8b8dccf-9dvh7",pod_name="coredns-fb8b8dccf-9dvh7",service="kubelet"} 复制代码
能够看到 id、name 和 image 这些标签的值很是长,很差看不说,还浪费内存和存储资源,我就都删了。它貌似会形成一个 pod 中若是有多个容器,你可能没法知道这个容器是监控指标中是哪个,由于 image 这个标签被删了。
反正我删了,你看着办。删除以后就是这样:
container_fs_io_current{container="coredns",container_name="coredns",device="/dev/mapper/centos-root",endpoint="https-metrics",instance="10.99.100.2:10250",job="pods",namespace="kube-system",pod="coredns-fb8b8dccf-9dvh7",service="kubelet"} 复制代码
固然不少标签是咱们本身建立,若是你不须要,能够在上面的 relabel_configs
中删除对应标签的配置。或许你还想删其余的标签,那你往上面的配置中加就行。
最后记得 reload。
k8s 的其余组件我就不继续监控了,包括 kubelet、controller manager、coredns 等,它们监控的手段和以前的几个组件都差很少,相信大家本身弄起来也是轻轻松松。
下面咱们会安装 kube-state-metrics,这个东西会链接 apiserver,而后将集群里的各类资源的指标都暴露出来,好比 configMap、ingress、secret、pod、deployment、statefulset 等,这是对 pod 指标的一大补充,很是有用。
由于它要访问集群内的全部资源,才能将它们的信息提供出去,所以部署它以前,先为它建立一些权限。这些权限都会绑定到一个 serviceAccount 上,而后咱们用这个 sa 运行 kube-state-metrics 就行。
kube-state-metrics-clusterRole.yml:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: kube-state-metrics rules: - apiGroups: - "" resources: - configmaps - secrets - nodes - pods - services - resourcequotas - replicationcontrollers - limitranges - persistentvolumeclaims - persistentvolumes - namespaces - endpoints verbs: - list - watch - apiGroups: - extensions resources: - daemonsets - deployments - replicasets - ingresses verbs: - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - list - watch - apiGroups: - batch resources: - cronjobs - jobs verbs: - list - watch - apiGroups: - autoscaling resources: - horizontalpodautoscalers verbs: - list - watch - apiGroups: - authentication.k8s.io resources: - tokenreviews verbs: - create - apiGroups: - authorization.k8s.io resources: - subjectaccessreviews verbs: - create - apiGroups: - policy resources: - poddisruptionbudgets verbs: - list - watch - apiGroups: - certificates.k8s.io resources: - certificatesigningrequests verbs: - list - watch 复制代码
kube-state-metrics-clusterRoleBinding.yml:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kube-state-metrics roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kube-state-metrics subjects: - kind: ServiceAccount name: kube-state-metrics namespace: monitoring 复制代码
kube-state-metrics-role.yml:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kube-state-metrics namespace: monitoring rules: - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - extensions resourceNames: - kube-state-metrics resources: - deployments verbs: - get - update - apiGroups: - apps resourceNames: - kube-state-metrics resources: - deployments verbs: - get - update 复制代码
kube-state-metrics-roleBinding.yml:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kube-state-metrics namespace: monitoring roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kube-state-metrics subjects: - kind: ServiceAccount name: kube-state-metrics 复制代码
kube-state-metrics-serviceAccount.yml:
apiVersion: v1 kind: ServiceAccount metadata: name: kube-state-metrics namespace: monitoring 复制代码
kube-state-metrics 会提供两个指标页面,一个是暴露集群内资源的,另外一个是它自身的,它自身的能够选择性的关注。
先建立 kube-state-metrics-deployment.yml:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: kube-state-metrics name: kube-state-metrics namespace: monitoring spec: replicas: 1 selector: matchLabels: app: kube-state-metrics template: metadata: labels: app: kube-state-metrics spec: containers: - args: - --port=10000 - --telemetry-port=10001 image: quay.io/coreos/kube-state-metrics:v1.6.0 name: kube-state-metrics resources: limits: cpu: 100m memory: 150Mi requests: cpu: 100m memory: 150Mi - command: - /pod_nanny - --container=kube-state-metrics - --cpu=100m - --extra-cpu=2m - --memory=150Mi - --extra-memory=30Mi - --threshold=5 - --deployment=kube-state-metrics env: - name: MY_POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: MY_POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace image: k8s.gcr.io/addon-resizer:1.8.4 name: addon-resizer resources: limits: cpu: 50m memory: 30Mi requests: cpu: 10m memory: 30Mi nodeSelector: kubernetes.io/os: linux securityContext: runAsNonRoot: true runAsUser: 65534 serviceAccountName: kube-state-metrics 复制代码
指定了两个启动参数,也就是两个端口,其中 10000 是暴露集群资源指标的端口,10001 就是它自身了。除了 kube-state-metrics 以外,还启动了 addon-resizer 这个容器,我不知道它是干啥的,反正官方怎么搞咱们怎么弄就是了。
最后是 service 文件 kube-state-metrics-service.yml:
apiVersion: v1 kind: Service metadata: labels: k8s-app: kube-state-metrics name: kube-state-metrics namespace: monitoring spec: clusterIP: None ports: - name: http-main port: 10000 targetPort: 10000 - name: http-self port: 10001 targetPort: 10001 selector: app: kube-state-metrics 复制代码
两个端口都暴露出来,你能够都收集或者只收集 10000 端口。若是只收集 10000,你能够只暴露一个端口,也能够两个都暴露,而后在 Prometheus 配置中过滤掉一个端口便可。
将上面全部的文件都 apply 以后,就能够直接配置 Prometheus 进行收集了。在此以前,你可使用 curl 命令访问它的指标页面,看看里面都有啥:
curl IP:10000/metrics
curl IP:10001/metrics
复制代码
这个 ip 地址不用我说怎么拿吧,而后你就能够看到集群资源的指标很是很是很是的多,我以为你最好对其进行过滤,将不须要的通通拒绝掉,否则对 Prometheus 形成的压力很大。
而后下面就是 Prometheus 的配置:
- job_name: kube-state-metrics honor_labels: true kubernetes_sd_configs: - role: endpoints namespaces: names: - monitoring scrape_interval: 30s scrape_timeout: 30s tls_config: insecure_skip_verify: true bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: keep source_labels: - __meta_kubernetes_service_label_k8s_app regex: kube-state-metrics - action: keep source_labels: - __meta_kubernetes_endpoint_port_name regex: http-main metric_relabel_configs: - source_labels: - __name__ regex: (kube_daemonset_status_number_ready|kube_daemonset_status_number_unavailable|kube_deployment_status_replicas_unavailable|kube_deployment_spec_paused|kube_deployment_spec_strategy_rollingupdate_max_surge|kube_deployment_spec_strategy_rollingupdate_max_unavailable|kube_endpoint_address_available|kube_endpoint_address_not_ready|kube_node_info|kube_node_spec_unschedulable|kube_node_status_condition|kube_node_status_capacity|kube_node_status_capacity|kube_node_status_allocatable|kube_persistentvolumeclaim_info|kube_persistentvolumeclaim_status_phase|kube_persistentvolumeclaim_resource_requests_storage_bytes|kube_persistentvolume_status_phase|kube_persistentvolume_info|kube_persistentvolume_capacity_bytes|kube_pod_info|kube_pod_status_phase|kube_pod_status_ready|kube_pod_container_info|kube_pod_container_status_waiting|kube_pod_container_status_waiting_reason|kube_pod_container_status_running|kube_pod_container_status_terminated_reason|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_restarts_total|kube_pod_container_resource_limits|kube_service_info|kube_statefulset_status_replicas_current|kube_statefulset_status_replicas_ready) action: keep 复制代码
配置的内容就无需我多提了,和前面监控的配置都差很少。
主要是这里删除了一大批我不关注的指标,注意我这里作的是白名单,只收集我指定的,由于不须要的实在太多,写不过来。虽然正则表达式这么长,可是因为指标名称短,且 regex 默认锚定了行首和行尾,因此匹配效率仍是很高的。
最后记得 reload。
ok,本文到此为止,下一篇会提到如何使用 grafana 和 alertmanager,谢谢!