一、k8s监控方案

1、监控k8s包含监控基础架构平台和监控正在运行的工作负载,利k8s本身的命令可能无法满足实际的需求,因此在实际的生产环境中,可以将k8s与外部的监控系统进行集成。

2、k8s监控主要体现在对集群的监控和对pod的监控,包括节点资源利用率、节点数、运行pod的容器指标等。

3、常用的监控工具有Prometheus、Grafana、Heapster、InfluxDB、Telegraf、Elasticsearch、Kibana、Fluentd、Datadog、cAdvisor等

4、部分监控工具介绍

   ①,Prometheus:是一种开源的系统和服务监控工具,特别使用于监控k8s集群,提供了丰富的指标收集和查询功能、并支持强大的告警和通知机制。

   ②,Grafana:它是一款用go语言开发的开源可视化监控工具,可以与Prometheus等数据源集成,提供仪表盘和图表展示,它还支持灵活的查询和可视化选项,使用户能够直观的监控k8s集群的状态。

   ③,Heapster:它是k8s集群监控和性能收集的工具(集群级别监控解决方案),用于收集和聚合集群中各个节点和容器的性能指标,它支持与多个后端存储(如InfluxDB)的集成。它会与k8s的监控进程cAdvisor进行通信,将每个node节点上的监控进程cAdvisor的监控数据进行汇总,然后导到第三方工具(如InfluxDB)中。

   ④,InfluxDB:是一个高性能的时间序列数据库,适用于保存和查询包含大量时间戳的数据。它可以与其他工具集成(如Heapster、Telegraf)作为后端存储,实现数据的收集和持久化。

   ⑤,Telegraf:是一种轻量级的数据收集代理,可用于从各种来源收集和传输指标数据,它支持多种输出插件,可以将数据发送到InfluxDB、Prometheus等目标。

   ⑥,Elasticsearch:是一个分布式搜索和分析引擎,也可以用于存储和查询监控数据,它常与Logstash和Kibana一起构成ELK堆栈,提供了强大的日志和指标分析功能。

   ⑦,Kibana:是一个数据可视化平台,与Elasticsearch集成,用于创建交互式仪表盘和图表,可以帮助用户直观的分析和可视化k8s集群的日志和指标数据。

   ⑧,Fluentd:是一个开源的日志收集代理,可用于从多个源收集、传输和转发日志数据,它支持与Elasticsearch、Kafka等工具集成。

   ⑨,Datadog:是一种云原生监控和分析平台,支持监控k8s集群的性能和健康状态。提供了实时的指标监控、告警、日志收集和可视化功能

   ⑩,cAdvisor(Container Advisor):是一个针对容器的监控工具,用于收集和展示容器的资源使用情况和性能指标,可以与其他监控工具集成,提供容器级别的监控数据。k8s已经将监控进程cAdvisor的功能集成到了kubelet组件中了。

5、Prometheus介绍

  ①、Prometheus是一开源的服务监控系统和时序数据库,特别使用于监控k8s集群,提供了丰富的指标收集和查询功能、快捷数据采集、存储和查询接口,并支持强大的告警和通知机制。它的核心组件Prometheus server会定期从静态配置的监控目标或者基于服务发现自动配置的目标中拉取数据,当拉取到的数据大于配置的内存缓存区时,数据就回持久化到存储设备中。

  ②,Prometheus特性:高纬度数据模型、自定义查询语言、可视化数据展示、高效的存储策略、易于运维、提供各种客户端开发库、警告和报警、数据导出等。

6、实验环境:

 主机名

IP地址系统版本k8s版本

master(控制节点)

192.168.1.8

centos7.9

v1.27.3

node(工作节点)

192.168.1.13

centos7.9

v1.27.3

二、部署node-exporter

node-exporter是Prometheus的一个export,主要用来收集服务器硬件资源的使用情况。

1、创建命名空间

kubectl create ns prometheus
kubectl config set-context --current --namespace=prometheus 

2、部署node-exporter

采用daemonset(守护进程集)方式,它会在符合匹配条件的节点上均部署一个pod,当有新节点加入集群时,也会为它们新增一个pod。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-export
  namespace: prometheus
  labels:
    app: node-export
spec:
  selector:
    matchLabels:
      app: node-export
  template:
    metadata:
      labels:
        app: node-export
    spec:
      containers:
      - name: node-export
        image: prom/node-exporter:v0.18.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9100
          protocol: TCP
          name: web
---

apiVersion: v1
kind: Service
metadata:
  name: node-export
  namespace: prometheus
  labels:
    app: node-export
spec:
  ports:
  type: NodePort
  - name: web
    port: 9100
    nodePort: 30001
    protocol: TCP
  selector:
    app: node-export

三,创建一个configmap资源对象的存储卷,用来存储Prometheus的配置文件

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: prometheus
  name: prometheus-config
  namespace: prometheus
data:
  prometheus.yml: |
    global:           #指定Prometheus的全局配置,比如采集间隔等
      scrape_interval: 15s      #采集目标主机监控数据的时间间隔,默认1m
      scrape_timeout: 10s     #数据采集超时时间,默认10s
      evaluation_interval: 1m       #触发告警生成alert时间,默认1m
    scrape_configs:            #配置数据源
    - job_name: 'kubernetes-node'
      kubernetes_sd_configs:              #指定k8s的服务发现
      - role: node
      relabel_configs:
      - source_labels: [__address__]          #配置的原始标签,匹配地址
        regex: '(.*):10250'          #匹配带有10250的URL
        replacement: '${1}:30001'         #把匹配到的10250的地址保留
        target_label: __address__             #新生成的URL是${1}获取到的ip:30001,这个端口是node-exporter服务暴露的端口,如果没有暴露端口(不是nodeport类型),就是实际容器的端口
        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: __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

四、部署Prometheus

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-deploy
  namespace: prometheus
  labels:
    app: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - image: prom/prometheus:v2.15.2
        imagePullPolicy: IfNotPresent
        name: prometheus
        command:
        - /bin/prometheus
        - --config.file=/etc/prometheus/prometheus.yml  #指定配置文件
        - --storage.tsdb.path=/prometheus    #数据存储目录
        - --storage.tsdb.retention=360h       #数据保存时长
        - --web.enable-lifecycle                   #开启热加载
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: "/prometheus"
          name: data
        - mountPath: "/etc/prometheus"
          name: test
      serviceAccountName: prometheus
      volumes:
      - name: data
        hostPath:
          path: /data    #挂载点
          type: Directory
      - name: test
        configMap:
          name: prometheus-config
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: prometheus
  name: prometheus-service
  namespace: prometheus
spec:
  type: NodePort
  ports:
  - port: 9090
    targetPort: 9090
    nodePort: 30002
  selector:
    app: prometheus
mkdir /data
chmod -R 777 /data

五、配置访问控制权限及k8s服务账号、集群角色绑定

#vim rbac.yaml

---
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:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---

#### 2、配置k8s服务账号及集群角色绑定

#vim access.yaml
apiVersion: v1
kind: ServiceAccount  #创建一个服务账号
metadata:
  name: prometheus
  namespace: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding            #集群角色绑定
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount           #与服务账号进行绑定
  name: prometheus
  namespace: prometheus

六,部署kube-state-metrics组件

kube-state-metrics组件会监听api server生成有关资源对象的动态指标,是为Prometheus采集k8s资源数据的exporter,能够采集绝大多数k8s内置资源的相关数据,如pod、deployment、service等,同时也提供自己的数据,主要是采集资源个数和采集发生的异常次数统计。

#vim acc-metrics.yaml

--
apiVersion: v1
kind: ServiceAccount           #服务账号
metadata:
  name: kube-state-metrics
  namespace: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole        #集群角色
metadata:
  name: kube-state-metrics
rules:
- apiGroups: [""]
  resources: ["nodes", "pods", "services", "resourcequotas", "replicationcontrollers", "limitranges", "persistentvolumeclaims", "persistentvolumes", "namespaces", "endpoints"]
  verbs: ["list", "watch"]
- apiGroups: ["extensions"]
  resources: ["daemonsets", "deployments", "replicasets"]
  verbs: ["list", "watch"]
- apiGroups: ["apps"]
  resources: ["statefulsets"]
  verbs: ["list", "watch"]
- apiGroups: ["batch"]
  resources: ["cronjobs", "jobs"]
  verbs: ["list", "watch"]
- apiGroups: ["autoscaling"]
  resources: ["horizontalpodautoscalers"]
  verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding  #集群角色绑定
metadata:
  name: kube-state-metrics
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-state-metrics
subjects:
- kind: ServiceAccount
  name: kube-state-metrics
  namespace: prometheus
```

#### 3、编写kube-state-metrics资源文件

vim kube-metrisc.yaml

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-state-metrics
  namespace: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-state-metrics
  template:
    metadata:
      labels:
        app: kube-state-metrics
    spec:
      serviceAccountName: kube-state-metrics
      containers:
      - name: kube-state-metrics
        image: quay.io/coreos/kube-state-metrics:v1.9.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    prometheus.io/scrape: 'true'
  name: kube-state-metrics
  namespace: prometheus
  labels:
    app: kube-state-metrics
spec:
  ports:
  - name: kube-state-metrics
    port: 8080
    protocol: TCP
  selector:
    app: kube-state-metrics

七,部署grafana服务

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: prometheus
  labels:
    app: grafana
spec:
  selector:
    matchLabels:
      app: grafana
  replicas: 1
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - image: grafana/grafana
        name: grafana
        imagePullPolicy: IfNotPresent
        env:
        - name: GF_AUTH_BASIC_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "false"
        readinessProbe:
          httpGet:
            path: /login
            port: 3000
        volumeMounts:
        - name: grafana-test
          mountPath: /var/lib/grafana
        - name: ca-certificates
          mountPath: /etc/ssl/certs
          readOnly: true
      volumes:
      - name: ca-certificates
        hostPath:
          path: /etc/ssl/certs
      - name: grafana-test
        hostPath:
          path: /var/lib/grafana         #挂载点,(这里的挂载点也需要手动创建,并授权)
          type: Directory
      
---

apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: prometheus
  labels:
    app: grafana
spec:
  type: NodePort
  ports:
    - port: 3000
      nodePort: 30003
  selector:
    app: grafana
#在**node**节点创建数据目录,并授权限

#注:工作节点上的存储目录不授权会报错

```
mkdir /var/lib/grafana
chmod -R 777 /var/lib/grafana

八、配置Prometheus热加载

kubectl get pods -n prometheus -o wide -l app=prometheus 
#每次修改Prometheus配置文件,就不用停止Prometheus服务了,就可以是配置生效

#也可以使用以下方法加载配置文件:
curl -X POST -Ls http://ip(prometheus pod的ip):9090/-/reload

九、应用资源,配置grafana

kubectl apply -f *.yaml

网页访问Prometheus页面(http://ip:30002)可以看到有数据展示

登录grafana,访问http://ip:30003(grafana暴露的端口),默认用户和密码是admin,登录后会提示个更改密码

添加数据源,点击DATA SOURCES

选择Prometheus类型,输入相关Prometheus属性值(name、URL等信息)

URL格式为:http://Prometheus-svc名称.命名空间.svc:9090(如果是nodeport类型,也可以输入ip+暴露的端口)

 最后点击save&test保存,出现“data source is working(数据源正在工作)”数据源创建成功

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐