对于自己搭建的kubernetes集群,能做到实时监控pod的状态并及时发送告警是非常有必要的
通过翻阅kubernetes官方的各种文档后,我决定采用kube-state-metrics来实现对kubenetes进行监控,并配合promethues进行数据存储、grafana进行数据渲染与告警,从而实现一套比较完整的监控方案
安装过程如下:
数据收集
部署kube-state-metrics
将kube-state-metrics组件的yaml克隆下来
git clone https://github.com/devopscube/kube-state-metrics-configs.git
clone成功后会有如下几个文件:
root@k8s-master:~/kube-state-metrics/kube-state-metrics-configs# ll
total 36
drwxr-xr-x 3 root root 4096 Mar 27 10:06 ./
drwxr-xr-x 3 root root 4096 Mar 27 10:06 ../
-rw-r--r-- 1 root root 377 Mar 27 10:06 cluster-role-binding.yaml
-rw-r--r-- 1 root root 1651 Mar 27 10:06 cluster-role.yaml
-rw-r--r-- 1 root root 1069 Mar 27 10:06 deployment.yaml
drwxr-xr-x 8 root root 4096 Mar 27 10:06 .git/
-rw-r--r-- 1 root root 78 Mar 27 10:06 README.md
-rw-r--r-- 1 root root 193 Mar 27 10:06 service-account.yaml
-rw-r--r-- 1 root root 406 Mar 27 10:06 service.yaml
默认deployment.yaml是没有指定时区的,为了方便观察kubernetes中的数据时区再配置一下,指定为东八区的时间
env:
- name: TZ
value: Asia/Shanghai
完整的deployment.yaml文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: kube-state-metrics
app.kubernetes.io/version: v1.8.0
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: kube-state-metrics
template:
metadata:
labels:
app.kubernetes.io/name: kube-state-metrics
app.kubernetes.io/version: v1.8.0
spec:
containers:
- image: quay.io/coreos/kube-state-metrics:v1.8.0
env:
- name: TZ
value: Asia/Shanghai
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 5
name: kube-state-metrics
ports:
- containerPort: 8080
name: http-metrics
- containerPort: 8081
name: telemetry
readinessProbe:
httpGet:
path: /
port: 8081
initialDelaySeconds: 5
timeoutSeconds: 5
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: kube-state-metrics
修改好后到clone的目录apply一下即可:
kubectl apply -f kube-state-metrics-configs/
如下:
root@k8s-master:~/kube-state-metrics# kubectl apply -f kube-state-metrics-configs/
clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/kube-state-metrics created
deployment.apps/kube-state-metrics created
serviceaccount/kube-state-metrics created
service/kube-state-metrics created
如果执行的是上面的命令的话,默认会在kube-system命名空间下创建对应的资源,查看kube-state-metrics是否部署成功,执行get命令查看一下
kubectl get deployments kube-state-metrics -n kube-system
如下:
root@k8s-master:~/kube-state-metrics# kubectl get deployments kube-state-metrics -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
kube-state-metrics 1/1 1 1 4m49s
全ready好了就说明已部署成功了
再看一下kube-state-metrics的日志:
如下图
数据展示
kube-state-metrics关联promethues
对于promethues与grafana的部署这里不再演示,感兴趣的可在上一篇文章《介绍一下,spring cloud下的另一种定时任务解决方案》中找到,或直接执行下面的两个地址的部署文件
- https://github.com/spring-cloud/spring-cloud-dataflow/tree/master/src/kubernetes/prometheus
- https://github.com/spring-cloud/spring-cloud-dataflow/tree/master/src/kubernetes/grafana
当promethues准备好后,添加对应的采集job即可:
- job_name: 'kube-state-metrics'
static_configs:
- targets: ['kube-state-metrics.kube-system.svc.cluster.local:8080']
如果是用的上面spring cloud data flow官方的promethues来采集数据的话,配置在promethues对应的configMap里即可
其prometheus-configmap.yaml文件内容如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus
labels:
app: prometheus
data:
prometheus.yml: |-
global:
scrape_interval: 10s
scrape_timeout: 9s
evaluation_interval: 10s
scrape_configs:
- job_name: 'proxied-applications'
metrics_path: '/metrics/connected'
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- default
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: prometheus-proxy
- source_labels: [__meta_kubernetes_pod_container_port_number]
action: keep
regex: 8080
- job_name: 'kube-state-metrics'
static_configs:
- targets: ['kube-state-metrics.kube-system.svc.cluster.local:8080']
- job_name: 'proxies'
metrics_path: '/metrics/proxy'
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- default
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: prometheus-proxy
- source_labels: [__meta_kubernetes_pod_container_port_number]
action: keep
regex: 8080
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
之后再重启promethues让配置生效,再打开promethues的web看一下target里的配置是否生效,如下图
grafana关联promethues进行图表查看
在完成了promethues对于kube-state-metrics数据的采集后,接下来便是数据的渲染与展示了。为了直观我们一般用grafana来进行图表渲染
对于grafana的安装与配置请参考上面部分kube-state-metrics关联promethues的内容
因为是用的grafana,所以直接去grafana的官网找一个dashboard导入grafana即可
也就是在这个地址中找一个:
https://grafana.com/grafana/dashboards
比如我就找了这个试试效果:https://grafana.com/grafana/dashboards/10856
在导入的界面输入对应dashboard的id
之后再进入到dashboard的界面进行查看,效果感觉还是很不错的
监控告警
grafana告警
grafana也支持告警功能,可通过界面手动指定某一规则然后选择某一发送渠道就可以了。常用的钉钉、邮件、微信告警、webhook等都支持,感觉也还是挺方便的
这里以检测有失败的pod为例快速演示一下钉钉告警
先编辑某一panel,它的查询语句为:
kube_pod_status_phase{namespace=~".*", phase=“Failed”}>0
对于kube_pod_status_phase存在的数据有哪些可以通过grafana或promethues查看,如下:
将对应panel修改为支持告警的某一图形,如这里的Graph
再次点击Alert模块选择添加Alert即可,之后再配上对应的规则,如我这里当指标值大于0时就发送告警,发送内容为:
有pod异常,请注意!
其消息内容也可以指定为变量,具体可以参考grafana对消息告警部分的介绍:
https://grafana.com/docs/grafana/latest/alerting/add-notification-template/
当grafana的alert创建好了可以在grafana中的alert模块中看到
当达到了alert的触发规则grafana则会发送对应的消息过来。
为了测试方便,我专门弄了两个有问题的pod验证一下
果不其然,根据上面配置的规则一分钟检测一次,一分钟后就真的就收到了消息,如下图:
注意:在grafana中同一告警规则触发一次后的同一类型的消息只会发送一次,如果想再次发送需要手动在grafana中将对应的alert条目设为暂停后重新开启一下
举个栗子:
A时刻有两个pod异常了,会触发一次告警,之后就再也不会触发告警了,即便现在有3个pod都异常了也不会再次触发告警,想要再次触发需要手动把alert暂停再开启一下
还有就是grafana默认是采用Sqlite数据库进行grafana的数据存储的,所以如果在grafana的web界面中配置的告警规则如果grafana重启之后对应的告警信息也会丢失的,如果修改了grafana的数据源则不会出现这个问题
promethues告警
正因为grafana默认采用了sqlite进行数据存储而且一般我们也不会修改,会存在web界面中配置grafana重启后配置会丢失这个特点,以及有时我们仅想用普通的数据采集与更加完善的监控告警,也不想再引入过多第三方的组件,那么这时promethues的告警功能存在的价值就能体现出来了
promethues的告警安装与配置过程和grafana相比要稍微复杂一点,具体这里就不再演示了,感兴趣的可以参考promethues的官网
https://prometheus.io/docs/alerting/latest/overview/
想快速入门的话也可以看网上这位大佬的文章:
https://www.bookstack.cn/read/prometheus-book/alert-README.md
总结
在k8s中可以通过kube-state-metrics监控k8s中资源的状态信息,如pod、deployment、jobs等的实例个数也运行情况
如果需要进行数据展示可以通过promethues搭配进行数据存储,再配合grafana进行更美观的图表展示
如果想对数据进行监控告警并且监控逻辑不是很复杂的话直接用grafana的监控告警也已满足基本需求了,如果想做到更高级的报警监控可以使用promethues告警模块来实现
周末真快呀!下周加油!