kubernetes之监控Prometheus实战(一)

Prometheus介绍

Prometheus是一个最初在SoundCloud上构建的开源监控系统 它现在是一个独立的开源项目,为了强调这一点,并说明项目的治理结构,Prometheus 于2016年加入CNCF,作为继Kubernetes之后的第二个托管项目

特点

  • 具有由 metric 名称和键/值对标识的时间序列数据的多维数据模型
  • PromQL,有一个灵活的查询语言
  • 不依赖分布式存储,只和本地磁盘有关
  • 通过 HTTP 的服务拉取时间序列数据
  • 也支持推送的方式来添加时间序列数据
  • 通过服务发现或静态配置发现目标
  • 多种图形和仪表板支持

组件

Prometheus系统由多个组件组成,其中许多组件是可选的:

  • Prometheus Server:用于抓取指标、存储时间序列数据
  • exporter:暴露指标让任务来抓
  • pushgateway:push 的方式将指标数据推送到该网关
  • alertmanager:处理报警的报警组件
  • adhoc:用于数据查询

大多数 Prometheus 组件都是用 Go 编写的,因此很容易构建和部署为静态的二进制文件。

架构图

此图说明prometheus的体系结构及其一些系统组件

整体流程比较简单,Prometheus 直接接收或者通过中间的 Pushgateway 网关被动获取指标数据,在本地存储所有的获取的指标数据,并对这些数据进行一些规则整理,用来生成一些聚合数据或者报警信息,Grafana 或者其他工具用来可视化这些数据。

安装

由于 Prometheus 是 Golang 编写的程序,所以要安装的话也非常简单,只需要将二进制文件下载下来直接执行即可,前往地址:https://prometheus.io/download 下载我们对应的版本即可。

Prometheus 是通过一个 YAML 配置文件来进行启动的,如果我们使用二进制的方式来启动的话,可以使用下面的命令:

./prometheus --config.file=prometheus.yml

prometheus.yml配置文件

global:
  scrape_interval:     15s
  evaluation_interval: 15s

rule_files:
  # - "first.rules"
  # - "second.rules"

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ['localhost:9090']

配置文件中配置的三个模块:globalrule_files,和scrape_configs

global 模块是prometheus的全局配置

  • scrape_interval:表示 prometheus 抓取指标数据的频率,默认是15s,我们可以覆盖这个值
  • evaluation_interval:用来控制评估规则的频率,prometheus 使用规则产生新的时间序列数据或者产生警报

rule_files 模块制定了规则所在的位置,prometheus 可以根据这个配置加载规则,用于生成新的时间序列数据或者报警信息,当前我们没有配置任何规则。

scrape_configs 用于控制 prometheus 监控哪些资源。由于 prometheus 通过 HTTP 的方式来暴露的它本身的监控数据,prometheus 也能够监控本身的健康情况。在默认的配置里有一个单独的 job,叫做prometheus,它采集 prometheus 服务本身的时间序列数据。这个 job 包含了一个单独的、静态配置的目标:监听 localhost 上的9090端口。prometheus 默认会通过目标的/metrics路径采集 metrics。所以,默认的 job 通过 URL:http://localhost:9090/metrics采集 metrics。收集到的时间序列包含 prometheus 服务本身的状态和性能。如果我们还有其他的资源需要监控的话,直接配置在该模块下面就可以了。

在kubernetes中部署安装

这里我们把prometheus相关的服务都部署在kube-ops这个namespace下

1、我们把prometheus.yml中部署成ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-ops
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']

2、创建prometheus相关pod资源

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: prometheus
  namespace: kube-ops
  labels:
    app: prometheus
spec:
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - image: prom/prometheus:v2.6.0
        name: prometheus
        imagePullPolicy: IfNotPresent
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=7d"
        - "--web.enable-admin-api"
        - "--web.enable-lifecycle"
        ports:
        - containerPort: 9090
          name: http
        volumeMounts:
        - mountPath: "/prometheus"
          subPath: prometheus
          name: data
        - mountPath: "/etc/prometheus"
          name: config
        resources:
          requests:
            cpu: 1000m
            memory: 2Gi
          limits:
            cpu: 1000m
            memory: 2Gi
      securityContext:
        runAsUser: 0
      volumes:
      - name: config
        configMap:
          name: prometheus-config
      - name: data
        persistentVolumeClaim:
          claimName: prometheus
  • 通过storage.tsdb.path指定了 TSDB 数据的存储路径
  • 通过storage.tsdb.retention设置了保留多长时间的数据
  • 通过web.enable-admin-api参数可以用来开启对 admin api 的访问权限
  • 通过web.enable-lifecycle非常重要,用来开启支持热更新的,有了这个参数之后,prometheus.yml 配置文件只要更新了,通过执行http://localhost:9090/-/reload就会立即生效,所以一定要加上这个参数

我们这里将 prometheus.yml 文件对应的 ConfigMap 对象通过 volume 的形式挂载进了 Pod,这样 ConfigMap 更新后,对应的 Pod 里面的文件也会热更新的,然后我们再执行上面的 reload 请求,Prometheus 配置就生效了

为了将时间序列数据进行持久化,我们将数据目录和一个 pvc 对象进行了绑定,所以我们需要提前创建好这个 pvc 对象(这里我们使用的storageclass)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus
  namespace: kube-ops
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: "rook-ceph-block"

除了上面的注意事项外,我们这里还需要配置 rbac 认证,因为我们需要在 prometheus 中去访问 Kubernetes 的相关信息,所以我们这里管理了一个名为 prometheus 的 serviceAccount 对象:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: kube-ops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  - services
  - endpoints
  - pods
  - nodes/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  - nodes/metrics
  verbs:
  - get
- nonResourceURLs:
  - /metrics
  verbs:
  - get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: kube-ops

由于我们要获取的资源信息,在每一个 namespace 下面都有可能存在,所以我们这里使用的是 ClusterRole 的资源对象,值得一提的是我们这里的权限规则声明中有一个nonResourceURLs的属性,是用来对非资源型 metrics 进行操作的权限声明。

还有一个要注意的地方是我们这里必须要添加一个securityContext的属性,将其中的runAsUser设置为0,这是因为现在的 prometheus 运行过程中使用的用户是 nobody,否则会出现下面的permission denied之类的权限错误:

level=error ts=2018-10-22T14:34:58.632016274Z caller=main.go:617 err="opening storage failed: lock DB directory: open /data/lock: permission denied"

这里我们还需要一个svc服务,作为外部访问。

apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: kube-ops
  labels:
    app: prometheus
spec:
  selector:
    app: prometheus
  type: NodePort
  ports:
    - name: web
      port: 9090
      targetPort: http

文件准备完成后我们可以使用以下命令构建

kubectl apply -f .

访问

kubectl get svc -n kube-ops
NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
prometheus   NodePort   10.111.210.47   <none>        9090:31990/TCP   7d

我们可以通过任意节点访问31990端口即可访问

Kubernetes 集群的监控方案

目前主要有以下集中方案

  • Heapster: 是一个集群范围的监控和数据聚合工具,以 Pod 的形式运行在集群中。除了 Kubelet/cAdvisor 之外,我们还可以向 Heapster 添加其他指标源数据比如 kube-state-metrics
  • cAdvisor: 是Google开源的容器资源监控和性能分析工具,它是专门为容器而生,本身也支持 Docker 容器,在 Kubernetes 中,我们不需要单独去安装,cAdvisor 作为 kubelet 内置的一部分程序可以直接使用。
  • Kube-state-metrics: 通过监听 API Server 生成有关资源对象的状态指标,比如 Deployment、Node、Pod,需要注意的是 kube-state-metrics 只是简单提供一个 metrics 数据,并不会存储这些指标数据,所以我们可以使用 Prometheus 来抓取这些数据然后存储。
  • metrics-server: 也是一个集群范围内的资源数据聚合工具,是 Heapster 的替代品,同样的,metrics-server 也只是显示数据,并不提供数据存储服务。

不过 kube-state-metrics 和 metrics-server 之间还是有很大不同的,二者的主要区别如下:

  • kube-state-metrics 主要关注的是业务相关的一些元数据,比如 Deployment、Pod、副本状态等
  • metrics-server 主要关注的是资源度量 API 的实现,比如 CPU、文件描述符、内存、请求延时等指标。

监控kubernetes集群节点

对于集群的监控一般我们需要考虑以下几个方面:

  • Kubernetes 节点的监控:比如节点的 cpu、load、disk、memory 等指标
  • 内部系统组件的状态:比如 kube-scheduler、kube-controller-manager、kubedns/coredns 等组件的详细运行状态
  • 编排级的 metrics:比如 Deployment 的状态、资源请求、调度和 API 延迟等数据指标

这里通过 Prometheus 来采集节点的监控指标数据,可以通过node_exporter来获取,顾名思义,node_exporter 抓哟就是用于采集服务器节点的各种运行指标的,目前 node_exporter 支持几乎所有常见的监控点,比如 conntrack,cpu,diskstats,filesystem,loadavg,meminfo,netstat等,详细的监控点列表可以参考其Github repo

我们可以通过 DaemonSet 控制器来部署该服务,这样每一个节点都会自动运行一个这样的 Pod,如果我们从集群中删除或者添加节点后,也会进行自动扩展。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: kube-ops
  labels:
    name: node-exporter
spec:
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v0.17.0
        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 是运行在容器中的,所以我们在 Pod 中需要配置一些 Pod 的安全策略,这里我们就添加了hostPID: truehostIPC: truehostNetwork: true3个策略,用来使用主机的 PID namespace、IPC namespace 以及主机网络,这些 namespace 就是用于容器隔离的关键技术,要注意这里的 namespace 和集群中的 namespace 是两个完全不相同的概念。

另外我们还将主机的/dev/proc/sys这些目录挂载到容器中,这些因为我们采集的很多节点数据都是通过这些文件夹下面的文件来获取到的,比如我们在使用top命令可以查看当前cpu使用情况,数据就来源于文件/proc/stat,使用free命令可以查看当前内存使用情况,其数据来源是来自/proc/meminfo文件。

另外由于我们集群使用的是 kubeadm 搭建的,所以如果希望 master 节点也一起被监控,则需要添加响应的容忍。

创建上面的资源对象即可:

$ kubectl apply -f node-exporter.yaml
$ kubectl get pods -n kube-ops -o wide | grep node-exporter
node-exporter-48b6g           1/1       Running   0          7d        172.16.138.42   k8s-node02
node-exporter-4swrs           1/1       Running   0          7d        172.16.138.43   k8s-node03
node-exporter-4w2dd           1/1       Running   0          7d        172.16.138.40   k8s-master
node-exporter-fcp9x           1/1       Running   0          7d        172.16.138.41   k8s-node01

部署完成后,我们可以看到在3个节点上都运行了一个 Pod,有的同学可能会说我们这里不需要创建一个 Service 吗?我们应该怎样去获取/metrics数据呢?我们上面是不是指定了hostNetwork=true,所以在每个节点上就会绑定一个端口 9100,我们可以通过这个端口去获取到监控指标数据:

服务发现

由于我们这里3个节点上面都运行了 node-exporter 程序,如果我们通过一个 Service 来将数据收集到一起用静态配置的方式配置到 Prometheus 去中,就只会显示一条数据,我们得自己在指标数据中去过滤每个节点的数据,那么有没有一种方式可以让 Prometheus 去自动发现我们节点的 node-exporter 程序,并且按节点进行分组呢?是有的,就是我们前面和大家提到过的服务发现

在 Kubernetes 下,Promethues 通过与 Kubernetes API 集成,目前主要支持5中服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。

但是要让 Prometheus 也能够获取到当前集群中的所有节点信息的话,我们就需要利用 Node 的服务发现模式,同样的,在 prometheus.yml 文件中配置如下的 job 任务即可:

    - job_name: "kubernetes-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_(.+)
 

通过指定kubernetes_sd_configs的模式为node,Prometheus 就会自动从 Kubernetes 中发现所有的 node 节点并作为当前 job 监控的目标实例,发现的节点/metrics接口是默认的 kubelet 的 HTTP 接口。

配置文件说明:

这里就是一个正则表达式,去匹配__address__,然后将 host 部分保留下来,port 替换成了9100

因为我们是通过prometheus 去发现 Node 模式的服务的时候,访问的端口默认是10250,而现在该端口下面已经没有了/metrics指标数据了,因为我们是要去配置上面通过node-exporter抓取到的节点指标数据,而我们上面是不是指定了hostNetwork=true,所以在每个节点上就会绑定一个端口9100,所以我们应该将这里的10250替换成9100。

这里我们就需要使用到 Prometheus 提供的relabel_configs中的replace能力了,relabel 可以在 Prometheus 采集数据之前,通过Target 实例的 Metadata 信息,动态重新写入 Label 的值。除此之外,我们还能根据 Target 实例的 Metadata 信息选择是否采集或者忽略该 Target 实例。比如我们这里就可以去匹配__address__这个 Label 标签,然后替换掉其中的端口。

通过labelmap这个属性来将 Kubernetes 的 Label 标签添加为 Prometheus 的指标标签,添加了一个 action 为labelmap,正则表达式是__meta_kubernetes_node_label_(.+)的配置,这里的意思就是表达式中匹配都的数据也添加到指标数据的 Label 标签中去。

对于 kubernetes_sd_configs 下面可用的标签如下:

  • __meta_kubernetes_node_name:节点对象的名称
  • __meta_kubernetes_node_label:节点对象中的每个标签
  • __meta_kubernetes_node_annotation:来自节点对象的每个注释
  • __meta_kubernetes_node_address:每个节点地址类型的第一个地址(如果存在) *

prometheus 的 ConfigMap 更新完成后,同样的我们执行 reload 操作,让配置生效:

$ kubectl delete -f prome-cm.yaml
$ kubectl create -f prome-cm.yaml
$ kubectl get svc -n kube-ops
$ curl -X POST "http://10.111.210.47:9090/-/reload"

配置生效后,我们再去 prometheus 的 dashboard 中查看 Targets 是否能够正常抓取数据,访问任意节点IP:30358

 另外由于 kubelet 也自带了一些监控指标数据,所以我们这里也把 kubelet 的监控任务也一并配置上:

    - job_name: 'kubernetes-kubelet'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

上面的配置和我们之前配置 node-exporter 的时候几乎是一样的,区别是我们这里使用了 https 的协议,另外需要注意的是配置了 ca.cart 和 token 这两个文件,这两个文件是 Pod 启动后自动注入进来的,通过这两个文件我们可以在 Pod 中访问 apiserver。

现在我们再去更新下配置文件,执行 reload 操作,让配置生效,然后访问 Prometheus 的 Dashboard 查看 Targets 路径:

监控 Kubernetes 集群应用

exporter 监控应用

我们这里通过一个redis-exporter的服务来监控 redis 服务,对于这类应用,我们一般会以 sidecar 的形式和主应用部署在同一个 Pod 中,比如我们这里来部署一个 redis 应用,并用 redis-exporter 的方式来采集监控数据供 Prometheus 使用。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
  namespace: kube-ops
spec:
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
      - name: redis-exporter
        image: oliver006/redis_exporter:latest
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 9121
---
kind: Service
apiVersion: v1
metadata:
  name: redis
  namespace: kube-ops
spec:
  selector:
    app: redis
  ports:
  - name: redis
    port: 6379
    targetPort: 6379
  - name: prom
    port: 9121
    targetPort: 9121

可以看到上面我们在 redis 这个 Pod 中包含了两个容器,一个就是 redis 本身的主应用,另外一个容器就是 redis_exporter。现在直接创建上面的应用:

$ kubectl create -f prome-redis.yaml
deployment.extensions "redis" created
service "redis" created

我们可以通过 9121 端口来校验是否能够采集到数据:

$ curl 10.104.131.44:9121/metrics
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
......
# HELP redis_used_cpu_user_children used_cpu_user_childrenmetric
# TYPE redis_used_cpu_user_children gauge
redis_used_cpu_user_children{addr="redis://localhost:6379",alias=""} 0

同样的,现在我们只需要更新 Prometheus 的配置文件:

- job_name: 'redis'
  static_configs:
  - targets: ['redis:9121']

配置文件更新后,重新加载:

$ kubectl delete -f prome-cm.yaml
$ kubectl create -f prome-cm.yaml
$ curl -X POST "http://10.111.210.47:9090/-/reload"

Grafana 的安装使用

前面我们使用 Prometheus 采集了 Kubernetes 集群中的一些监控数据指标,我们也尝试使用promQL语句查询出了一些数据,并且在 Prometheus 的 Dashboard 中进行了展示,但是明显可以感觉到 Prometheus 的图表功能相对较弱,所以一般情况下我们会一个第三方的工具来展示这些数据,今天我们要和大家使用到的就是grafana

安装

grafana 是一个可视化面板,有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器,支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作为数据源,比 Prometheus 自带的图表展示功能强大太多,更加灵活,有丰富的插件,功能更加强大。

接下来我们就来直接安装,同样的,我们将 grafana 安装到 Kubernetes 集群中,第一步同样是去查看 grafana 的 docker 镜像的介绍,我们可以在 dockerhub 上去搜索,也可以在官网去查看相关资料,镜像地址如下:https://hub.docker.com/r/grafana/grafana/,我们可以看到介绍中运行 grafana 容器的命令非常简单:

$ docker run -d --name=grafana -p 3000:3000 grafana/grafana

我们将部署grafana的pod资源

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: grafana
  namespace: kube-ops
  labels:
    app: grafana
spec:
  revisionHistoryLimit: 10
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:5.4.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
          name: grafana
        env:
        - name: GF_SECURITY_ADMIN_USER
          value: admin
        - name: GF_SECURITY_ADMIN_PASSWORD
          value: admin321
        readinessProbe:
          failureThreshold: 10
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 30
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          limits:
            cpu: 100m
            memory: 256Mi
          requests:
            cpu: 100m
            memory: 256Mi
        volumeMounts:
        - mountPath: /var/lib/grafana
          subPath: grafana
          name: storage
      securityContext:
        fsGroup: 472
        runAsUser: 472
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: grafana

我们使用了最新的镜像grafana/grafana:5.4.2,然后添加了监控检查、资源声明,另外两个比较重要的环境变量GF_SECURITY_ADMIN_USERGF_SECURITY_ADMIN_PASSWORD,用来配置 grafana 的管理员用户和密码的,由于 grafana 将 dashboard、插件这些数据保存在/var/lib/grafana这个目录下面的,所以我们这里如果需要做数据持久化的话,就需要针对这个目录进行 volume 挂载声明,其他的和我们之前的 Deployment 没什么区别,由于上面我们刚刚提到的 Changelog 中 grafana 的 userid 和 groupid 有所变化,所以我们这里需要增加一个securityContext的声明来进行声明。

当然如果要使用一个 pvc 对象来持久化数据,我们就需要添加一个可用的 pv 供 pvc 绑定使用:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana
  namespace: kube-ops
  annotations:
    volume.beta.kubernetes.io/storage-class: "rook-ceph-block"
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: "rook-ceph-block"

最后,我们需要对外暴露 grafana 这个服务,所以我们需要一个对应的 Service 对象,当然用 NodePort 或者再建立一个 ingress 对象都是可行的:

apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: kube-ops
  labels:
    app: grafana
spec:
  type: NodePort
  ports:
    - port: 3000
  selector:
    app: grafana

现在我们直接创建上面的这些资源对象:

$ kubectl create -f .

 这个时候我们可以查看 Service 对象启动的端口:

kubectl get svc -n kube-ops
NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
grafana      NodePort   10.97.81.127    <none>        3000:30489/TCP   5d
prometheus   NodePort   10.111.210.47   <none>        9090:31990/TCP   7d

这里我们看到grafana启动端口是30489。我们可以通过任意节点+30489访问

由于上面我们配置了管理员的,所以第一次打开的时候会跳转到登录界面,然后就可以用上面我们配置的两个环境变量的值来进行登录了。

配置

接下来点击Add data source进入添加数据源界面。

我们这个地方配置的数据源是 Prometheus,所以选择这个 Type 即可,给改数据源添加一个 name:prometheus,最主要的是下面HTTP区域是配置数据源的访问模式。

访问模式是用来控制如何处理对数据源的请求的:

  • 服务器(Server)访问模式(默认):所有请求都将从浏览器发送到 Grafana 后端的服务器,后者又将请求转发到数据源,通过这种方式可以避免一些跨域问题,其实就是在 Grafana 后端做了一次转发,需要从Grafana 后端服务器访问该 URL。
  • 浏览器(Browser)访问模式:所有请求都将从浏览器直接发送到数据源,但是有可能会有一些跨域的限制,使用此访问模式,需要从浏览器直接访问该 URL。

由于我们这个地方 Prometheus 通过 NodePort 的方式的对外暴露的服务,所以我们这个地方是不是可以使用浏览器访问模式直接访问 Prometheus 的外网地址,但是这种方式显然不是最好的,相当于走的是外网,而我们这里 Prometheus 和 Grafana 都处于 kube-ops 这同一个 namespace 下面,是不是在集群内部直接通过 DNS 的形式就可以访问了,而且还都是走的内网流量,所以我们这里用服务器访问模式显然更好,数据源地址:http://prometheus:9090(因为在同一个 namespace 下面所以直接用 Service 名也可以),然后其他的配置信息就根据实际情况了,比如 Auth 认证,我们这里没有,所以跳过即可,点击最下方的Save & Test提示成功证明我们的数据源配置正确:

数据源添加完成后,就可以来添加 Dashboard 了。

配置Dashboard

 同样,切换到主页,我们可以根据自己的需求手动新建一个 Dashboard,除此之外,grafana 的官方网站上还有很多公共的 Dashboard 可以供我们使用,我们这里可以使用Kubernetes cluster monitoring (via Prometheus)(dashboard id 为162)这个 Dashboard 来展示 Kubernetes 集群的监控信息,在左侧侧边栏 Create 中点击import导入:

 

接下来输入162号导入(我现在已经导入,所以报一存在)

需要注意的是在执行上面的 import 之前要记得选择我们的prometheus这个名字的数据源,执行import操作,就可以进入到 dashboard 页面:

如果这里数据没出现有两个原因:

1、时间选择UTC时间

查询语句不正确

例如点击Edit的,我们可以看到查询语句

(sum(node_memory_MemTotal) - sum(node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached) ) / sum(node_memory_MemTotal) * 100

这就是我们之前在 Prometheus 里面查询的promQL语句,我们可以将上面的查询语句复制到 Prometheus 的 Graph 页面进行查询,其实可以预想到是没有对应的数据的,因为我们用node_exporter采集到的数据指标不是node_memory_MemTotal关键字,而是node_memory_MemTotal_bytes,将上面的promQL语句做相应的更改:

接下来按照此方法,依次修改Dashboard中的其他图标。

除此之外,我们也可以前往 grafana dashboard 的页面去搜索其他的关于 Kubernetes 的监控页面,地址:https://grafana.com/dashboards,比如id 为747和741的这两个 dashboard。

猜你喜欢

转载自www.cnblogs.com/xzkzzz/p/10208115.html