由于我们这里演示环境使用的是 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 的监控项了:
可以看到有一个明显的错误,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 这个监控任务就正常了:
数据采集到后,可以在 grafana 中导入编号为 3070 的 dashboard,就可以获取到 etcd 的监控图表: