写点什么

【云原生•监控】基于 Prometheus 的云原生集群监控 (理论 + 实践)-03

作者:Reactor2020
  • 2023-12-12
    俄罗斯
  • 本文字数:9632 字

    阅读完需:约 32 分钟

【云原生•监控】基于 Prometheus 的云原生集群监控(理论+实践)-03

k8s 服务组件指标

kubernetes云原生集群作为大规模多节点容器调度平台,在交付和部署上的巨大优势逐渐让其称为一种技术趋势,如基于工作负载快速进行扩/缩容、故障自愈、资源弹性等。

但是,另一方面kubernetes云原生集群「复杂性较高」,集群自身存在非常多的组件,如 master 节点上运行着:api-server 组件、etcd 组件、kube-scheduler 组件、kube-controller-manager 组件、coredns 组件等,node 节点上有 kubelet 组件、kube-proxy 组件等。这里还隐含着另一个问题就是:一旦云原生集群出现问题,云原生集群上部署的应用组件可能都会受到影响,「影响面比较大」

所以,作为云原生集群的运维人员,关注云原生集群组件的整体运行情况,特别是一些核心组件的运行状况,避免某些组件出现性能瓶颈、异常奔溃等导致整个云原生集群性能低下甚至不可用风险的发生,这一节我们就来重点关注下云原生集群核心组件的监控。

kubernetes 架构

在对kubernetes服务组件进行监控之前,我们要先来了解下kubernetes的架构(见下图):

kubernetes集群节点大致分为两类:控制节点和工作节点。

左边蓝色框框中就是控制节点上运行的核心组件:

  • API Server组件:API Server可以看着的整个集群的大脑,从图上可以看出基本所有组件都要和API Server组件进行交互,同时,内外部接口请求也都要经过API Server组件,如kubectl指令、client-go获取监听集群资源等。

  • ETCD组件:API Server组件作为集群的对外接口层,会接收大量外部请求,肯定需要持久化数据库存储这些元数据信息,ETCD组件就是kubernetes元数据存储的数据库。

  • Scheduler组件:kubernetes作为大规模多节点容器调度平台,可灵活的基于多种策略实现容器的调度,这就是Scheduler组件的职责。

  • Controller Manager组件:kubernetes中核心的设计理念是声明式,kubernetes集群中所有的操作都可以通过声明式的 yaml 文件将需求描述清楚,具体底层如何实现用户是无需太多关注的,这其中背后实现的逻辑就是kubernetes集群中存在的大量控制器的功劳,kubernetes二次开发主要也是自定义各种控制器,而Controller Manager组件就是管理这些控制器的管理器。

右边框框就是工作节点,控制节点相当于集群管理层,驱动着整个集群的运行,而工作节点是真正运行业务容器的节点,即将控制节点调度分配过来的任务干好即可。其核心组件:

  • kubelet组件:工作节点上最重要的一个组件就是 kubelet 组件,主要负责底层容器创建、管理、运行等,kubelet基于CRI(Container Runtime Interface)与容器运行时(Docker、containerd等)进行通信,这种标准化的接口使得kubernetes能够与不同的容器运行时进行交互,提高了系统的灵活性和可扩展性。

  • kube-proxy组件:kube-proxykubernetes集群中负责网络代理和负载均衡的重要组件,它通过转发请求、负载均衡和会话绑定等功能,确保服务的可访问性和高可用性,为应用程序提供稳定和可靠的网络服务。

API Server 组件监控

1、API Server作为kubernetes最核心的组件,当然他的监控也是非常有必要的。API Server组件部署在kube-system命名空间下:

[root@k8s-01 manifests]# kubectl get pod -n kube-system -owide -l component=kube-apiserver NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATESkube-apiserver-k8s-01   1/1     Running   2          21d   192.168.31.160   k8s-01   <none>           <none>
复制代码

并在default命名空间下创建service,并通过手工配置endpoint

[root@k8s-01 manifests]# kubectl get svc NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGEkubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   519d[root@k8s-01 manifests]# kubectl get ep kubernetes NAME         ENDPOINTS             AGEkubernetes   192.168.31.160:6443   519d
复制代码

2、因此,我们可以基于serviceendpoints服务发现:

- job_name: 'kube-apiserver'   metrics_path: metrics   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: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: kubernetes     action: keep   - source_labels: [__meta_kubernetes_endpoint_port_name]     regex: https     action: keep     - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

3、通过prometheus target界面查看采集点接入正常:

4、导入15761 dashboardAPI Server组件监控指标就展示到模板上。

比如可以看到 API Server 组件健康检查状态,API Server组件作为kubernetes集群大脑,主要对外提供API接口,所以,这里重点监控API Server组件的请求量、请求响应延迟大小、错误请求量等:

ETCD 组件监控

kubernetes集群的ETCD默认是开启暴露metrics数据的。

1、获取Etcd Pod名称:

[root@k8s-01 manifests]# kubectl edit pod etcd-k8s-01 -n kube-systemspec:  containers:  - command:    - etcd    - --advertise-client-urls=https://192.168.31.160:2379    - --cert-file=/etc/kubernetes/pki/etcd/server.crt    - --client-cert-auth=true    - --data-dir=/var/lib/etcd    - --initial-advertise-peer-urls=https://192.168.31.160:2380    - --initial-cluster=k8s-01=https://192.168.31.160:2380    - --key-file=/etc/kubernetes/pki/etcd/server.key    - --listen-client-urls=https://127.0.0.1:2379,https://192.168.31.160:2379    - --listen-metrics-urls=http://127.0.0.1:2381    - --listen-peer-urls=https://192.168.31.160:2380    - --name=k8s-01    - --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt    - --peer-client-cert-auth=true    - --peer-key-file=/etc/kubernetes/pki/etcd/peer.key    - --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt    - --snapshot-count=10000    - --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt    image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_imag
复制代码

我们可以看到启动参数里面有一个 --listen-metrics-urls=http://127.0.0.1:2381 的配置,该参数就是来指定 Metrics 接口运行在 2381 端口下面的,而且是 http 的协议,所以也不需要什么证书配置,这就比以前的版本要简单许多了,以前的版本需要用 https 协议访问,所以要配置对应的证书。

注意:这里监听的是127.0.0.1,需要修改/etc/kubernetes/manifests/etcd.yaml,将--listen-metrics-urls=http://127.0.0.1:2381修改成--listen-metrics-urls=http://0.0.0.0:2381,编辑后会自动更新 Pod(静态 Pod)。

2、创建etcd组件service服务:

apiVersion: v1kind: Servicemetadata:  name: etcd-k8s  namespace: kube-system  labels:    k8s-app: etcdspec:  type: ClusterIP  clusterIP: None  #设置为None,不分配Service IP  ports:  - name: port    port: 2381---apiVersion: v1kind: Endpointsmetadata:  name: etcd-k8s  namespace: kube-system  labels:    k8s-app: etcdsubsets:- addresses:  - ip: 192.168.31.160   # 指定etcd节点地址,如果是集群则继续向下添加    nodeName: k8s-01  ports:  - name: port    port: 2381         # Etcd 端口号
复制代码

3、prometheus监控接入:

- job_name: 'kube-etcd'   metrics_path: metrics   scheme: http   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: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: etcd-k8s     action: keep   - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

4、通过prometheus target界面查看采集点接入正常:

5、导入3973 或者 3070 dashboardETCD组件监控指标就展示到模板上。

Scheduler 组件监控

1、创建kube-scheduler组件servicekube-scheduler.yaml

apiVersion: v1kind: Servicemetadata:  namespace: kube-system  name: kube-scheduler  labels:    k8s-app: kube-schedulerspec:  selector:    component: kube-scheduler  type: ClusterIP  clusterIP: None  ports:  - name: http-metrics    port: 10251    targetPort: 10251    protocol: TCP
复制代码

2、修改/etc/kubernetes/manifests/kube-scheduler.yaml

spec:  containers:  - command:    - kube-scheduler    - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf    - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf    - --bind-address=127.0.0.1    - --kubeconfig=/etc/kubernetes/scheduler.conf    - --leader-elect=true    - --port=0    image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/kube-scheduler:v1.21.0    imagePullPolicy: IfNotPresent    livenessProbe:
复制代码

修改点主要有两处:

  • --bind-address=127.0.0.1修改成--bind-address=0.0.0.0,否则外部无法访问。

  • 使用--port标志为 HTTP 服务指定端口,你可能已经完全--port=0禁用 HTTP 服务,这里配置--port=10251

修改完成后等待重启:

[root@k8s-01 kube-scheduler]# kubectl get pod -n kube-systemz -n kube-system -owide|grep kube-schedulerkube-scheduler-k8s-01                     1/1     Running   0          5m37s   192.168.31.160   k8s-01   <none>           <none>
复制代码

在 kube-scheduler-k8s-01 组件运行的 master 节点(k8s-01)上查看端口是否开启监听:

[root@k8s-01 prometheus]# netstat -antp|grep 10251tcp6       0      0 :::10251                :::*                    LISTEN      68892/kube-schedule tcp6       0      0 192.168.31.160:10251    192.168.31.161:57196    ESTABLISHED 68892/kube-schedule [root@k8s-01 prometheus]# netstat -antp|grep 10259tcp6       0      0 :::10259                :::*                    LISTEN      68892/kube-schedule 
复制代码

--port=0 禁用时,只有 10259 HTTPS 监听端口开启,将--port=10251 配置后,10251 HTTP 监听端口也会开启。

3、prometheus监控接入:

- job_name: 'kube-scheduler'   metrics_path: metrics   scheme: http   tls_config:     ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt     insecure_skip_verify: false   bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   kubernetes_sd_configs:   - role: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: kube-scheduler     action: keep   - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

4、通过prometheus target界面查看采集点接入正常:

Controller Manager 组件

1、创建kube-scheduler组件servicekubeControllerManager.yaml

apiVersion: v1kind: Servicemetadata:  labels:    k8s-app: kube-controller-manager  name: kube-controller-manager  namespace: kube-systemspec:  selector:    component: kube-controller-manager  type: ClusterIP  clusterIP: None  ports:  - name: https-metrics    port: 10252    targetPort: 10252    protocol: TCP
复制代码

2、修改/etc/kubernetes/manifests/kube-controller-manager.yaml

spec:  containers:  - command:    - kube-scheduler    - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf    - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf    - --bind-address=127.0.0.1    - --kubeconfig=/etc/kubernetes/scheduler.conf    - --leader-elect=true    - --port=0    image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/kube-scheduler:v1.21.0    imagePullPolicy: IfNotPresent    livenessProbe:
复制代码

修改点主要有两处:

  • --bind-address=127.0.0.1修改成--bind-address=0.0.0.0,否则外部无法访问。

  • 使用--port标志为 HTTP 服务指定端口,你可能已经完全--port=0禁用 HTTP 服务,这里配置--port=10252

修改完成后等待重启:

[root@k8s-01 manifests]# kubectl get pod -n kube-systemz -n kube-system -owide|grep kube-controller-managerkube-controller-manager-k8s-01            1/1     Running   0          35s    192.168.31.160   k8s-01   <none>           <none>
复制代码

kube-controller-manager-k8s-01组件运行的master节点(k8s-01)上查看端口是否开启监听:

[root@k8s-01 manifests]# netstat -antp|grep 10252tcp6       0      0 :::10252                :::*                    LISTEN      125547/kube-control [root@k8s-01 manifests]# netstat -antp|grep 10257tcp6       0      0 :::10257                :::*                    LISTEN      125547/kube-control 
复制代码

--port=0 禁用时,只有 10257 HTTPS 监听端口开启,将--port=10251 配置后,10252 HTTP 监听端口也会开启。

3、prometheus监控接入:

- job_name: 'kube-controller-manager'   metrics_path: metrics   scheme: http   tls_config:     ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt     insecure_skip_verify: false   bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   kubernetes_sd_configs:   - role: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: kube-controller-manager     action: keep   - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

4、通过prometheus target界面查看采集点接入正常:

kubelet 组件

kubelet组件集成cAdvisor,通过/metrics/cadvisor端点暴露容器性能指标,kubelet组件还通过/metrics端点暴露自身组件指标。

1、prometheus监控接入:

- job_name: "kubelet"  kubernetes_sd_configs:    - role: node  scheme: https  tls_config:    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt    insecure_skip_verify: true  bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token  relabel_configs:    - action: labelmap      regex: __meta_kubernetes_node_label_(.+)      replacement: $1    - replacement: /metrics      target_label: __metrics_path__
复制代码

2、通过prometheus target界面查看采集点接入正常:

kube-proxy 组件

kube-proxy默认暴露两个端口,一个是 10249,在/metrics 端点暴露监控指标,另一个是 10256。可以使用netstat命令检查这两个端口是否监听:

[root@k8s-01 prometheus]# netstat -antp|grep 10256tcp6       0      0 :::10256                :::*                    LISTEN      101021/kube-proxy   [root@k8s-01 prometheus]# netstat -antp|grep 10249tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      101021/kube-proxy 
复制代码

如果需要修改监听端口,修改kubectl edit configmap kube-proxy -n kube-system,将metricsBindAddress这段修改成metricsBindAddress: 0.0.0.0:10249即可。默认监听127.0.0.1,修改:

metricsBindAddress: 0.0.0.0:10249
复制代码

然后重新启动kube-proxy这个pod

[root@k8s-01 prometheus]# kubectl get pods -n kube-system | grep kube-proxy |awk '{print $1}' | xargs kubectl delete pods -n kube-systempod "kube-proxy-75h6q" deletedpod "kube-proxy-jhnbg" deletedpod "kube-proxy-s8jmc" deleted[root@k8s-01 prometheus]# kubectl get pod -n kube-system|grep kube-proxykube-proxy-s8nhd                          1/1     Running   0          42skube-proxy-wx6vg                          1/1     Running   0          44skube-proxy-xcq4t                          1/1     Running   0          44s
复制代码

再次使用netstat检测 10249 监听到 0.0.0.0 上:

[root@k8s-01 prometheus]# netstat -antp|grep 10249tcp6       0      0 :::10249                :::*                    LISTEN      109228/kube-proxy   tcp6       0      0 192.168.31.160:10249    192.168.31.161:57096    ESTABLISHED 109228/kube-proxy
复制代码

1、创建service

# vi kube-proxy-service.yamlapiVersion: v1kind: Servicemetadata:  labels:    k8s-app: kube-proxy  name: kube-proxy  namespace: kube-systemspec:  selector:    k8s-app: kube-proxy  type: ClusterIP  clusterIP: None  ports:  - name: https-metrics    port: 10249    targetPort: 10249    protocol: TCP
复制代码

2、prometheus监控接入:

- job_name: 'kube-proxy'   metrics_path: metrics   scheme: http   tls_config:     ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt     insecure_skip_verify: false   bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   kubernetes_sd_configs:   - role: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: kube-proxy     action: keep   - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

3、通过prometheus target界面查看采集点接入正常:

CoreDNS

kubernetes集群中非常重要的CoreDNS插件,一般默认情况下就开启了 /metrics 接口:

kubectl get cm coredns -n kube-system -o yaml
复制代码

上面ConfigMapprometheus :9153 就是开启prometheus的插件:

[root@k8s-01 ~]# kubectl get pods -n kube-system -l k8s-app=kube-dns -o wideNAME                      READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATEScoredns-b98666c6d-cdhwp   1/1     Running   2          80d   192.165.61.208   k8s-01   <none>           <none>coredns-b98666c6d-zmg8t   1/1     Running   2          80d   192.165.61.206   k8s-01   <none>           <none>
复制代码

我们可以先尝试手动访问下 /metrics 接口,如果能够手动访问到那证明接口是没有任何问题的:

[root@k8s-01 ~]# curl http://192.165.61.208:9153/metrics|more# TYPE coredns_build_info gaugecoredns_build_info{goversion="go1.15.3",revision="054c9ae",version="1.8.0"} 1# HELP coredns_cache_entries The number of elements in the cache.# TYPE coredns_cache_entries gaugecoredns_cache_entries{server="dns://:53",type="denial"} 31coredns_cache_entries{server="dns://:53",type="success"} 7# HELP coredns_cache_hits_total The count of cache hits.# TYPE coredns_cache_hits_total countercoredns_cache_hits_total{server="dns://:53",type="denial"} 23coredns_cache_hits_total{server="dns://:53",type="success"} 6# HELP coredns_cache_misses_total The count of cache misses.# TYPE coredns_cache_misses_total countercoredns_cache_misses_total{server="dns://:53"} 468
复制代码

我们可以看到可以正常访问到,从这里可以看到CoreDNS的监控数据接口是正常的了,然后我们就可以将这个 /metrics 接口配置到 prometheus.yml 中去。

默认,以在kube-system命名空间下创建了CoreDNS组件的service

[root@k8s-01 kube-dns]# kubectl get svc -n kube-system|grep dnskube-dns                  ClusterIP   10.96.0.10     <none>        53/UDP,53/TCP,9153/TCP   520d
复制代码

CoreDNS组件监控接入配置:

- job_name: 'kube-dns'   metrics_path: metrics   scheme: http   tls_config:     ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt     insecure_skip_verify: false   bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   kubernetes_sd_configs:   - role: endpoints   relabel_configs:   - source_labels: [__meta_kubernetes_service_name]     regex: kube-dns     action: keep   - source_labels: [__meta_kubernetes_endpoint_port_name]     regex: metrics     action: keep    - action: labelmap     regex: __meta_kubernetes_pod_label_(.+)
复制代码

通过prometheus target界面查看采集点接入正常:


发布于: 刚刚阅读数: 5
用户头像

Reactor2020

关注

云原生监控运维 2018-09-17 加入

更多资料,请关注@reactor_2020

评论

发布
暂无评论
【云原生•监控】基于Prometheus的云原生集群监控(理论+实践)-03_监控_Reactor2020_InfoQ写作社区