Prometheus监控-第1天

7.1 基于Prometheus的全方位监控平台

一、打造基于Prometheus的全方位监控平台
1.1、前言
官网地址:

https://prometheus.io/docs/prometheus/latest/getting_started/

  • 灵活的时间序列数据库;
  • 定制各式各样的监控规则;
  • Prometheus的开发人员和用户社区非常活跃;
  • 独立的开源项目,不依赖于任何公司;
  • 继Kurberntes之后第二个入驻的项目;

1.2、prometheus架构

Prometheus 的工作原理主要分为五个步骤:
1. 数据采集(Exporters):Prometheus 定期通过HTTP请求从目标资源中拉取数据。目标资源可以是应用程序、系统、服务或其他资源。

数据存储(Storage):Prometheus 将采集到的数据存储在本地存储引擎中。存储引擎以时间序列方式存储数据,其中每个时间序列都由指标名称和一组键值对组成。
数据聚合(PromQL):Prometheus 通过查询表达式聚合数据。PromQL 是 Prometheus 的查询语言,它允许用户通过查询表达式从存储引擎中检索指标的特定信息。
告警处理(Alertmanager):Prometheus 可以根据用户指定的规则对数据进行警报。当指标的值超出特定阈值时,Prometheus 向 Alertmanager 发送警报。Alertmanager 可以帮助用户对警报进行分组、消除和路由,并将警报发送到相应的接收器,例如邮件、企微、钉钉等。
数据大盘(Grafana):帮助用户通过可视化方式展示 Prometheus 的数据,包括仪表盘、图表、日志和警报等。
1.3、prometheus时间序列数据
1.3.1、什么是序列数据?
时间序列数据(TimeSeries Data):按照时间顺序记录系统、设备状态变化的数据被称为时序数据。

1.3.2、时间序列数据特点
性能好:关系型数据库对于大规模数据的处理性能糟糕。NOSQL 可以比较好的处理大规模数据,依然比不上时间序列数据库。
存储成本低:高效的压缩算法,节省存储空间,有效降低 IO。
官方数据:Prometheus 有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用 3.5byte 左右空间,上百万条时间序列,30 秒间隔,保留 60 天,大概200多G。

1.3.3、Promethues适合场景
Prometheus 非常适合记录任何纯数字时间序列。它既适合以机器为中心的监控,也适合监控高度动态的面向服务的体系架构。

二、部署配置
整个监控体系涉及的技术栈较多,几乎可覆盖真实企业中的所有场景。主要技术栈如下:

  • Prometheus:监控主服务
  • node-exporter:数据采集器
  • kube-state-metrics:数据采集器
  • metrics-server:数据采集器
  • Consul:自动发现
  • blackbox:黑盒拨测
  • Alertmanager:监控告警服务
  • Grafana:数据展示服务
  • prometheusAlert:告警消息转发服务

2.1、Prometheus部署
部署对外可访问Prometheus:

  • 首先需要创建Prometheus所在命名空间;
  • 然后创建Prometheus使用的RBAC规则;
  • 创建Prometheus的configmap来保存配置文件;
  • 创建service暴露Prometheus服务;
  • 创建deployment部署Prometheus容器;
  • 最后创建Ingress实现外部域名访问Prometheus。

部署顺序如图下:

2.1.1、创建命名空间

$ kubectl create namespace monitor

2.1.2、创建RBAC规则
创建RBAC规则,包含ServiceAccount、ClusterRole、ClusterRoleBinding三类YAML文件。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: monitor
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources: ["nodes","nodes/proxy","services","endpoints","pods"]
  verbs: ["get", "list", "watch"] 
- apiGroups: ["extensions"]
  resources: ["ingress"]
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef: 
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: monitor

确认验证:

$ kubectl apply -f prometheus-rbac.yaml #创建RBAC
$ kubectl get sa prometheus -n monitor #查看
$ kubectl get clusterrole prometheus
$ kubectl get clusterrolebinding prometheus

2.1.3、创建ConfigMap类型的Prometheus配置文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitor
data:
  prometheus.yml: |
    global:
      scrape_interval:     15s
      evaluation_interval: 15s
      external_labels:
        cluster: "kubernetes"
        
    ############ 数据采集job ###################
    scrape_configs:
    - job_name: prometheus
      static_configs:
      - targets: ['127.0.0.1:9090']
        labels:
          instance: prometheus
 
    ############ 指定告警规则文件路径位置 ###################
    rule_files:
    - /etc/prometheus/rules/*.rules

确认验证:

$ kubectl apply -f prometheus-configmap.yaml
$ kubectl get cm prometheus-config -n monitor

2.1.4、创建ConfigMap类型的prometheus rules配置文件
使用ConfigMap方式创建prometheus rules配置文件:

包含的内容是两块,分别是general.rules和node.rules。使用以下命令创建Prometheus的另外两个配置文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-rules
  namespace: monitor
data:
  general.rules: |
    groups:
    - name: general.rules
      rules:
      - alert: InstanceDown
        expr: |
          up{job=~"k8s-nodes|prometheus"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} 停止工作"
          description: "{{ $labels.instance }} 主机名:{{ $labels.hostname }} 已经停止1分钟以上."

  node.rules: |
    groups:
    - name: node.rules
      rules:
      - alert: NodeFilesystemUsage
        expr: |
          100 - (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 > 85
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "Instance {{ $labels.instance }} : {{ $labels.mountpoint }} 分区使用率过高"
          description: "{{ $labels.instance }} 主机名:{{ $labels.hostname }} : {{ $labels.mountpoint }} 分区使用大于85% (当前值: {{ $value }})"

确认验证:

$ kubectl apply -f prometheus-rule.yaml
$ kubectl get cm -n monitor prometheus-rules

2.1.5、创建prometheus svc

apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitor
  labels:
    k8s-app: prometheus
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 9090
    targetPort: 9090
  selector:
    k8s-app: prometheus

2.1.6、创建prometheus deploy
由于Prometheus需要对数据进行持久化,以便在重启后能够恢复历史数据。所以这边我们通过早先课程部署的NFS做存储来实现持久化。

当前我们使用NFS提供的StorageClass来做数据存储。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus-data-pvc
  namespace: monitor
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "nfs-storage"
  resources:
    requests:
      storage: 10Gi
Prometheus控制器文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitor
  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.36.0
        imagePullPolicy: IfNotPresent
        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: 2048Mi
          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: prometheus-rules
          mountPath: /etc/prometheus/rules
      - name: configmap-reload
        image: jimmidyson/configmap-reload:v0.5.0
        imagePullPolicy: IfNotPresent
        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-data-pvc
      - name: prometheus-rules
        configMap:
          name: prometheus-rules
      - name: config
        configMap:
          name: prometheus-config

部署的 Deployment 资源文件中的 containers 部分配置了两个容器,分别是:

  • prometheus: Prometheus 容器是主容器,用于运行 Prometheus 进程。
  • configmap-reload: 用于监听指定的 ConfigMap 文件中的内容,如果内容发生更改,则执行 webhook url请求,因为 Prometheus 支持通过接口重新加载配置文件,所以这里使用这个容器提供的机制来完成 PrometheusConfigMap 配置文件内容一有更改,就执行 Prometheus 的 /-/reload 接口,进行更新配置操作。

上面资源文件中 Prometheus 参数说明:

  • –web.enable-lifecycle: 启用 Prometheus 用于重新加载配置的 /-/reload 接口
  • –config.file: 指定 Prometheus 配置文件所在地址,这个地址是相对于容器内部而言的
  • –storage.tsdb.path: 指定 Prometheus 数据存储目录地址,这个地址是相对于容器而言的
  • –storage.tsdb.retention.time: 指定删除旧数据的时间,默认为 15d
  • –web.console.libraries: 指定控制台组件依赖的存储路径
  • –web.console.templates: 指定控制台模板的存储路径

确认验证:

$ kubectl get deploy -n monitor
$ kubectl get pods -n monitor

2.1.7、创建prometheus ingress实现外部域名访问

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: monitor
  name: prometheus-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.kubernets.cn
    http:
      paths:
        - pathType: Prefix
          backend:
            service:
              name: prometheus
              port:
                number: 9090
          path: /
访问验证:
$ curl prometheus.kubernets.cn
<a href="/graph">Found</a>.

三、初识Prometheus监控平台
prometheus监控平台:
Graph:用于绘制图表,可以选择不同的时间范围、指标和标签,还可以添加多个图表进行比较。
Alert:用于设置告警规则,当指标达到设定的阈值时,会发送告警通知。
Explore:用于查询和浏览指标数据,可以通过查询表达式或者标签过滤器来查找数据。
Status:用于查看prometheus的状态信息,包括当前的targets、rules、alerts等。
Config:用于编辑prometheus的配置文件,可以添加、修改和删除配置项。
四、总结
全面的监控:Prometheus可以监控各种数据源,比如服务器、容器等,还支持度量数据和日志数据等多种类型的监控。
支持动态服务发现:Prometheus可以自动地发现并监控正在运行的服务,从而避免手动配置。(后续课程会介绍到)
灵活的告警机制:Prometheus支持可配置的告警规则,可以根据不同的情况发出不同的告警信息,并且可以通过API通知其他服务。(后续课程会介绍到)
多维数据模型:Prometheus的数据模型支持多维度的数据,可以使用标准的PromQL查询语言对数据进行分析和展示。
高效的存储:Prometheus使用自己的时间序列数据库存储数据,采用一种基于时间的存储方式,可以高效地处理大量数据。

7.2 基于Prometheus的全方位监控平台–K8S集群层面监控

一、KubeStateMetrics简介
kube-state-metrics 是一个 Kubernetes 组件,它通过查询 Kubernetes 的 API 服务器,收集关于 Kubernetes 中各种资源(如节点、pod、服务等)的状态信息,并将这些信息转换成 Prometheus 可以使用的指标。

kube-state-metrics 主要功能

  • 节点状态信息,如节点 CPU 和内存的使用情况、节点状态、节点标签等。
  • Pod 的状态信息,如 Pod 状态、容器状态、容器镜像信息、Pod 的标签和注释等。
  • Deployment、Daemonset、Statefulset 和 ReplicaSet
    等控制器的状态信息,如副本数、副本状态、创建时间等。
  • Service 的状态信息,如服务类型、服务 IP 和端口等。
  • 存储卷的状态信息,如存储卷类型、存储卷容量等。
  • Kubernetes 的 API 服务器状态信息,如 API 服务器的状态、请求次数、响应时间等。

通过 kube-state-metrics 可以方便的对 Kubernetes 集群进行监控,发现问题,以及提前预警。

二、KubeStateMetrics
包含ServiceAccount、ClusterRole、ClusterRoleBinding、Deployment、ConfigMap、Service 六类YAML文件

apiVersion: v1

kind: ServiceAccount

metadata:

  name: kube-state-metrics

  namespace: monitor

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: kube-state-metrics

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

rules:

- apiGroups: [""]

  resources:

  - configmaps

  - secrets

  - nodes

  - pods

  - services

  - resourcequotas

  - replicationcontrollers

  - limitranges

  - persistentvolumeclaims

  - persistentvolumes

  - namespaces

  - endpoints

  verbs: ["list", "watch"]

- apiGroups: ["apps"]

  resources:

  - statefulsets

  - daemonsets

  - deployments

  - replicasets

  verbs: ["list", "watch"]

- apiGroups: ["batch"]

  resources:

  - cronjobs

  - jobs

  verbs: ["list", "watch"]

- apiGroups: ["autoscaling"]

  resources:

  - horizontalpodautoscalers

  verbs: ["list", "watch"]

- apiGroups: ["networking.k8s.io", "extensions"]

  resources:

  - ingresses

  verbs: ["list", "watch"]

- apiGroups: ["storage.k8s.io"]

  resources:

  - storageclasses

  verbs: ["list", "watch"]

- apiGroups: ["certificates.k8s.io"]

  resources:

  - certificatesigningrequests

  verbs: ["list", "watch"]

- apiGroups: ["policy"]

  resources:

  - poddisruptionbudgets

  verbs: ["list", "watch"]



---

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

  name: kube-state-metrics-resizer

  namespace: monitor

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

rules:

- apiGroups: [""]

  resources:

  - pods

  verbs: ["get"]

- apiGroups: ["extensions","apps"]

  resources:

  - deployments

  resourceNames: ["kube-state-metrics"]

  verbs: ["get", "update"]

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: kube-state-metrics

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: kube-state-metrics

subjects:

- kind: ServiceAccount

  name: kube-state-metrics

  namespace: monitor

---

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

  name: kube-state-metrics

  namespace: monitor

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: Role

  name: kube-state-metrics-resizer

subjects:

- kind: ServiceAccount

  name: kube-state-metrics

  namespace: monitor



---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: kube-state-metrics

  namespace: monitor

  labels:

    k8s-app: kube-state-metrics

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    version: v1.3.0

spec:

  selector:

    matchLabels:

      k8s-app: kube-state-metrics

      version: v1.3.0

  replicas: 1

  template:

    metadata:

      labels:

        k8s-app: kube-state-metrics

        version: v1.3.0

      annotations:

        scheduler.alpha.kubernetes.io/critical-pod: ''

    spec:

      priorityClassName: system-cluster-critical

      serviceAccountName: kube-state-metrics

      containers:

      - name: kube-state-metrics

        image: k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.4.2

        ports:

        - name: http-metrics            ## 用于公开kubernetes的指标数据的端口

          containerPort: 8080           

        - name: telemetry               ##用于公开自身kube-state-metrics的指标数据的端口

          containerPort: 8081

        readinessProbe:

          httpGet:

            path: /healthz

            port: 8080

          initialDelaySeconds: 5

          timeoutSeconds: 5

      - name: addon-resizer         ##addon-resizer 用来伸缩部署在集群内的 metrics-server, kube-state-metrics等监控组件

        image: mirrorgooglecontainers/addon-resizer:1.8.6

        resources:

          limits:

            cpu: 200m

            memory: 200Mi

          requests:

            cpu: 100m

            memory: 30Mi

        env:

          - name: MY_POD_NAME

            valueFrom:

              fieldRef:

                fieldPath: metadata.name

          - name: MY_POD_NAMESPACE

            valueFrom:

              fieldRef:

                fieldPath: metadata.namespace

        volumeMounts:

          - name: config-volume

            mountPath: /etc/config

        command:

          - /pod_nanny

          - --config-dir=/etc/config

          - --container=kube-state-metrics

          - --cpu=100m

          - --extra-cpu=1m

          - --memory=100Mi

          - --extra-memory=2Mi

          - --threshold=5

          - --deployment=kube-state-metrics

      volumes:

        - name: config-volume

          configMap:

            name: kube-state-metrics-config

---

# Config map for resource configuration.

apiVersion: v1

kind: ConfigMap

metadata:

  name: kube-state-metrics-config

  namespace: monitor

  labels:

    k8s-app: kube-state-metrics

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

data:

  NannyConfiguration: |-

    apiVersion: nannyconfig/v1alpha1

    kind: NannyConfiguration



---

apiVersion: v1

kind: Service

metadata:

  name: kube-state-metrics

  namespace: monitor

  labels:

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    kubernetes.io/name: "kube-state-metrics"

  annotations:

    prometheus.io/scrape: 'true'

spec:

  ports:

  - name: http-metrics

    port: 8080

    targetPort: http-metrics

    protocol: TCP

  - name: telemetry

    port: 8081

    targetPort: telemetry

    protocol: TCP

  selector:

    k8s-app: kube-state-metrics

确认验证:

$ kubectl get all -nmonitor |grep kube-state-metrics

$ curl -kL $(kubectl get service -n monitor | grep kube-state-metrics | awk ‘{ print $3 }’):8080/metrics

2.1、新增 Kubernetes 集群架构监控
在 prometheus-config.yaml 一次添加如下采集数据:
2.1.1、kube-apiserver
需要注意的是使用https访问时,需要tls相关配置,可以指定ca证书路径或者 insecure_skip_verify: true跳过证书验证。

除此之外,还要指定 bearer_token_file,否则会提示 server returned HTTP status 400 Bad Request;

  - job_name: kube-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]
        action: keep
        regex: default;kubernetes
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

2.1.2、controller-manager
查看controller-manager信息(名称可能不太一样,大家注意一下)

xxxxxxxxxx

# kubectl describe pod -n kube-system kube-controller-manager-master1
Name:                 kube-controller-manager-k8s-master
Namespace:            kube-system
……
Labels:               component=kube-controller-manager
                      tier=control-plane

……
Containers:
  kube-controller-manager:
    ……
    Command:
      kube-controller-manager
      --allocate-node-cidrs=true
      --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
      --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
      --bind-address=127.0.0.1

由上可知,匹配pod对象,lable标签为component=kube-controller-manager即可,但需注意的是controller-manager默认只运行127.0.0.1访问,因此还需先修改controller-manager配置.

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

xxxxxxxxxx
# cat /etc/kubernetes/manifests/kube-controller-manager.yaml 

……

  - command:

    - --bind-address=0.0.0.0 # 端口改为0.0.0.0

    #- --port=0 # 注释0端口

……

编写prometheus配置文件,需要注意的是,他默认匹配到的是80端口,需要手动指定为10252端口;

xxxxxxxxxx

  - job_name: kube-controller-manager
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_component]
        regex: kube-controller-manager
        action: keep
      - source_labels: [__meta_kubernetes_pod_ip]
        regex: (.+)
        target_label: __address__
        replacement: ${1}:10252
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

2.1.3、scheduler

xxxxxxxxxx
[root@tiaoban prometheus]# kubectl describe pod -n kube-system kube-scheduler-master1
Name:                 kube-scheduler-k8s-master
Namespace:            kube-system
……
Labels:               component=kube-scheduler
                      tier=control-plane
……

由上可知,匹配pod对象,lable标签为component=kube-scheduler即可scheduler和controller-manager一样,默认监听0端口,需要注释

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

xxxxxxxxxx

$ cat /etc/kubernetes/manifests/kube-scheduler.yaml
……
  - command:
    - --bind-address=0.0.0.0 # 端口改为0.0.0.0
    #- --port=0 # 注释0端口

……

编写prometheus配置文件,需要注意的是,他默认匹配到的是80端口,需要手动指定为10251端口,同时指定token,否则会提示 server returned HTTP status 400 Bad Request;

  - job_name: kube-scheduler
      kubernetes_sd_configs:
      - role: pod
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_component]
        regex: kube-scheduler
        action: keep
      - source_labels: [__meta_kubernetes_pod_ip]
        regex: (.+)
        target_label: __address__
        replacement: ${1}:10251
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

2.1.4、kube-state-metrics
编写prometheus配置文件,需要注意的是,他默认匹配到的是8080和801两个端口,需要手动指定为8080端口;

  - job_name: kube-scheduler
      kubernetes_sd_configs:
      - role: pod
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_component]
        regex: kube-scheduler
        action: keep
      - source_labels: [__meta_kubernetes_pod_ip]
        regex: (.+)
        target_label: __address__
        replacement: ${1}:10251
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

2.1.5、coredns
编写prometheus配置文件,需要注意的是,他默认匹配到的是53端口,需要手动指定为9153端口

  - job_name: coredns
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels:
          - __meta_kubernetes_service_label_k8s_app
        regex: kube-dns
        action: keep
      - source_labels: [__meta_kubernetes_pod_ip]
        regex: (.+)
        target_label: __address__
        replacement: ${1}:9153
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: service
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

2.1.6、etcd

# kubectl describe pod -n kube-system etcd-xxxx

Name:                 etcd-master1
Namespace:            kube-system
Priority:             2000001000
Priority Class Name:  system-node-critical
Node:                 master1/192.10.192.158
Start Time:           Mon, 30 Jan 2023 15:06:35 +0800
Labels:               component=etcd
                      tier=control-plane
···
    Command:
      etcd
      --advertise-client-urls=https://192.10.192.158:2379
      --cert-file=/etc/kubernetes/pki/etcd/server.crt
      --client-cert-auth=true
      --data-dir=/var/lib/etcd
      --initial-advertise-peer-urls=https://192.10.192.158:2380
      --initial-cluster=master1=https://192.10.192.158:2380
      --key-file=/etc/kubernetes/pki/etcd/server.key
      --listen-client-urls=https://127.0.0.1:2379,https://192.10.192.158:2379
      --listen-metrics-urls=http://127.0.0.1:2381
      --listen-peer-urls=https://192.10.192.158:2380
      --name=master1
      --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 协议访问,所以要配置对应的证书。但是还需修改配置文件,地址改为0.0.0.0

编写prometheus配置文件,需要注意的是,他默认匹配到的是2379端口,需要手动指定为2381端口

  - job_name: etcd
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels:
          - __meta_kubernetes_pod_label_component
        regex: etcd
        action: keep
      - source_labels: [__meta_kubernetes_pod_ip]
        regex: (.+)
        target_label: __address__
        replacement: ${1}:2381
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

上面部分参数简介如下:

  • kubernetes_sd_configs: 设置发现模式为 Kubernetes 动态服务发现
  • kubernetes_sd_configs.role: 指定 Kubernetes 的服务发现模式,这里设置为 endpoints
    的服务发现模式,该模式下会调用 kube-apiserver 中的接口获取指标数据。并且还限定只获取 kube-state-metrics
    所在 - Namespace 的空间 kube-system 中的 Endpoints 信息
  • kubernetes_sd_configs.namespace: 指定只在配置的 Namespace 中进行 endpoints 服务发现
  • relabel_configs: 用于对采集的标签进行重新标记

热加载prometheus,使configmap配置文件生效(也可以等待prometheus的自动热加载):

$ curl -XPOST http://prometheus.kubernets.cn/-/reload

三、cAdvisor
cAdvisor 主要功能:

  • 对容器资源的使用情况和性能进行监控。它以守护进程方式运行,用于收集、聚合、处理和导出正在运行容器的有关信息。
  • cAdvisor 本身就对 Docker 容器支持,并且还对其它类型的容器尽可能的提供支持,力求兼容与适配所有类型的容器。
  • Kubernetes 已经默认将其与 Kubelet 融合,所以我们无需再单独部署 cAdvisor 组件来暴露节点中容器运行的信息。

3.1、Prometheus 添加 cAdvisor 配置
由于 Kubelet 中已经默认集成 cAdvisor 组件,所以无需部署该组件。需要注意的是,他的指标采集地址为 /metrics/cadvisor,需要配置https访问,可以设置 insecure_skip_verify: true 跳过证书验证;

  - job_name: kubelet
      metrics_path: /metrics/cadvisor
      scheme: https
      tls_config:
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - source_labels: [__meta_kubernetes_endpoints_name]
        action: replace
        target_label: endpoint
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace

热加载prometheus,使configmap配置文件生效:

$ curl -XPOST http://prometheus.kubernets.cn/-/reload

四、node-exporter
Node Exporter 是 Prometheus 官方提供的一个节点资源采集组件,可以用于收集服务器节点的数据,如 CPU频率信息、磁盘IO统计、剩余可用内存等等。

部署创建:

由于是针对所有K8S-node节点,所以我们这边使用DaemonSet这种方式;

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitor
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
     name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:latest
        ports:
        - containerPort: 9100
        resources:
          requests:
            cpu: 0.15
        securityContext:
          privileged: true
        args:
        - --path.procfs
        - /host/proc
        - --path.sysfs
        - /host/sys
        - --collector.filesystem.ignored-mount-points
        - '"^/(sys|proc|dev|host|etc)($|/)"'
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: sys
          mountPath: /host/sys
        - name: rootfs
          mountPath: /rootfs
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

node_exporter.yaml文件说明:

  • hostPID:指定是否允许Node Exporter进程绑定到主机的PID命名空间。若值为true,则可以访问宿主机中的PID信息。
  • hostIPC:指定是否允许Node Exporter进程绑定到主机的IPC命名空间。若值为true,则可以访问宿主机中的IPC信息。
  • hostNetwork:指定是否允许Node Exporter进程绑定到主机的网络命名空间。若值为true,则可以访问宿主机中的网络信息。

验证:

[root@master1 /]# curl localhost:9100/metrics |grep cpu
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since theprogram started.
# TYPE go_memstats_gc_cpu_fraction gauge
go_memstats_gc_cpu_fraction 2.7853625597758774e-06
# HELP node_cpu_guest_seconds_total Seconds the CPUs spent in guests (VMs) for each mode.
# TYPE node_cpu_guest_seconds_total counter
node_cpu_guest_seconds_total{cpu="0",mode="nice"} 0
node_cpu_guest_seconds_total{cpu="0",mode="user"} 0
node_cpu_guest_seconds_total{cpu="1",mode="nice"} 0
node_cpu_guest_seconds_total{cpu="1",mode="user"} 0
# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 1.90640354e+06
node_cpu_seconds_total{cpu="0",mode="iowait"} 6915.35
node_cpu_seconds_total{cpu="0",mode="irq"} 0
node_cpu_seconds_total{cpu="0",mode="nice"} 1426.82
node_cpu_seconds_total{cpu="0",mode="softirq"} 14446.63

4.1、新增 k8s-node 监控
在 prometheus-config.yaml 中新增采集 job:k8s-nodes

node_exporter也是每个node节点都运行,因此role使用node即可,默认address端口为10250,替换为9100即可;

- job_name: k8s-nodes

  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_(.+)

  - source_labels: [__meta_kubernetes_endpoints_name]

    action: replace

    target_label: endpoint

  - source_labels: [__meta_kubernetes_pod_name]

    action: replace

    target_label: pod

  - source_labels: [__meta_kubernetes_namespace]

    action: replace

    target_label: namespace

热加载prometheus,使configmap配置文件生效:

$ curl -XPOST http://prometheus.kubernets.cn/-/reload

五、总结

  • kube-state-metrics:将 Kubernetes API 中的各种对象状态信息转化为 Prometheus
    可以使用的监控指标数据。
  • cAdvisor:用于监视容器资源使用和性能的工具,它可以收集 CPU、内存、磁盘、网络和文件系统等方面的指标数据。
  • node-exporter:用于监控主机指标数据的收集器,它可以收集 CPU 负载、内存使用情况、磁盘空间、网络流量等各种指标数据。

这三种工具可以协同工作,为用户提供一个全面的 Kubernetes 监控方案,帮助用户更好地了解其 Kubernetes 集群和容器化应用程序的运行情况。

在Docker中使用Prometheus,可以通过docker-compose实现持久化存储。具体步骤如下: 1. 创建一个docker-compose.yml文件,在其中定义Prometheus服务和数据卷。 ``` version: '3' services: prometheus: image: prom/prometheus volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' ports: - '9090:9090' volumes: prometheus_data: ``` 在上面的配置中,我们定义了一个名为“prometheus”的服务,它使用Prometheus的官方镜像,并将配置文件和数据卷映射到宿主机上。配置文件将在后面的步骤中创建。 2. 创建Prometheus配置文件。 在宿主机上创建一个名为“prometheus.yml”的文件,并添加以下内容: ``` global: scrape_interval: 15s # 默认的采集时间为15秒 evaluation_interval: 15s # 默认的评估时间为15秒 scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['node-exporter:9100'] # node-exporter的服务名为node-exporter ``` 在上面的配置中,我们定义了两个作业(jobs):“prometheus”和“node_exporter”。第一个作业是Prometheus自身的监控,而第二个作业是用于监控主机资源的node_exporter。 3. 启动Prometheus服务。 在命令行中进入docker-compose.yml所在的目录,并输入以下命令启动服务: ``` docker-compose up -d ``` 这将在后台启动Prometheus服务,并将数据存储在名为“prometheus_data”的数据卷中。 现在,可以通过浏览器访问localhost:9090来访问Prometheus仪表板。可以在仪表板中添加监控指标并设置报警规则。 总结: 上述步骤演示了如何使用docker-compose在Docker中持久化存储Prometheus数据。通过这种方式,可以轻松地管理和监控容器化应用程序,并确保数据不会丢失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值