一、安装
Grafana 是一个可视化面板,有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器,支持Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作为数据源,比 Prometheus 自带的图表展示功能强大太多,更加灵活,有丰富的插件,功能更加强大。
镜像地址:https://hub.docker.com/r/grafana/grafana
编辑deployment配置清单:
grafana-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grafana
namespace: kube-ops
labels:
app: grafana
spec:
selector:
matchLabels:
app: grafana
replicas: 1
revisionHistoryLimit: 10
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:6.5.0
imagePullPolicy: IfNotPresent
ports:
- name: grafana
containerPort: 3000
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: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 100m
memory: 256Mi
volumeMounts:
- name: storage
mountPath: /var/lib/grafana
subPath: grafana
securityContext:
fsGroup: 472
runAsUser: 472
volumes:
- name: storage
persistentVolumeClaim:
claimName: grafana
这里配置securityContext的原因是从v5.1.0开始,grafana的运行用户ID(userid)和组ID(groupid)已经改成了472。而另外两个env是用来配置Grafana的管理员用户和密码。
配置持久化存储PVC:
grafana-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: grafana
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
server: xxx.xx.xxx.xx
path: /data/k8s/grafana
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana
namespace: kube-ops
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
配置Service服务:
grafana-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: kube-ops
labels:
app: grafana
spec:
selector:
app: grafana
type: NodePort
ports:
- name: grafana
port: 3000
然后我们会发现Pod并没有正常启动:
# kubectl get pod -n kube-ops
NAME READY STATUS RESTARTS AGE
grafana-d8cb7fd98-grqqf 0/1 CrashLoopBackOff 200 16h
查看其日志如下:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning BackOff 3m39s (x4398 over 16h) kubelet, 172.16.0.52 Back-off restarting failed container
[root@ecs-5704-0003 ~]# kubectl logs grafana-d8cb7fd98-grqqf -n kube-ops
GF_PATHS_DATA='/var/lib/grafana' is not writable.
You may have issues with file permissions, more information here: http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later
mkdir: can't create directory '/var/lib/grafana/plugins': Permission denied
我们发现其报权限不足,虽然我们上面定义了其sercurityContext为472,但是container在挂载PVC的时候目录的userID和groupID并不是472,我们可以通过一个Job任务来更改其宿主:
grafana-chown-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: grafana-chown
namespace: kube-ops
spec:
template:
metadata:
name: grafana-chown
spec:
containers:
- name: grafana-chown
image: busybox
imagePullPolicy: IfNotPresent
command: ["chown", "-R", "472:472", "/var/lib/grafana"]
volumeMounts:
- name: storage
subPath: grafana
mountPath: /var/lib/grafana
restartPolicy: Never
volumes:
- name: storage
persistentVolumeClaim:
claimName: grafana
注意:这里定义的PVC的名字和上面Grafana的Deployment中定义的必须一致。
然后我们生成Job的配置清单:
# kubectl apply -f grafana-chown-job.yaml
# kubectl get pod -n kube-ops
NAME READY STATUS RESTARTS AGE
grafana-chown-jfp77 0/1 Completed 0 4m22s
grafana-d8cb7fd98-vm8hq 1/1 Running 5 5m41s
然后我们发现可以成功运行了。
二、配置
2.1、添加数据源
我们这个地方配置的数据源是 Prometheus,所以选择这个 Type 即可,给改数据源添加一个 name:prometheus-ds,最主要的是下面HTTP
区域是配置数据源的访问模式。
访问模式是用来控制如何处理对数据源的请求的:
- 服务器(Server)访问模式(默认):所有请求都将从浏览器发送到 Grafana 后端的服务器,后者又将请求转发到数据源,通过这种方式可以避免一些跨域问题,其实就是在 Grafana 后端做了一次转发,需要从Grafana 后端服务器访问该 URL。
- 浏览器(Browser)访问模式:所有请求都将从浏览器直接发送到数据源,但是有可能会有一些跨域的限制,使用此访问模式,需要从浏览器直接访问该 URL。
由于我们这个地方 Prometheus 通过 NodePort 的方式的对外暴露的服务,所以我们这个地方是不是可以使用浏览器访问模式直接访问 Prometheus 的外网地址,但是这种方式显然不是最好的,相当于走的是外网,而我们这里 Prometheus 和 Grafana 都处于 kube-ops 这同一个 namespace 下面,是不是在集群内部直接通过 DNS 的形式就可以访问了,而且还都是走的内网流量,所以我们这里用服务器访问模式显然更好,数据源地址:http://prometheus-svc.kube-ops.svc:9090,然后其他的配置信息就根据实际情况了,比如 Auth 认证,我们这里没有,所以跳过即可,点击最下方的Save & Test提示成功证明我们的数据源配置正确:
2.2、添加Dashboard
Dashboard官方有很多模板,地址为:https://grafana.com/grafana/dashboards
然后可以搜索找自己想要的模板:
我们这里下载一个:https://grafana.com/grafana/dashboards/162/revisions
然后我们导入即可:
选择我们的数据源。
没有出数据的地方可能是promQL语句不对,或者是我们在我们采集的指标中没有模板中定义的,我们可以通过edit获得现有的promQL,然后到prometheus的grafa中调式语句。
CPU使用率的promQL:
sum(sum by (pod_name)( rate(container_cpu_usage_seconds_total{image!=""}[1m] ) )) / count(node_cpu_seconds_total{mode="system"}) * 100
文件系统使用率的promQL:
(sum(node_filesystem_size_bytes{device="rootfs"}) - sum(node_filesystem_free_bytes{device="rootfs"}) ) / sum(node_filesystem_size_bytes{device="rootfs"}) * 100
Pod Network IO的promQL:
sort_desc(sum by (pod_name) (rate (container_network_receive_bytes_total{name!="", pod_name!=""}[1m]) ))
sort_desc(sum by (pod_name) (rate (container_network_transmit_bytes_total{name!="", pod_name!=""}[1m]) ))
2.3、报警
Grafana 支持很多种形式的报警功能,比如 email、钉钉、slack、webhook 等等.
2.3.1、email报警
要启用 email 报警需要在启动配置文件中/etc/grafana/grafan.ini开启 SMTP 服务,我们这里同样利用一个 ConfigMap 资源对象挂载到 grafana Pod 中:
grafana-cm.yaml
metadata:
name: grafana-config
namespace: kube-ops
data:
grafana.ini: |
[server]
root_url = http://<你grafana的url地址>
[smtp]
enabled = true
host = smtp.163.com:25
user = ych_1024@163.com
password = <邮箱密码>
skip_verify = true
from_address = ych_1024@163.com
[alerting]
enabled = true
execute_alerts = true
上面配置了我的 163 邮箱,开启报警功能,当然我们还得将这个 ConfigMap 文件挂载到 Pod 中去:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grafana
namespace: kube-ops
labels:
app: grafana
spec:
selector:
matchLabels:
app: grafana
replicas: 1
revisionHistoryLimit: 10
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:6.5.0
imagePullPolicy: IfNotPresent
ports:
- name: grafana
containerPort: 3000
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: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 100m
memory: 256Mi
volumeMounts:
- name: storage
mountPath: /var/lib/grafana
subPath: grafana
- name: config
mountPath: /etc/grafana
securityContext:
fsGroup: 472
runAsUser: 472
volumes:
- name: storage
persistentVolumeClaim:
claimName: grafana
- name: config
configMap:
name: grafana-config
然后我们创建configmap并更新pod。
# kubectl apply -f grafana-cm.yaml
configmap/grafana-config created
# kubectl apply -f grafana-deploy.yaml
deployment.extensions/grafana configured
2.3.2、钉钉报警
(1)、生成钉钉机器人的webhook
(2)、测试
(3)、查看结果
2.3.3、添加报警
目前只有 Graph 支持报警功能,所以我们选择 Graph 相关图表,点击编辑,进入 Graph 编辑页面可以看到有一个 Alert 模块,切换过来创建报警:
参数说明:
- 1、Alert 名称,可以自定义。
- 2、执行的频率,这里我选择每60s检测一次。
- 3、判断标准,默认是 avg,这里是下拉框,自己按需求选择。
- 4、query(A,5m,now),字母A代表选择的metrics 中设置的 sql,也可以选择其它在 metrics中设置的,但这里是单选。1m代表从现在起往之前的五分钟,即1m之前的那个点为时间的起始点,
now
为时间的结束点,此外这里可以自己手动输入时间。 - 5、设置的预警临界点,这里手动输入,和6是同样功能,6可以手动移动,两种操作是等同的。
然后配置报警发送的信息:
然后达到报警阈值就可以接收到报警了。