跳转至

Grafana

前面我们使用 Prometheus 采集了 Kubernetes 集群中的一些监控数据指标,我们也尝试使用 promQL 语句查询出了一些数据,并且在 Prometheus 的 Dashboard 中进行了展示,但是明显可以感觉到 Prometheus 的图表功能相对较弱,所以一般情况下我们还是会使用 Grafana 来进行展示,前面我们已经详细学习过 Grafana 的使用了,这里我们在 Kubernetes 集群中使用,所以同样可以将 Grafana 安装到集群中来,当然在集群外也是可以的。

安装

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

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

但是还有一个需要注意的是 Changelog 中 v5.1.0 版本的更新介绍:

Major restructuring of the container
Usage of chown removed
File permissions incompatibility with previous versions
user id changed from 104 to 472
group id changed from 107 to 472
Runs as the grafana user by default (instead of root)
All default volumes removed

特别需要注意第 3 条,useridgroupid 都有所变化,所以我们在运行的容器的时候需要注意这个变化。现在我们将这个容器转化成 Kubernetes 中的 Pod:

# grafana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: kube-mon
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      volumes:
        - name: storage
          persistentVolumeClaim:
            claimName: grafana-data
      initContainers:
        - name: fix-permissions
          image: busybox
          command: [chown, -R, "472:472", "/var/lib/grafana"]
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: storage
      containers:
        - name: grafana
          image: grafana/grafana:8.3.3
          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: 150m
              memory: 512Mi
            requests:
              cpu: 150m
              memory: 512Mi
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: storage
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: kube-mon
spec:
  type: NodePort
  ports:
    - port: 3000
  selector:
    app: grafana
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: grafana-local
  labels:
    app: grafana
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 1Gi
  storageClassName: local-storage
  local:
    path: /data/k8s/grafana
  persistentVolumeReclaimPolicy: Retain
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-data
  namespace: kube-mon
spec:
  selector:
    matchLabels:
      app: grafana
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-storage

我们使用了最新的镜像 grafana/grafana:8.3.3,然后添加了健康检查、资源声明,另外两个比较重要的环境变量GF_SECURITY_ADMIN_USERGF_SECURITY_ADMIN_PASSWORD,用来配置 grafana 的管理员用户和密码的,由于 grafana 将 dashboard、插件这些数据保存在 /var/lib/grafana 这个目录下面的,所以我们这里如果需要做数据持久化的话,就需要针对这个目录进行 volume 挂载声明,由于上面我们刚刚提到的 Changelog 中 grafana 的 userid 和 groupid 有所变化,所以我们这里增加一个 initContainers 来修改数据卷的权限,最后,我们需要对外暴露 grafana 这个服务,所以我们需要一个对应的 Service 对象,当然用 NodePort 或者再建立一个 ingress 对象都是可行的。

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

☸ ➜ kubectl apply -f https://p8s.io/docs/k8s/manifests/prometheus/grafana.yaml

创建完成后,我们可以查看 grafana 对应的 Pod 是否正常:

☸ ➜ kubectl get pods -n kube-mon -l app=grafana
NAME                       READY   STATUS    RESTARTS   AGE
grafana-7fbc6c7684-792mx   1/1     Running   0          4m37s
☸ ➜ kubectl logs -f grafana-7fbc6c7684-792mx -n kube-mon
......
t=2022-01-10T08:07:04+0000 lvl=info msg="warming cache for startup" logger=ngalert
t=2022-01-10T08:07:04+0000 lvl=info msg="HTTP Server Listen" logger=http.server address=[::]:3000 protocol=http subUrl= socket=

看到上面的日志信息就证明我们的 grafana 的 Pod 已经正常启动起来了。这个时候我们可以查看 Service 对象:

☸ ➜ kubectl get svc -n kube-mon
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
grafana      NodePort    10.109.3.79      <none>        3000:31384/TCP      6m6s

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

grafana login

由于上面我们配置了管理员的,所以第一次打开的时候会跳转到登录界面,然后就可以用上面我们配置的两个环境变量的值来进行登录了,登录完成后就可以进入到下面 Grafana 的首页,然后接下来的使用方式就可以参考前面数据可视化章节中的内容了,首先点击Add data source进入添加数据源界面。

我们这个地方配置的数据源是 Prometheus,我们这里 Prometheus 和 Grafana 都处于 kube-mon 这同一个 namespace 下面,所以我们这里的数据源地址:http://prometheus:9090(因为在同一个 namespace 下面所以直接用 Service 名也可以),然后其他的配置信息就根据实际情况了,比如 Auth 认证,我们这里没有,所以跳过即可,点击最下方的 Save & Test 提示成功证明我们的数据源配置正确:

grafana prometheus datasource

然后接下来就可以根据我们的需求去创建可视化的 Dashboard 面板了。

导入 Dashboard

为了能够快速对系统进行监控,我们可以直接复用别人的 Grafana Dashboard,在 Grafana 的官方网站上就有很多非常优秀的第三方 Dashboard,我们完全可以直接导入进来即可。比如我们想要对所有的集群节点进行监控,也就是 node-exporter 采集的数据进行展示,这里我们就可以导入 https://grafana.com/grafana/dashboards/8919 这个 Dashboard。

在侧边栏点击 "+",选择 Import,在 Grafana Dashboard 的文本框中输入 8919 即可导入:

import

进入导入 Dashboard 的页面,可以编辑名称,选择 Prometheus 的数据源:

edit dashboard

保存后即可进入导入的 Dashboard 页面。由于该 Dashboard 更新比较及时,所以基本上导入进来就可以直接使用了,我们也可以对页面进行一些调整,如果有的图表没有出现对应的图形,则可以编辑根据查询语句去 DEBUG。

node-exporter dashboard

然后如果想自定义图表直接根据我们的需求参考可视化章节内容去制作即可,还有其他需求也可以去 Grafana 官网导入合适的 Dashboard。