Go 监控的标配:实战 Prometheus( 二 )

当然 , 我们还需要在 kubenetes 里把需要被监控的业务配置成 Headless Service , 以便 kubenets 能够为每一个 POD 提供一个稳定的并且唯一的网络标识 , 也就是内网域名:
apiVersion: v1kind: Servicemetadata:name: foonamespace: defaultspec:clusterIP: None说明:关于 Headeless Service 和内网域名的相关知识 , 如果不清楚 , 那么可以参考我以前写的文章:「手把手教你用ETCD[11]」 , 里面有详细的介绍 。
此外 , 说一点题外话 , 假如使用 kubernetes_sd_config 作为服务发现方式 , 设想下面一个场景:集群里有非常多的节点 , 但是你只想监控其中的一部分 , 那么如何配置呢?答案是通过 kubenetes 的 annotations[12] 功能 , 标识出你要监控的节点 , 然后在 prometheus 里 relable[13] , 详细的介绍可以参考 stackoverflow 上的相关内容[14] 。
关于数据持久化的问题一般来说 , 我们通过 kubenetes 部署的都是一些无状态的服务 , 而对于 prometheus 服务而言 , 它应该是一个有状态的服务(StatefulSet) , 也就是说需要考虑数据持久化 ,否则一重启 , 监控信息的历史记录都丢失了 , 肯定不是我们所希望看到的:
apiVersion: apps/v1kind: StatefulSetmetadata:name: prometheusnamespace: defaultlabels:app: prometheusspec:serviceName: prometheusreplicas: 1selector:matchLabels:app: prometheustemplate:metadata:labels:app: prometheusspec:dnsPolicy: ClusterFirstcontainers:- name: prometheusimage: prom/prometheus:v2.22.0imagePullPolicy: Alwaysports:- name: httpcontainerPort: 9090protocol: TCPvolumeMounts:- name: datadirmountPath: /prometheus- name: configfilemountPath: "/etc/prometheus/prometheus.yml"subPath: prometheus.ymlresources:limits:cpu: "1"memory: 512Mirequests:cpu: "1"memory: 512Mivolumes:- name: configfileconfigMap:name: prometheus# securityContext:#runAsNonRoot: true#runAsUser: 65534#runAsGroup: 65534#fsGroup: 65534volumeClaimTemplates:- metadata:name: datadirspec:storageClassName: ...accessModes:- ReadWriteOnceresources:requests:storage: 10Gi不过当我配置 StatefulSet 的时候 , kubenetes 却报错了:
pod has unbound immediate PersistentVolumeClaims
相关描述无法直观看出问题出在哪 , 好在还可以查日志:
shell> kubectl logs prometheus-0结果看到了真正的错误原因:
open /prometheus/queries.active: permission denied
以此信息为关键字去 github 上搜索 , 可以找到相关的 issue[15] , 确认是权限问题 。 网上能查到一些解决方法 , 比如 GoogleCloudPlatform[16] 是通过在 initContainers 里执行 chmod 解决的 , 不过更好的方法是通过securityContext[17] 设置 非 root 权限:
securityContext:runAsNonRoot: truerunAsUser: 65534runAsGroup: 65534fsGroup: 65534至于为什么是 65534 , 可以本地运行 docker 容器后看看使用的是什么账号:
shell> docker exec $(docker ps -qf ancestor=prom/prometheus) iduid=65534(nobody) gid=65534(nogroup)其它问题差点忘了说 grafana[18] , 既然说 prometheus , 怎么能忘了 grafana 呢!grafana 对 prometheus 的支持很好 , 使用起来非常简单 , 按照官问文档[19]的说明配置即可 , 没有什么可说的 , 我要说的是关于Dashboard[20] 的选择 , 现在最流行的是 Go Metrics(10826)[21] , 多数时候 , 它也是最好的 , 不过它有一个缺点:它是基于 kubenetes 里的 namespace / pod 筛选的 , 如果你没有使用基于 kubenetes 的服务发现机制 , 比如本文使用的是基于 dns 的服务发现机制 , 那么筛选功能就失效了 , 基于此 , 我做了一个修改版本的 Go Metrics(13240)[22] , 它是基于 job / instance 筛选的 , 效果如下:
Go 监控的标配:实战 Prometheus文章插图
最后 , 推荐一些资料:「Prometheus book[23]」 , 「Prometheus监控Kubernetes系列[24]」 。
参考资料[1]
prometheus:
[2]
集成: docs/guides/go-application/
[3]
部署:
[4]
官方文档: docs/prometheus/latest/installation/
[5]
官方文档: docs/prometheus/latest/installation/
[6]
ConfigMap:
[7]
static_configs: docs/prometheus/latest/configuration/configuration/#static_config
[8]
kubernetes_sd_config: docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
[9]
RBAC:
[10]
dns_sd_config: docs/prometheus/latest/configuration/configuration/#dns_sd_config
[11]
手把手教你用ETCD:
[12]
annotations:
[13]
relable:
[14]
相关内容:
[15]
issue:
[16]
GoogleCloudPlatform:
[17]
securityContext:
[18]
grafana:
[19]
官问文档: docs/visualization/grafana/
[20]
Dashboard: grafana/dashboards?search=golang