kube-prometheus监控etcd

293 阅读4分钟

由于我们这里演示环境使用的是 kubeadm 搭建的集群,我们可以使用 kubectl 工具去获取 etcd 启动的相关参数:

[root@k8s-master my]# kubectl get pods -n kube-system -l component=etcd
NAME              READY   STATUS    RESTARTS        AGE
etcd-k8s-master   1/1     Running   1 (5d20h ago)   307d
[root@k8s-master my]# kubectl get pods etcd-k8s-master -n kube-system -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/etcd.advertise-client-urls: https://192.168.26.54:2379
    kubernetes.io/config.hash: 068ce7d1e63d86bf63d26b34c4648113
    kubernetes.io/config.mirror: 068ce7d1e63d86bf63d26b34c4648113
    kubernetes.io/config.seen: "2022-10-08T23:39:16.335397913+08:00"
    kubernetes.io/config.source: file
    seccomp.security.alpha.kubernetes.io/pod: runtime/default
  creationTimestamp: "2022-10-08T15:39:16Z"
  labels:
    component: etcd
    tier: control-plane
  name: etcd-k8s-master
  namespace: kube-system
  ownerReferences:
  - apiVersion: v1
    controller: true
    kind: Node
    name: k8s-master
    uid: 722e0d7f-b4a4-4202-9a87-c144b35def43
  resourceVersion: "370129"
  uid: e5e3f735-59b9-4e26-bd9c-bb85c383fbda
spec:
  containers:
  - command:
    - etcd
    - --advertise-client-urls=https://192.168.26.54: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.26.54:2380
    - --initial-cluster=k8s-master=https://192.168.26.54:2380
    - --key-file=/etc/kubernetes/pki/etcd/server.key
    - --listen-client-urls=https://127.0.0.1:2379,https://192.168.26.54:2379
    - --listen-metrics-urls=http://127.0.0.1:2381
    - --listen-peer-urls=https://192.168.26.54:2380
    - --name=k8s-master
    - --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

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

接下来我们直接创建对应的 ServiceMonitor 对象即可:

# kubernetesControlPlane-serviceMonitorEtcd.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: etcd-k8s
  namespace: monitoring
  labels:
    k8s-app: etcd-k8s
spec:
  jobLabel: k8s-app
  endpoints:
    - port: port
      interval: 15s
  selector:
    matchLabels:
      k8s-app: etcd
  namespaceSelector:
    matchNames:
      - kube-system

上面我们在 monitoring 命名空间下面创建了名为 etcd-k8s 的 ServiceMonitor 对象,基本属性和前面章节中的一致,匹配 kube-system 这个命名空间下面的具有 k8s-app=etcd 这个 label 标签的 Service,jobLabel 表示用于检索 job 任务名称的标签,由于 etcd 的 metrics 接口在 2381 端口下面,不需要 https 安全认证,所以用默认的配置即可。关于 ServiceMonitor 更多的配置属性,可以参考官方的 API 文档的描述。

然后我们直接创建这个 ServiceMonitor 对象即可:

[root@k8s-master my]#  kubectl apply -f kubernetesControlPlane-serviceMonitorEtcd.yaml
servicemonitor.monitoring.coreos.com/etcd-k8s created

但实际上现在并不能监控到 etcd 集群,因为并没有一个满足 ServiceMonitor 条件的 Service 对象与之关联:

[root@k8s-master my]#  kubectl get svc -n kube-system -l k8s-app=etcd
No resources found in kube-system namespace.

所以接下来我们需要创建一个满足上面条件的 Service 对象,由于我们把 etcd 当成是集群外部的服务,所以要引入到集群中来我们就需要自定义 Endpoints 对象来创建 Service 对象了:

apiVersion: v1
kind: Service
metadata:
  name: etcd-k8s
  namespace: kube-system
  labels:
    k8s-app: etcd
spec:
  type: ClusterIP
  clusterIP: None # 一定要设置 clusterIP:None
  ports:
    - name: port
      port: 2381
---
apiVersion: v1
kind: Endpoints
metadata:
  name: etcd-k8s
  namespace: kube-system
  labels:
    k8s-app: etcd
subsets:
  - addresses:
      - ip: 192.168.26.54 # 指定etcd节点地址,如果是集群则继续向下添加
        nodeName: etc-master
    ports:
      - name: port
        port: 2381

我们这里创建的 Service 没有采用前面通过 label 标签的形式去匹配 Pod 的做法,因为前面我们说过很多时候我们创建的 etcd 集群是独立于集群之外的,这种情况下面我们就需要自定义一个 Endpoints,要注意 metadata 区域的内容要和 Service 保持一致,Service 的 clusterIP 设置为 None,新版本的 etcd 将 metrics 接口数据放置到了 2381 端口。直接创建该资源对象即可:

[root@k8s-master my]# kubectl apply -f etcd-service.yml 
service/etcd-k8s created
endpoints/etcd-k8s created
[root@k8s-master my]#  kubectl get svc -n kube-system -l k8s-app=etcd
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
etcd-k8s   ClusterIP   None         <none>        2381/TCP   14s

创建完成后,隔一会儿去 Prometheus 的 Dashboard 中查看 targets,便会有 etcd 的监控项了:

image.png

可以看到有一个明显的错误,2381 端口链接被拒绝,这是因为我们这里的 etcd 的 metrics 接口是监听在 127.0.0.1 这个 IP 上面的,所以访问会拒绝:

--listen-metrics-urls=http://127.0.0.1:2381

我们只需要在 /etc/kubernetes/manifest/ 目录下面(静态 Pod 默认的目录)的 etcd.yaml 文件中将上面的listen-metrics-urls 更改成节点 IP 即可:

--listen-metrics-urls=http://0.0.0.0:2381

当 etcd 重启生效后,查看 etcd 这个监控任务就正常了:

image.png

数据采集到后,可以在 grafana 中导入编号为 3070 的 dashboard,就可以获取到 etcd 的监控图表:

image.png