K8S集群event事件告警

前言

使用阿里云开源的kube-eventer 项目采集K8S集群的event事件,然后推送给WebHook应用,进行邮件告警。
地址:https://github.com/AliyunContainerService/kube-eventer

程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#cat kube-event-webhook.py 
import json
import smtplib
import os
from email.mime.text import MIMEText
from email.header import Header
from flask import Flask, request

app = Flask(__name__)

# 从环境变量中读取配置
SMTP_HOST = os.getenv('SMTP_HOST', 'smtp.139.com')
SMTP_PORT = int(os.getenv('SMTP_PORT', 25))
SMTP_USER = os.getenv('SMTP_USER', '15398009149@139.com')
SMTP_PASSWORD = os.getenv('SMTP_PASSWORD', '36edaxxxxx25da00')
FROM_ADDR = os.getenv('FROM_ADDR', '15398009149@139.com')
# 从环境变量中读取收件人地址(多个地址用逗号分隔)
TO_ADDRS = os.getenv('TO_ADDRS', '15398009149@139.com').split(',')
# 从环境变量中读取 Flask 端口
FLASK_PORT = int(os.getenv('FLASK_PORT', 5000))

def format_content(template, data):
"""
根据模板和数据格式化内容
:param template: 模板字符串(包含占位符)
:param data: 替换占位符的数据(字典格式)
:return: 格式化后的字符串
"""
try:
# 替换模板中的占位符
formatted_content = template
for key, value in data.items():
# 处理嵌套字段(如 InvolvedObject.Namespace)
if isinstance(value, dict):
for sub_key, sub_value in value.items():
placeholder = "{{ ." + key + "." + sub_key + " }}"
formatted_content = formatted_content.replace(placeholder, str(sub_value))
else:
placeholder = "{{ ." + key + " }}"
formatted_content = formatted_content.replace(placeholder, str(value))
return formatted_content
except Exception as e:
print(f"格式化内容失败: {e}")
return template # 如果替换失败,返回原始模板

def send_mail(content, to_addrs):
"""
发送邮件
:param content: 邮件内容
:param to_addrs: 收件人邮箱地址列表
"""
# 创建邮件对象
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = Header(FROM_ADDR, 'utf-8')
message['To'] = Header(','.join(to_addrs), 'utf-8') # 多个收件人用逗号分隔
message['Subject'] = Header('集群事件告警通知', 'utf-8')

try:
# 连接 SMTP 服务器
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as smtp_obj:
# 登录 SMTP 服务器
smtp_obj.login(SMTP_USER, SMTP_PASSWORD)
# 发送邮件
smtp_obj.sendmail(FROM_ADDR, to_addrs, message.as_string())
print(f"邮件发送成功,收件人: {', '.join(to_addrs)}")
except Exception as err:
print(f"邮件发送失败: {str(err)}")

@app.route("/send_mail", methods=["POST"])
def send():
"""
处理 Webhook 请求并发送邮件
"""
# 获取请求体中的数据
raw_data = request.data.decode('utf-8')

try:
# 解析 JSON 数据
data = json.loads(raw_data)

# 提取 content 字段
if "text" in data and "content" in data["text"]:
content = data["text"]["content"]
else:
content = "集群事件告警" # 如果未提供 content,使用默认值

# 提取收件人邮箱地址(如果请求中指定了收件人)
to_addrs = data.get("to_addrs", TO_ADDRS) # 如果未提供 to_addrs,使用默认的 TO_ADDRS

# 直接使用 content 作为邮件内容
formatted_content = content

# 发送邮件
send_mail(formatted_content, to_addrs)

return "邮件发送成功。"
except Exception as e:
print(f"处理请求失败: {e}")
return "邮件发送失败。", 500

if __name__ == "__main__":
app.run("0.0.0.0", FLASK_PORT)

打包Docker镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# cat requirements.txt 
Flask==2.3.2


# 使用官方 Python 3.9 镜像作为基础镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 将当前目录下的所有文件复制到容器的 /app 目录
COPY . /app

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 暴露 Flask 应用的端口(通过环境变量配置)
EXPOSE $FLASK_PORT

# 设置环境变量默认值
ENV SMTP_HOST=smtp.139.com
ENV SMTP_PORT=25
ENV SMTP_USER=15398009149@139.com
ENV SMTP_PASSWORD=36edaada65f04225da00
ENV FROM_ADDR=15398009149@139.com
ENV TO_ADDRS=15398009149@139.com
ENV FLASK_PORT=5000

# 启动 Flask 应用
CMD ["python3", "kube-event-webhook.py"]

#构建镜像
docker build -t kube-event-webhook:v1.0.2 .

启动应用

1
2
3
4
5
6
7
8
9
10
11
12
docker run -d \
-p 30000:5000 \
-e TO_ADDRS="15398009149@139.com" \
-e FLASK_PORT=5000 \
-e SMTP_HOST=mta.cmri.cn \
-e SMTP_USER=jtai@cmri.cn \
-e SMTP_PASSWORD=NiUvwE1i \
-e FROM_ADDR=jtai@cmri.cn \
-e /etc/hosts:/etc/hosts \
--name kube-event-webhook \
kube-event-webhook:v1.0.2
# TO_ADDRS变量可以添加多个接收邮件地址

K8S集群event事件告警
http://example.com/2025/02/27/K8S集群event事件告警/
作者
种田人
发布于
2025年2月27日
许可协议