网络知识 娱乐 自建grafana对接云原生监控进行个性化配置

自建grafana对接云原生监控进行个性化配置

现在很多人为了能够更好的监控腾讯云上的tke集群,都会直接使用腾讯云托管的prometheus服务云原生监控来监控集群。腾讯云云原生监控服务(Tencent Prometheus Service,TPS)是针对云原生服务场景进行优化的监控和报警解决方案,全面支持开源 Prometheus 的监控能力,为用户提供轻量、稳定、高可用的云原生 Prometheus 监控服务。借助 TPS,您无需自行搭建 Prometheus 监控系统,也无需关心数据存储、数据展示、系统运维等问题,只需简单配置即可享受支持多集群的高性能云原生监控服务。

作为一名运维人员,用云原生监控来监控tke集群,确实省了很多事,但是也会有一些限制,因为是托管服务,云原生监控实例对应的后端组件,用户是无法接触到的,是由腾讯云统一管理的,比如如果想对grafana做下个性化配置,很多时候不支持。但是业务如果有这种需求,那要怎么办呢?

其实我们可以不用云原生监控自带的grafana,在集群里面自建一个grafana,然后数据源配上云原生监控实例的prometheus接口地址,每个云原生监控实例都会提供一个内网的prometheus的数据查询地址,下面来说说如何通过自建grafana对接云原生监控然后进行个性化配置。

1. 创建TPS实例并获取Prometheus数据查询地址

这里如何创建实例就不一一讲解了,大家可以参考官网文档https://cloud.tencent.com/document/product/457/49889

创建好实例后,参考文档管理你的tke集群,这里默认只能关联同vpc下的集群,关联集群参考文档https://cloud.tencent.com/document/product/457/49890

关联好集群后,可以在控制台获取对应的Prometheus数据查询地址,我这里的地址是http://10.2.0.20:9090

grafana的内网访问地址默认是开启的,但是外网访问地址可以自行选择是否开启,这里可以不用开启,这里直接用我们自建的grafana就行。

2. tke集群部署grafana

下面我们在和云原生监控实例相同vpc的tke集群部署一个grafana,首先创建一个pvc持久化grafana的数据

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
   name: grafana
   namespace: weixnie
spec:
   storageClassName: cbs
   accessModes:
     - ReadWriteOnce
   resources:
     requests:
       storage: 10Gi

然后部署下grafana的deploy

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: weixnie
spec:
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      securityContext:
        fsGroup: 472
        supplementalGroups:
          - 0
      containers:
        - name: grafana
          image: grafana/grafana:7.5.4
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
              name: http-grafana
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /robots.txt
              port: 3000
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 30
            successThreshold: 1
            timeoutSeconds: 2
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 3000
            timeoutSeconds: 1
          resources:
            requests:
              cpu: 250m
              memory: 750Mi
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: grafana-pv
      volumes:
        - name: grafana-pv
          persistentVolumeClaim:
            claimName: grafana

为grafana创建一个svc

apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: weixnie
spec:
  ports:
  - name: 3000-3000-tcp
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    app: grafana
  sessionAffinity: None
  type: ClusterIP

创建一个ingress暴露grafana,通过域名访问grafana

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx-intranet
  name: grafana-ingress
  namespace: weixnie
spec:
  rules:
  - host: grafana.tke.niewx.cn
    http:
      paths:
      - backend:
          serviceName: grafana
          servicePort: 3000
        path: /
        pathType: ImplementationSpecific

部署好之后,我们就可以在浏览器通过域名访问到我们的grafana了

3. 配置数据源和dashborad

url里面填写之前获取的Prometheus数据查询地址,然后保存即可。这样就可以直接读取云原生监控实例里面的监控数据了。

下面我们来配置模板,这里模板可以用云原生监控提供的,我们可以临时开启下云原生监控grafana的公网访问,然后将里面的模板导出,再导入到我们自建的grafana里面就行。 可以参考文档进行dashborad的迁移https://cloud.tencent.com/developer/article/1766285 如果只需要某几个dashborad,则手动用json的方式导出导入即可

找到dashborad对应的json文件,然后在自建的dashborad导入即可。

4. 个性化配置grafana

上面的配置,其实云原生监控已经都提供了,这里自建主要是为了个性化配置,下面我们对grafana进行个性化配置

4.1 通过grafana告警并发送监控图片

这里我已发送邮件告警举例,首先创建一个grafana.ini的配置文件,里面配置smtp邮件服务器的信息,然后通过configmap挂载到容器,注意这里可能会出现访问25端口不通,因为腾讯云服务器对25端口进行了封禁,这个时候可以将端口改成465,465是加密端口。

apiVersion: v1
data:
  grafana.ini: |-
    [smtp]
    enabled = true
    host = smtp.163.com:465
    user = nwx_qdlg@163.com
    password = xxxxxxxxx
    skip_verify = true
    from_address = nwx_qdlg@163.com
    [alerting]
    enabled = true
    execute_alerts = true
kind: ConfigMap
metadata:
  name: grafana-config
  namespace: weixnie

configmap创建好之后,修改deploy的yaml进行挂载

............
        volumeMounts:
        - mountPath: /var/lib/grafana
          name: grafana-pv
        - mountPath: /etc/grafana
          name: config
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 472
        supplementalGroups:
        - 0
      terminationGracePeriodSeconds: 30
      volumes:
      - name: grafana-pv
        persistentVolumeClaim:
          claimName: grafana
      - configMap:
          defaultMode: 420
          name: grafana-config
        name: config

挂载后,然后重建pod,pod正常后,这个时候可以在grafana测试邮件告警,新建一个notifications channels

点击test,然后看下邮箱是否可以收到告警邮件

邮箱收到了告警邮件,说明这里告警channel配置成功。接下来我们测试下发送我们自己想要的告警。

因为grafana目前只有 Graph 支持报警功能,所以我们选择 Graph 相关图表,可以在grafana的页面找下12006这个监控dashborad,这个都是Graph类型,监控k8s集群apiserver的。

配置下apiserver request rate这个面板的告警

  • Evaluate every 表示检测评率,这里为了测试效果,改为1秒
  • Conditions 表示触发条件。下面图片的意思表示 当每秒平均值达到10,就会触发报警。
  • when 表示什么时间,of 表示条件,is above 表示触发值

为了方便触发告警,我们将告警阈值设置小点,保存后,这里过一会就会发送告警,但是这里有一个问题,我发现我收到的告警没有图片,提示我要安装grafana-image-renderer这个插件,这个插件是用来生成图片的

按照官网文档,我进入容器执行grafana-cli plugins install grafana-image-renderer,然后重建pod,发现新的pod一直在重启,看了下日志发现有报错

Failed to start renderer plugin: Unrecognized remote plugin message: nnThis usually means that the plugin is either invalid or simplynneeds to be recompiled to support the latest protocol

我手动去cbs盘删除这个插件,就能正常启动了,这是什么原因呢?

网上google一把,找到了一个解决方案https://github.com/grafana/grafana-image-renderer/#known-issue-having-ipv6-disabled

这里是将renderer单独作为一个容器部署,然后grafana去访问这个容器即可,文档里面是用的docker-compose部署的,这里我说下如何在k8s里面进行部署

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: weixnie
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: grafana
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - env:
        - name: GF_RENDERING_SERVER_URL
          value: http://renderer:8081/render
        - name: GF_RENDERING_CALLBACK_URL
          value: http://grafana:3000/
        - name: GF_LOG_FILTERS
          value: rendering:debug
        image: grafana/grafana:7.5.4
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 3000
          timeoutSeconds: 1
        name: grafana
        ports:
        - containerPort: 3000
          name: http-grafana
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /robots.txt
            port: 3000
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 2
        resources: {}
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/grafana
          name: grafana-pv
        - mountPath: /etc/grafana
          name: config
      - image: grafana/grafana-image-renderer:latest
        imagePullPolicy: Always
        name: renderer
        resources: {}
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 472
        supplementalGroups:
        - 0
      terminationGracePeriodSeconds: 30
      volumes:
      - name: grafana-pv
        persistentVolumeClaim:
          claimName: grafana
      - configMap:
          defaultMode: 420
          name: grafana-config
        name: config

这里将renderer和grafana放到一个pod里面,并配置环境变量

GF_RENDERING_SERVER_URL: http://renderer:8081/render
GF_RENDERING_CALLBACK_URL: http://grafana:3000/
GF_LOG_FILTERS: rendering:debug

但是这里是通过renderer名称访问的,这个时候还需要创建一个svc来暴露renderer服务

apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: renderer
  namespace: weixnie
spec:
  ports:
  - name: 8081-8081-tcp
    port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    app: grafana
  sessionAffinity: None
  type: ClusterIP

这个时候,grafana就能正常访问到renderer插件这个容器了。配置好之后,我们再次触发下告警

发现邮件里面就有包含告警的图片了,到grafana挂载的cbs目录页能找到生成的图片。

但是我发现告警触发后只发送一次,如果重要的告警需要间隔几分钟就提醒一次,该怎么设置呢?

其实在notifications channel有个Send reminders的配置

可以设置下告警发送频率,不勾选,默认就只发送一次。到这里grafana的告警发送配置就完成了,后续你只需要在对应的面板配置下告警就行。

4.2 配置grafana支持页面嵌入

有时候很多页面里面会看到嵌入的grafana监控,apisix网关的dashborad页面就支持嵌入Grafana的监控图,但是grafana默认是不支持页面嵌入的,这个时候需要进行配置下才行。

修改下grafana.ini文件,然后加上如下配置

# 允许iframe嵌入
allow_embedding = true

# 允许匿名登录
[auth.anonymous]
enabled = true

配置好之后,重建下grafana,将对应的dashboard地址复制,填写到需要嵌入的页面即可,这样就可以直接在其他页面里面查看grafana监控了。

5. 配置腾讯云cls日志服务dashboard

日志服务CLS与Grafana打通,支持将CLS的原始日志数据与SQL聚合分析结果导出至Grafana展示。用户只需安装CLS日志服务grafana插件,在grafana填写检索分析的语句,即可在Grafana上展示结果。

这里就不一一演示了,大家可以参考github文档 https://github.com/TencentCloud/cls-grafana-datasource