Kubernetes(k8s)监控与报警(qq邮箱+钉钉):Prometheus + Grafana + Alertmanager(超详细)-Prometheus部署

时间:2024-04-15 07:04:09

3.1 创建命名空间

Kubernetes中的命名空间提供了一种组织和管理集群资源的机制,可以实现资源的逻辑隔离、权限控制、资源管理、环境隔离等功能,有助于提高集群的安全性、可管理性和可观察性。

kubectl create namespace monitor-sa

或者

kubectl create ns monitor-sa

在这里插入图片描述

3.2 创建服务账户

创建服务账户在Kubernetes中是为了实现身份认证、授权访问、安全隔离、跟踪和监控以及与其他服务集成等功能。合理使用服务账户可以提高集群的安全性、可管理性和可观察性,确保工作负载之间的安全通信和权限控制。

kubectl create serviceaccount monitor -n monitor-sa

monitor: 指定要创建的服务账户的名称为 monitor。
-n monitor-sa: 指定将服务账户创建在名为 monitor-sa 的命名空间中。

在这里插入图片描述

3.3 授权服务账户RBAC权限

kubectl create clusterrolebinding monitor-clusterrolebinding -n monitor-sa --clusterrole=cluster-admin --serviceaccount=monitor-sa:monitor

或者通过以下步骤(跳过):

1、创建一个用于创建服务账户、配置 RBAC 权限并授权给 Prometheus Pod 的 YAML 文件。

vim prometheus-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitor
  namespace: monitor-sa

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitor-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: monitor
  namespace: monitor-sa
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

2、并使用以下命令将其应用到集群中:

kubectl apply -f prometheus-rbac.yaml

在这里插入图片描述

3.4 创建数据目录

为了数据持久化,控制节点默认是存在污点的,不会调度Pod,所以在node01工作节点创建数据存目录,调度到node01。

sudo mkdir /data

sudo chmod 777 /data

在这里插入图片描述

3.5 创建Configmap存储卷

并使用以下命令将其应用到集群中:

vim prometheus-cfg.yaml

kubectl apply -f prometheus-cfg.yaml

在这里插入图片描述

最终完整的prometheus-cfg.yaml配置文件,内容如下:

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: monitor-sa
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 10s
      evaluation_interval: 1m
    scrape_configs:
    - job_name: 'kubernetes-node'
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):10250'
        replacement: '${1}:9100'
        target_label: __address__
        action: replace
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    - job_name: 'kubernetes-node-cadvisor'
      kubernetes_sd_configs:
      - role:  node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
    - job_name: 'kubernetes-apiserver'
      kubernetes_sd_configs:
      - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https
    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

配置详解:

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: monitor-sa
data:
  prometheus.yml: |   # 用于配置 Prometheus 的全局设置和抓取配置
    global:   # 全局配置
      scrape_interval: 15s   # 抓取间隔为每15秒
      scrape_timeout: 10s    # 单次抓取超时时间为10秒
      evaluation_interval: 1m   # 指标评估间隔为每1分钟
    scrape_configs:   # 抓取配置列表
    - job_name: 'kubernetes-node'   # 任务名称为 'kubernetes-node',用于监控 Kubernetes 节点
      kubernetes_sd_configs:   # 使用 Kubernetes 服务发现配置
      - role: node   # 角色为节点
      relabel_configs:   # 重标签配置
      - source_labels: [__address__]   # 源标签为 __address__
        regex: '(.*):10250'   # 使用正则表达式匹配地址端口为10250
        replacement: '${1}:9100'   # 替换为端口9100
        target_label: __address__   # 目标标签为 __address__
        action: replace   # 替换操作
      - action: labelmap   # 标签映射操作,动态生成标签
        regex: __meta_kubernetes_node_label_(.+)   # 匹配节点标签
    - job_name: 'kubernetes-node-cadvisor'   # 任务名称为 'kubernetes-node-cadvisor',用于监控 Kubernetes 节点的 cAdvisor 指标
      kubernetes_sd_configs:   # 使用 Kubernetes 服务发现配置
      - role:  node   # 角色为节点
      scheme: https   # 使用 HTTPS 访问节点
      tls_config:   # TLS 配置
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt   # CA 证书路径
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   # 令牌路径
      relabel_configs:   # 重标签配置
      - action: labelmap   # 标签映射操作,动态生成标签
        regex: __meta_kubernetes_node_label_(.+)   # 匹配节点标签
      - target_label: __address__   # 目标标签为 __address__
        replacement: kubernetes.default.svc:443   # 替换为 Kubernetes 默认服务地址
      - source_labels: [__meta_kubernetes_node_name]   # 源标签为节点名称
        regex: (.+)   # 匹配所有字符
        target_label: __metrics_path__   # 目标标签为 __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor   # 替换为 cAdvisor 指标路径
    - job_name: 'kubernetes-apiserver'   # 任务名称为 'kubernetes-apiserver',用于监控 Kubernetes API 服务器
      kubernetes_sd_configs:   # 使用 Kubernetes 服务发现配置
      - role: endpoints   # 角色为端点
      scheme: https   # 使用 HTTPS 访问端点
      tls_config:   # TLS 配置
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt   # CA 证书路径
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token   # 令牌路径
      relabel_configs:   # 重标签配置
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]   # 源标签为命名空间、服务名称和端口名称
        action: keep   # 保留标签
        regex: default;kubernetes;https   # 匹配默认命名空间、Kubernetes 服务和 HTTPS 端口
    - job_name: 'kubernetes-service-endpoints'   # 任务名称为 'kubernetes-service-endpoints',用于监控 Kubernetes 服务端点
      kubernetes_sd_configs:   # 使用 Kubernetes 服务发现配置
      - role: endpoints   # 角色为端点
      relabel_configs:   # 重标签配置
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]   # 源标签为 Prometheus 抓取注解
        action: keep   # 保留标签
        regex: true   # 匹配值为 true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]   # 源标签为 Prometheus 方案注解
        action: replace   # 替换操作
        target_label: __scheme__   # 目标标签为 __scheme__
        regex: (https?)   # 匹配值为 HTTP 或 HTTPS
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]   # 源标签为 Prometheus 路径注解
        action: replace   # 替换操作
        target_label: __metrics_path__   # 目标标签为 __metrics_path__
        regex: (.+)   # 匹配所有字符
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]   # 源标签为地址和端口注解
        action: replace   # 替换操作
        target_label: __address__   # 目标标签为 __address__
        regex: ([^:]+)(?::\d+)?;(\d+)   # 匹配地址和端口
        replacement: $1:$2   # 替换地址和端口
      - action: labelmap   # 标签映射操作,动态生成标签
        regex: __meta_kubernetes_service_label_(.+)   # 匹配服务标签
      - source_labels: [__meta_kubernetes_namespace]   # 源标签为命名空间
        action: replace   # 替换操作
        target_label: kubernetes_namespace   # 目标标签为 kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]   # 源标签为服务名称
        action: replace   # 替换操作
        target_label: kubernetes_name   # 目标标签为 kubernetes_name

3.6 通过Deployment 部署Prometheus

使用 Kubernetes 的节点亲和性(Node Affinity)功能。节点亲和性允许你指定节点选择标准,根据这些标准,Kubernetes 调度器会尝试将 Pod 调度到满足条件的节点上。

1、创建一个YAML文件描述Deployment资源,并包含Prometheus容器的配置。

vim prometheus-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server
  namespace: monitor-sa
  labels:
    app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
      component: server
    #matchExpressions:
    #- {key: app, operator: In, values: [prometheus]}
    #- {key: component, operator: In, values: [server]}
  template:
    metadata:
      labels:
        app: prometheus
        component: server
      annotations:
        prometheus.io/scrape: 'false'
    spec:
      nodeName: k8s-node01	# 指定pod调度到哪个节点上	
      serviceAccountName: monitor
      containers:
      - name: prometheus
        image: registry.aliyuncs.com/google_containers/prometheus:v2.2.1
        imagePullPolicy: IfNotPresent
        command:
          - prometheus
          - --config.file=/etc/prometheus/prometheus.yml
          - --storage.tsdb.path=/prometheus	# 数据存储目录
          - --storage.tsdb.retention=720h	# 数据保存时长
          - --web.enable-lifecycle	# 开启热加载
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/prometheus/prometheus.yml
          name: prometheus-config
          subPath: prometheus.yml
        - mountPath: /prometheus/
          name: prometheus-storage-volume
      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

配置详解:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server   # 部署名称为 prometheus-server
  namespace: monitor-sa   # 命名空间为 monitor-sa
  labels:
    app: prometheus   # 标签为 app: prometheus
spec:
  replicas: 1   # 副本数为1
  selector:
    matchLabels:
      app: prometheus   # 匹配标签为 app: prometheus
      component: server   # 匹配标签为 component: server
  template:
    metadata:
      labels:
        app: prometheus   # Pod 标签为 app: prometheus
        component: server   # Pod 标签为 component: server
      annotations:
        prometheus.io/scrape: 'false'   # Prometheus 抓取设置为 false,不抓取该 Pod 的指标
    spec:
      nodeName: k8s-node01   # 指定将 Pod 调度到节点 k8s-node01
      serviceAccountName: monitor   # 使用 serviceAccountName 为 monitor 的服务账号
      containers:
      - name: prometheus   # 容器名称为 prometheus
        image: registry.aliyuncs.com/google_containers/prometheus:v2.2.1   #  Prometheus 镜像
        imagePullPolicy: IfNotPresent   # 如果本地没有该镜像,则从远程拉取
        command:
          - prometheus   # 启动命令为 prometheus
          - --config.file=/etc/prometheus/prometheus.yml   # 指定配置文件路径
          - --storage.tsdb.path=/prometheus   # 数据存储目录路径为 /prometheus
          - --storage.tsdb.retention=720h   # 数据保存时长为720小时
          - --web.enable-lifecycle   # 开启热加载功能
        ports:
        - containerPort: 9090   # 容器监听端口为 9090
          protocol: TCP   # 使用 TCP 协议
        volumeMounts:
        - mountPath: /etc/prometheus/prometheus.yml   # 挂载配置文件路径
          name: prometheus-config   # 挂载的配置文件名称为 prometheus-config
          subPath: prometheus.yml   # 挂载的子路径为 prometheus.yml
        - mountPath: /prometheus/   # 挂载数据存储目录路径
          name: prometheus-storage-volume   # 挂载的存储卷名称为 prometheus-storage-volume
      volumes:
        - name: prometheus-config   # 配置文件卷名称为 prometheus-config
          configMap:
            name: prometheus-config   # 使用的 ConfigMap 名称为 prometheus-config
            items:
              - key: prometheus.yml   # ConfigMap 中的键为 prometheus.yml
                path: prometheus.yml   # 挂载到容器中的路径为 prometheus.yml
                mode: 0644   # 权限设置为 0644
        - name: prometheus-storage-volume   # 存储卷名称为 prometheus-storage-volume
          hostPath:
            path: /data   # 宿主机路径为 /data
            type: Directory   # 类型为目录类型

2、应用Deployment YAML文件来创建部署:

kubectl apply -f prometheus-deployment.yaml

在这里插入图片描述
3、查看prometheus是否部署成功:

kubectl get pods -n monitor-sa

在这里插入图片描述

3.7 为prometheus Pod 创建一个service 实现四层代理

prometheus 在k8s 集群中创建完成后,无法在集群外部访问。可以创建一个 NodePort 类型的 Service 代理Pod。允许通过集群节点的 IP 地址和指定的端口访问 Prometheus。

1、首先,创建一个名为 prometheus-service.yaml 的配置文件,并添加以下内容:

vim prometheus-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitor-sa
  labels:
    app: prometheus
spec:
  type: NodePort  # 指定 Service 的类型为 NodePort
  ports:
  - port: 9090  # Service 暴露的端口
    targetPort: 9090  # Pod 中运行的应用程序所监听的端口
    protocol: TCP
  selector:
    app: prometheus # 选择具有 app: prometheus 标签的 Pod
    component: server # 选择具有 component: server 标签的 Pod

2、应用配置文件

使用 kubectl apply 命令将配置文件应用到 Kubernetes 集群中:

kubectl apply -f prometheus-service.yaml

在这里插入图片描述

3、验证 Service 是否创建成功

运行以下命令来验证 Service 是否已成功创建:

kubectl get svc -n monitor-sa

在这里插入图片描述

你会看到 prometheus-service 的类型为 NodePort,它公开了端口 30766,允许外部流量访问 Prometheus 服务。

4、访问 Prometheus

现在,可以使用任何 Kubernetes 集群节点的 IP 地址和指定的 NodePort来访问 Prometheus 服务。在浏览器中访问 http://192.168.234.20:30682来访问 Prometheus。

在这里插入图片描述

在这里插入图片描述

这样,你就可以在 Kubernetes 集群外部访问 Prometheus 服务了。