Kubernetes集群监控-Grafana安装

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

1、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

现在我们将这个容器转化成 Kubernetes 中的 Pod(grafana-deploy.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: kube-ops
  labels:
    app: grafana
spec:
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:6.7.1
        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:6.7.1,然后添加了监控检查、资源声明,另外两个比较重要的环境变量GF_SECURITY_ADMIN_USER和GF_SECURITY_ADMIN_PASSWORD,用来配置 grafana 的管理员用户和密码的,由于 grafana 将 dashboard、插件这些数据保存在/var/lib/grafana这个目录下面的,所以我们这里如果需要做数据持久化的话,就需要针对这个目录进行 volume 挂载声明,其他的和我们之前的 Deployment 没什么区别,由于上面我们刚刚提到的 Changelog 中 grafana 的 userid 和 groupid 有所变化,所以我们这里需要增加一个securityContext的声明来进行声明。

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

apiVersion: v1
kind: PersistentVolume
metadata:
  name: grafana
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    server: 172.16.200.1
    path: /data/k8s
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana
  namespace: kube-ops
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

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

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

现在我们直接创建上面的这些资源对象,创建完成之后我们可以查看Grafana对应的Pod是否正常:

img

通过上面的截图我们可以看到、Grafana的状态是 CrashLoopBackOff ,并没有正常启动。我们可以查看一下这个Pod的日志,如下:

img

注:上面的错误是在5.1版本之后才会出现的,当然你也可以使用之前的版本来规避这个问题。

可以看到是日志中错误很明显就是/var/lib/grafana目录的权限问题,这还是因为5.1版本后 groupid 更改了引起的问题,我们这里增加了securityContext,但是我们将目录/var/lib/grafana挂载到 pvc 这边后目录的拥有者并不是上面的 grafana(472)这个用户了,所以我们需要更改下这个目录的所属用户,这个时候我们可以利用一个 Job 任务去更改下该目录的所属用户(grafana-chown-job.yaml):

apiVersion: batch/v1
kind: Job
metadata:
  name: grafana-chown
  namespace: kube-ops
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: grafana-chown
        command: ["chown", "-R", "472:472", "/var/lib/grafana"]
        image: busybox
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: storage
          subPath: grafana
          mountPath: /var/lib/grafana
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: grafana

上面我们利用一个 busybox 镜像将/var/lib/grafana目录更改成了472这个 user 和 group,不过还需要注意的是下面的 volumeMounts 和 volumes 需要和上面的 Deployment 对应上。 现在我们删除之前创建的 Deployment 对象,重新创建。重新执行完成后,可以查看下上面的创建的资源对象是否正确了:

img

我们可以看到有一个状态为Completed的 Pod,这就是上面我们用来更改 grafana 目录权限的 Pod,是一个 Job 任务,所以执行成功后就退出了,状态变成了Completed,而上面的 grafana 的 Pod 也已经是Running状态了。这个时候我们可以查看 Service 对象:

img

现在我们就可以在浏览器中使用http://<任意节点IP:30070>来访问 grafana 服务了:

img

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

img

2、Grafana配置

在上面的首页中我们可以看到已经安装了 Grafana,接下来点击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提示成功证明我们的数据源配置正确:

img

img

img

img

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

3、Dashboard

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

img

我们可以将上面编号162的 dashboard 下载到本地,然后这里重新上传即可,也可以在上面的文本框中直接输入162编号回车即可,导入这个 dashboard:

img

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

img

我们可以看到 dashboard 页面上出现了很多漂亮的图表,但是看上去数据不正常,这是因为这个 dashboard 里面需要的数据指标名称和我们 Prometheus 里面采集到的数据指标不一致造成的,比如,第一个Cluster memory usage(集群内存使用情况),我们可以点击标题 -> Edit,进入编辑这个图表的编辑页面:

img

进入编辑页面我们就可以看到这个图表的查询语句:

(sum(node_memory_MemTotal) - sum(node_memory_MemFree+node_memory_Buffers+node_memory_Cached) ) / sum(node_memory_MemTotal) * 100

img

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

(sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes+node_memory_Cached_bytes)) / sum(node_memory_MemTotal_bytes) * 100

img

这个语句的意思就是(整个集群的内存-(整个集群剩余的内存以及Buffer和Cached))/整个集群的内存,简单来说就是总的集群内存使用百分比。将上面 grafana 的promQL语句替换掉,就可以看到图表正常了:

img

当然你也可以去Prometheus里面验证查询语句、剩下的查询语句我就不再一一展示了、请各位小伙伴自行解决、修改完成之后的图形如上图所示。

img

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

推荐文章