TKE/EKS多集群事件日志如何采集并配置事件告警

2022-05-11 21:08:19 浏览数 (1)

上一次,我们讲了如何采集tke/eks集群的事件日志,具体可以参考文档 如何将TKE/EKS集群事件日志持久化

之前我们是通过eventrouter这个开源组件来实现对集群事件日志持久化的,这个组件存在下面2个问题:

  • 日志格式不方便检索,因为每条日志加了时间戳,无法通过json格式解析日志,然后投递到es。
  • 对于warn级别的异常报错事件,不能告警提示。

为了能更好的检索日志,并配置事件日志告警,下面我们通过阿里的开源组件kube-eventer来实现对tke/eks多集群的事件日志采集。并配置下事件告警发送到钉钉。

kube-eventer的github地址:https://github.com/AliyunContainerService/kube-eventer

kube-eventer 是一个事件发射器,将 kubernetes 事件发送到 sinks(例如 dingtalk、sls、kafka 等)。Kubernetes的核心设计理念是状态机。所以当转移到期望状态时会有正常事件,当转移到意外状态时会发生警告事件。kube-eventer 可以帮助诊断、分析和报警问题。

kube-eventer的架构如下

下面我们配置下如何将腾讯云的tke和eks集群的事件日志采集到es,并给tke和eks配置下warn级别的事件告警发送到钉钉。

1. 部署es和kibana存储事件日志

首先部署下Elasticsearch和kibana用来存储和检索事件日志,这里可以参考之前的文档,这里就不一一演示了https://cloud.tencent.com/developer/article/1990549 。 因为这里是需要同时采集tke和eks集群的事件日志,本次测试的tke和eks集群都是在腾讯云的同一个vpc内,而Elasticsearch

是部署在tke集群上,为了能让eks集群能直接访问到es,这里需要将es的service设置为内网clb类型,同一个vpc内内网互通,这样eks就可以内网访问tke集群上部署的Elasticsearch,如果你的多个集群内网不通,就将Elasticsearch的serivce设置为公网类型clb,走公网将多个集群的事件日志采集到同一个es。

代码语言:javascript复制
[root@VM-0-4-centos ~]# kubectl get svc -n weixnie | grep -i Elasticsearch
elasticsearch-master                      LoadBalancer   10.55.254.57    172.16.0.20      9200:31403/TCP,9300:31323/TCP                                             10d
elasticsearch-master-headless             ClusterIP      None            <none>           9200/TCP,9300/TCP                                                         10d

这里172.16.0.20就是vpc内网访问的地址。

2. 创建钉钉机器人接受告警

因为我们需要将事件告警发送到钉钉,所以需要提前创建好一个接受告警的机器人,首先需要有一个钉钉群,并且是管理员,点击群管理,然后点击智能群助手

添加机器人

选择自定义

创建好之后复制下对应的webhook地址。

3. tke集群部署kube-eventer

为了避免token和集群信息泄漏,下面集群id个token信息都进行了删减,如果部署的话,需要根据实际修改yaml里面配置。

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: kube-eventer
  name: kube-eventer
  namespace: weixnie
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-eventer
  template:
    metadata:
      labels:
        app: kube-eventer
      annotations:    
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      dnsPolicy: ClusterFirstWithHostNet
      serviceAccount: kube-eventer
      containers:
        - image: registry.aliyuncs.com/acs/kube-eventer-amd64:v1.1.0-63e7f98-aliyun
          name: kube-eventer
          command:
            - "/kube-eventer"
            - "--source=kubernetes:https://kubernetes.default"
            ## .e.g,dingtalk sink demo
            - --sink=dingtalk:https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx&label=cls-tke&label=event&level=Warning&msg_type=markdown
            - --sink=elasticsearch:http://172.16.0.20:9200?ver=7&index=cls-tke-event&cluster_name=cls-tke
          env:
          # If TZ is assigned, set the TZ value as the time zone
          - name: TZ
            value: Asia/Shanghai
          volumeMounts:
            - name: localtime
              mountPath: /etc/localtime
              readOnly: true
            - name: zoneinfo
              mountPath: /usr/share/zoneinfo
              readOnly: true
      volumes:
        - name: localtime
          hostPath:
            path: /etc/localtime
        - name: zoneinfo
          hostPath:
            path: /usr/share/zoneinfo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-eventer
rules:
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
  name: kube-eventer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-eventer
subjects:
  - kind: ServiceAccount
    name: kube-eventer
    namespace: weixnie
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-eventer
  namespace: weixnie

下面我们来分别对dingtalk和elasticsearch这2个sink的参数讲解下:

  • dingtalk

--sink=dingtalk:<DINGTALK_WEBHOOK_URL>&label=<your_cluster_id>&level=<Normal or Warning, Warning default> 可以使用以下选项:

  1. label - 警报消息上的自定义标签。(例如 clusterId)
  2. level - 事件级别(默认:警告。选项:警告和正常)
  3. namespaces - 要过滤的命名空间(默认:所有命名空间,使用逗号分隔多个命名空间)
  4. kind - 要过滤的种类(默认:所有种类,使用逗号分隔多种。选项:Node、Pod 等。)
  5. msg_type - 消息类型(默认:文本。选项:文本和降价)
  6. sign - 签名密钥(如果钉钉使用签名的安全机制,可以通过该字段传入密钥。)[可选]

--sink=dingtalk:https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx&label=cls-tke&label=event&level=Warning&msg_type=markdown

这里我们将事件基本设置为Warning,表示只发送Warning级别的事件告警,告警格式为markdown,同时配置下label,第一个label为集群id,第二个是对应机器人设置的关键字。

  • elasticsearch

--sink=elasticsearch:<ES_SERVER_URL>[?<OPTIONS>]

  1. index - 指标和事件的索引。默认值为heapster
  2. esUserName - 启用身份验证时的用户名
  3. esUserSecret - 启用身份验证时的密码
  4. maxRetries - Elastic 客户端在放弃并返回错误之前将对单个请求执行的重试次数。默认为 0,因此默认禁用重试。
  5. healthCheck - 指定是否默认启用 healthCheck。默认情况下启用。要禁用,请提供一个负布尔值,如 0 或 false。
  6. sniff - 指定默认情况下是否启用嗅探器。默认情况下启用。要禁用,请提供一个负布尔值,如 0 或 false。
  7. startupHealthcheckTimeout - healthCheck 在启动时(即创建客户端时)等待 Elasticsearch 响应的时间(以秒为单位)。默认值为 1。
  8. ver - ElasticSearch 集群版本,可以是 2、5、6 或 7。默认为 5
  9. bulkWorkers - 批量处理的工人数量。默认值为 5。
  10. cluster_name - 不同 Kubernetes 集群的集群名称。默认值为default。
  11. pipeline - (可选;>ES5)摄取管道以处理文档。默认为禁用(空值)

--sink=elasticsearch:http://172.16.0.20:9200?ver=7&index=cls-tke-event&cluster_name=cls-tke

里我们配置下es的地址为内网clb的vip地址172.16.0.20,并设置下es的版本,本次使用的es是7.x版本,设置下es索引名称cls-tke-event,索引名称尽可能用集群id,这样方便后续区分检索,然后配置下集群id,用来在日志区分不同集群。

4. eks集群部署kube-eventer

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: kube-eventer
  name: kube-eventer
  namespace: weixnie
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-eventer
  template:
    metadata:
      labels:
        app: kube-eventer
      annotations:    
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      dnsPolicy: ClusterFirstWithHostNet
      serviceAccount: kube-eventer
      containers:
        - image: registry.aliyuncs.com/acs/kube-eventer-amd64:v1.1.0-63e7f98-aliyun
          name: kube-eventer
          command:
            - "/kube-eventer"
            - "--source=kubernetes:https://kubernetes.default"
            ## .e.g,dingtalk sink demo
            - --sink=dingtalk:https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx&label=cls-eks&label=event&level=Warning&msg_type=markdown
            - --sink=elasticsearch:http://172.16.0.20:9200?ver=7&index=cls-eks-event&cluster_name=cls-eks
          env:
          # If TZ is assigned, set the TZ value as the time zone
          - name: TZ
            value: Asia/Shanghai
          volumeMounts:
            - name: localtime
              mountPath: /etc/localtime
              readOnly: true
            - name: zoneinfo
              mountPath: /usr/share/zoneinfo
              readOnly: true
      volumes:
        - name: localtime
          hostPath:
            path: /etc/localtime
        - name: zoneinfo
          hostPath:
            path: /usr/share/zoneinfo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-eventer
rules:
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
  name: kube-eventer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kube-eventer
subjects:
  - kind: ServiceAccount
    name: kube-eventer
    namespace: weixnie
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube-eventer
  namespace: weixnie

eks上的部署和tke一样,修改下对应的集群id即可

代码语言:javascript复制
- --sink=dingtalk:https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx&label=cls-eks&label=event&level=Warning&msg_type=markdown
- --sink=elasticsearch:http://172.16.0.20:9200?ver=7&index=cls-eks-event&cluster_name=cls-eks

5. kibana配置索引检索不同集群日志

pod运行后,可以看下es是否生成了对应的索引,如果索引文件生成正常,则说明日志采集es正常

代码语言:javascript复制
[root@VM-55-14-tlinux ~]# curl 172.16.0.20:9200/_cat/indices | grep cls
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1564  100  1564    0     0   142k      0 --:--:-- --:--:-- --:--:--  152k
green open cls-tke-event-2022.05.10 gtc-bQ-vTS-Bmm7cZWMhXA 1 1  1275 0   1.4mb 967.9kb
green open cls-eks-event-2022.05.10 zmxIBxpEQkShBxX-o4CCmQ 1 1   144 0 439.1kb 219.5kb
green open cls-tke-event-2022.05.09 rOsASOsVSFeTtMpoWTjxXQ 1 1  4070 0   4.3mb   2.2mb
green open cls-eks-event-2022.05.09 afnL19eXSgeqeTkdQ0QITA 1 1   347 0 427.4kb 166.7kb

然后我们到kibana分别创建下索引来检索tke和eks日志

注意这里创建索引的时候,选择Metadata.managedFields.time这个字段过滤,这样就能检索实时刷新的事件。索引创建好之后,直接检索就行

可以发现,日志格式被解析成了json字段,这样方便检索。这里只配置了一个集群,如果有多个集群配置多个索引即可,当然,也可以配置为一个索引,检索的时候通过集群名称来检索对应集群的事件日志即可。

6. 钉钉查看告警

从上面的检索看,pod的事件日志是一条Warning类型,这里到钉钉群里看下,是否有这条事件的告警,如果有收到告警,则说明告警配置正常

告警群里收到了事件的告警,说明集群的告警配置正常。

0 人点赞