prometheus监控etcd

在 Kubernetes 集群的 ETCD 默认是开启暴露 metrics 数据的,不过一般来说 ETCD 部署在集群外,并且其暴露的接口是基于 HTTPS 协议。为了统一管理,我们需要将 ETCD 服务代理到 Kubernetes 集群中,然后使用 Prometheus 的 Kubernetes 动态服务发现机制,自动查找到带有指定 label 标签的 ETCD Service 服务。

Prometheus 通过服务发现机制采集 ETCD 数据的流程:

https://mydlq-club.oss-cn-beijing.aliyuncs.com/images/prometheus-etcd-cluster-1002.png?x-oss-process=style/shuiyin

prometheus监控etcd也是有两种方式:

第一种是通过在prometheus的配置文件下配置静态服务发现,将etcd的信息添加进去,通过在prometheus添加etcd的监控项来监控。

第二种是给etcd添加service服务。然后再prometheus的配置文件中添加k8s的服务发现的方式。

下面介绍下prometheus监控etcd的方法。

对于 etcd 集群一般情况下,为了安全都会开启 https 证书认证的方式,所以要想让 Prometheus 访问到 etcd 集群的监控数据,就需要提供相应的证书校验。

我这用的是kubeadm方式搭建的集群,可以使用kubectl工具去查看etcd启动的时候使用的证书路径:

kubectl -n kube-system get po etcd-k8s-master -o yaml

可以看到 etcd 使用的证书对应在节点的 /etc/kubernetes/pki/etcd 这个路径下面,所以首先我们将需要使用到的证书通过 secret 对象保存到集群中去:(在 etcd 运行的节点)

$ kubectl -n monitoring create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key --from-file=/etc/kubernetes/pki/etcd/ca.crt
secret "etcd-certs" created

如果是独立的二进制方式启动的 etcd 集群,同样将对应的证书保存到集群中的一个 secret 对象中去即可。

1.在k8s-master节点创建secret,将需要的etcd证书保存到secret对象etcd-certs中:

kubectl -n monitor-sa create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/server.key  --from-file=/etc/kubernetes/pki/etcd/server.crt --from-file=/etc/kubernetes/pki/etcd/ca.crt

2.修改prometheus-deploy.yaml文件,添加secrets,即将创建的secret对象"etcd-certs"通过volumes挂载方式,添加到prometheus-deploy.yaml部署文件中,如下所示:

 - name: k8s-certs
   mountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/
和
 - name: k8s-certs
          secret:
            secretName: etcd-certs

变成下面这样

        volumeMounts:
        - mountPath: /etc/prometheus/prometheus.yml
          name: prometheus-config
          subPath: prometheus.yml
        - mountPath: /prometheus/
          name: prometheus-storage-volume
        - name: k8s-certs
          mountPath: /var/run/secrets/kubernetes.io/k8s-certs/etcd/

      volumes:
        - name: prometheus-config
          configMap:
            name: prometheus-config
            items:
              - key: prometheus.yml
                path: prometheus.yml
                mode: 0644
        - name: prometheus-storage-volume
          hostPath:
           path: /data
           type: Directory
        - name: k8s-certs
          secret:
           secretName: etcd-certs

3.修改prometheus-cfg.yaml文件,增加如下job

 - job_name: 'kubernetes-etcd'
   scheme: https
   tls_config:
     ca_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/ca.crt
     cert_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.crt
     key_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.key
   scrape_interval: 5s
   static_configs:
   - targets: ['192.168.1.138:2379']

kubectl apply -f prometheus-cfg.yaml

kubectl delete -f prometheus-deploy.yaml
kubectl apply -f prometheus-deploy.yaml

第二种方法:

首先需要创建 ETCD 的 ServiceEndpoints 资源,将 ETCD 代理到 Kubernetes 集群内部,然后给 ETCD Service 添加指定 labels 标签 app.kubernetes.io/name: etcd,这样后续 Prometheus 会通过 Kubernetes 服务发现机制,查找到带有此标签的 Service 关联的应用列表。

将 ETCD 代理到 Kubernetes 的 EndpointsService 资源配置文件 etcd-proxy.yaml 内容如下:

apiVersion: v1
kind: Service
metadata:
  name: etcd-k8s
  namespace: kube-system
  labels:
    k8s-app: etcd                 ## Kubernetes 会根据该标签和 Endpoints 资源关联
    app.kubernetes.io/name: etcd  ## Prometheus 会根据该标签服务发现到该服务
spec:
  type: ClusterIP
  clusterIP: None                 ## 设置为 None,不分配 Service IP
  ports:
  - name: port
    port: 2379          
    protocol: TCP
---
apiVersion: v1
kind: Endpoints
metadata:
  name: etcd-k8s
  namespace: kube-system
  labels:
    k8s-app: etcd
subsets:
- addresses:                      ## 代理的应用IP地址列表
  - ip: 192.168.1.138  
  ports:
  - port: 2379                    ## 代理的应用端口号

由于 ETCD 是基于 HTTPS 协议,Prometheus 采集指标数据时需要使用 TLS 证书,所以我们需要将 ETCD 的证书文件挂载到 Kubernetes 集群的 ConfigMap 资源中。创建完后需要修改 Prometheus 部署资源的挂载配置,将证书 ConfigMap 挂载到 Prometheus 容器中。

将etcd证书文件存入configmap

进入etcd所在的服务器,将etcd证书文件挂载到kubernetes的configmap资源中,执行的命令如下:

  • -n: 命令空间。

  • –from-file: 读取指定文件,生成 ConfigMap 资源。

    $ kubectl create secret generic etcd-certs \
      --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
      --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key \
      --from-file=/etc/kubernetes/pki/etcd/ca.crt \
      -n kube-system
    

    注: 我是使用 kubeadm 安装的 Kubernetes 集群,默认 ETCD 证书会放到 /etc/kubernetes/pki/etcd/ 目录下。

接下来我们修改 Prometheus 部署资源配置,添加挂载 ETCD 证书参数,将证书文件挂入 Prometheus 应用中,内容如下:

apiVersion: v1
kind: Service
metadata:
  name: prometheus
  labels:
    k8s-app: prometheus
spec:
  type: NodePort
  ports:
  - name: http
    port: 9090
    targetPort: 9090
    nodePort: 30900
  selector:
    k8s-app: prometheus
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  labels:
    k8s-app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: prometheus
  template:
    metadata:
      labels:
        k8s-app: prometheus
    spec:
      serviceAccountName: prometheus
      containers:
      - name: prometheus
        image: prom/prometheus:v2.26.0
        ports:
        - name: http
          containerPort: 9090
        securityContext:
          runAsUser: 65534
          privileged: true
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--web.enable-lifecycle"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention.time=10d"
        - "--web.console.libraries=/etc/prometheus/console_libraries"
        - "--web.console.templates=/etc/prometheus/consoles"
        resources:
          limits:
            cpu: 2000m
            memory: 1024Mi
          requests:
            cpu: 1000m
            memory: 512Mi
        readinessProbe:
          httpGet:
            path: /-/ready
            port: 9090
          initialDelaySeconds: 5
          timeoutSeconds: 10
        livenessProbe:
          httpGet:
            path: /-/healthy
            port: 9090
          initialDelaySeconds: 30
          timeoutSeconds: 30
        volumeMounts:
        - name: data
          mountPath: /prometheus
          subPath: prometheus
        - name: config
          mountPath: /etc/prometheus
        - name: certs            #### 将ETCD证书的ConfigMap挂进Prometheus容器 
          readOnly: true
          mountPath: /certs
      - name: configmap-reload
        image: jimmidyson/configmap-reload:v0.5.0
        args:
        - "--volume-dir=/etc/config"
        - "--webhook-url=http://localhost:9090/-/reload"
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 10m
            memory: 10Mi
        volumeMounts:
        - name: config
          mountPath: /etc/config
          readOnly: true
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: prometheus
      - name: config
        configMap:
          name: prometheus-config
      - name: certs               #### 将ETCD证书的ConfigMap挂进Prometheus容器
        secret:      
          secretName: etcd-certs

接下来我们创建 Prometheus 采集 ETCD 的配置,在配置中需要指定使用的 TLS 证书参数和 Kubernetes 服务发现机制,配置内容如下:

###################### kubernetes-etcd ######################
- job_name: "kubernetes-etcd"
  scheme: https
  tls_config:
    ## 配置 ETCD 证书所在路径(Prometheus 容器内的文件路径)
    ca_file: /certs/ca.crt
    cert_file: /certs/healthcheck-client.crt
    key_file: /certs/healthcheck-client.key
    insecure_skip_verify: false
  kubernetes_sd_configs:
  ## 配置服务发现机制,指定 ETCD Service 所在的Namespace名称
  - role: endpoints
    namespaces:               
      names: ["monitor-sa"]         
  relabel_configs:
  ## 指定从 app.kubernetes.io/name 标签等于 etcd 的 service 服务获取指标信息
  - action: keep
    source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]
    regex: etcd

将etcd采集配置写入prometheus的configmap中

这里将上面 Prometheus 中的配置参数写到 Kubernetes 中的 ConfigMap 资源 prometheus-config.yaml 中,内容如下:

kind: ConfigMap
apiVersion: v1
metadata:
  name: prometheus-config
  namespace: kube-system
data:
  prometheus.yml: |
    global:
      scrape_interval:     15s
      evaluation_interval: 15s
      external_labels:
        cluster: "kubernetes"
    scrape_configs:
    ###################### kubernetes-etcd ######################
    - job_name: "kubernetes-etcd"
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/ca.crt
        cert_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.crt
        key_file: /var/run/secrets/kubernetes.io/k8s-certs/etcd/server.key
        insecure_skip_verify: false
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:               
          names: ["kube-system"]         
      relabel_configs:
      - action: keep
        source_labels: [__meta_kubernetes_service_label_app_kubernetes_io_name]
        regex: etcd    

Prometheus重新加载配置

  • -f: 指定要部署的资源文件。

  • -n: 指定 Namespace 名称。

    $ kubectl apply -f prometheus-config.yaml -n monitor-sa
    

    配置修改后需要使 Prometheus 重新加载 ConfigMap 中的参数配置,执行命令如下:

$ curl -XPOST http://192.168.1.138:30090/-/reload

重新加载prometheus的配置后,我们打开它的UI界面,查看targets一栏中是否存在etcd采集目标记录,并且检测状态是否正常。

你可能感兴趣的:(prometheus,kubernetes,容器,云原生,etcd)