Kubernetes自动化巡检脚本(Python)

脚本总体

python 复制代码
from kubernetes import client, config
import smtplib
from email.mime.text import MIMEText
import time

class K8sInspection:
    def __init__(self):
        """初始化Kubernetes客户端"""
        try:
            config.load_kube_config()
            self.v1 = client.CoreV1Api()
            self.apps_v1 = client.AppsV1Api()
            self.alerts = []
            print("✅ Kubernetes客户端初始化成功")
        except Exception as e:
            print(f"❌ Kubernetes客户端初始化失败: {e}")
            raise

    def check_node_health(self):
        """检查节点健康状态"""
        print("\n=== 节点健康检查 ===")
        try:
            nodes = self.v1.list_node().items
            for node in nodes:
                node_name = node.metadata.name
                # 检查节点是否就绪
                ready = any(cond.type == 'Ready' and cond.status == 'True' for cond in node.status.conditions)
                if not ready:
                    alert = f"节点 {node_name} 状态异常"
                    print(f"❌ {alert}")
                    self.alerts.append(alert)
                else:
                    print(f"✅ 节点 {node_name} 状态正常")
        except Exception as e:
            alert = f"检查节点健康时出错: {e}"
            print(f"❌ {alert}")
            self.alerts.append(alert)

    def check_pod_status(self):
        """检查Pod状态"""
        print("\n=== Pod状态检查 ===")
        try:
            pods = self.v1.list_pod_for_all_namespaces().items
            for pod in pods:
                namespace = pod.metadata.namespace
                pod_name = pod.metadata.name
                phase = pod.status.phase
                if phase != 'Running':
                    alert = f"Pod {namespace}/{pod_name} 状态异常: {phase}"
                    print(f"❌ {alert}")
                    self.alerts.append(alert)
                else:
                    print(f"✅ Pod {namespace}/{pod_name} 状态正常")
        except Exception as e:
            alert = f"检查Pod状态时出错: {e}"
            print(f"❌ {alert}")
            self.alerts.append(alert)

    def check_pvc_status(self):
        """检查PVC存储状态"""
        print("\n=== PVC存储检查 ===")
        try:
            pvcs = self.v1.list_persistent_volume_claim_for_all_namespaces().items
            for pvc in pvcs:
                namespace = pvc.metadata.namespace
                pvc_name = pvc.metadata.name
                status = pvc.status.phase
                if status != 'Bound':
                    alert = f"PVC {namespace}/{pvc_name} 状态异常: {status}"
                    print(f"❌ {alert}")
                    self.alerts.append(alert)
                else:
                    print(f"✅ PVC {namespace}/{pvc_name} 状态正常")
        except Exception as e:
            alert = f"检查PVC状态时出错: {e}"
            print(f"❌ {alert}")
            self.alerts.append(alert)

    def check_service_availability(self):
        """检查服务可用性"""
        print("\n=== 服务可用性检查 ===")
        try:
            services = self.v1.list_service_for_all_namespaces().items
            for service in services:
                namespace = service.metadata.namespace
                service_name = service.metadata.name
                # 检查服务是否有Endpoints
                try:
                    endpoints = self.v1.read_namespaced_endpoints(service_name, namespace)
                    if not endpoints.subsets:
                        alert = f"服务 {namespace}/{service_name} 无可用端点"
                        print(f"❌ {alert}")
                        self.alerts.append(alert)
                    else:
                        print(f"✅ 服务 {namespace}/{service_name} 状态正常")
                except Exception as e:
                    alert = f"检查服务 {namespace}/{service_name} 时出错: {e}"
                    print(f"❌ {alert}")
                    self.alerts.append(alert)
        except Exception as e:
            alert = f"检查服务可用性时出错: {e}"
            print(f"❌ {alert}")
            self.alerts.append(alert)

    def send_alert_email(self, recipient="收件人邮箱"):
        """发送告警邮件"""
        if not self.alerts:
            print("\n✅ 无告警信息,无需发送邮件")
            return

        print("\n=== 发送告警邮件 ===")
        # 构建邮件内容
        subject = f"K8s集群告警 - {len(self.alerts)}个问题"
        body = "集群中检测到以下问题:\n\n"
        for alert in self.alerts:
            body += f"- {alert}\n"

        # 163邮箱配置
        smtp_server = "smtp.163.com"
        smtp_port = 465
        smtp_user = "发件人邮箱"
        smtp_password = "PFgSR33q9SP49yqh"

        try:
            # 创建邮件
            msg = MIMEText(body)
            msg['Subject'] = subject
            msg['From'] = smtp_user
            msg['To'] = recipient

            # 发送邮件
            server = smtplib.SMTP_SSL(smtp_server, smtp_port)
            server.login(smtp_user, smtp_password)
            server.send_message(msg)
            server.quit()
            print(f"邮件已发送至: {recipient}")
            print(f"告警数量: {len(self.alerts)}")
        except Exception as e:
            print(f"邮件发送失败: {e}")
            # 打印详细错误信息,便于排查
            import traceback
            traceback.print_exc()

    def run_inspection(self):
        """运行完整巡检"""
        print(f"\n开始巡检 - {time.strftime('%Y-%m-%d %H:%M:%S')}")
        self.alerts = []

        # 执行各项检查
        self.check_node_health()
        self.check_pod_status()
        self.check_pvc_status()
        self.check_service_availability()

        # 发送告警邮件
        self.send_alert_email()

        print(f"\n巡检完成 - {time.strftime('%Y-%m-%d %H:%M:%S')}")
        return len(self.alerts) == 0

if __name__ == "__main__":
    try:
        inspector = K8sInspection()
        inspector.run_inspection()
    except Exception as e:
        print(f"巡检执行失败: {e}")
        import traceback
        traceback.print_exc()

脚本解析

依赖库导入

python 复制代码
from kubernetes import client, config  			# 操作 K8s 集群的官方 SDK
import smtplib                       			# 发送邮件
from email.mime.text import MIMEText 			# 构造邮件内容
import time                          			# 获取时间戳
  • kubernetes:核心库,用来获取集群所有资源状态
  • smtplib:邮件发送协议库,对接 163 邮箱
  • time:打印巡检开始 / 结束时间

核心类:K8sInspection

  • 初始化方法 __init__
  • 检查节点健康 check_node_health()
  • 检查 Pod 状态 check_pod_status()
  • 检查 PVC 存储状态 check_pvc_status()
  • 检查服务可用性 check_service_availability()
  • 告警邮件发送 send_alert_email()
  • 完整巡检入口 run_inspection()

初始化方法 __init__

python 复制代码
def __init__(self):
    try:
        config.load_kube_config()  				# 加载本机 ~/.kube/config 认证文件
        self.v1 = client.CoreV1Api()       		# 核心资源 API(节点/Pod/PVC/服务)
        self.apps_v1 = client.AppsV1Api()   	# 工作负载 API(控制器)
        self.alerts = []                   		# 告警列表:存所有异常
        print("✅ Kubernetes客户端初始化成功")
    except Exception as e:
        print(f"❌ Kubernetes客户端初始化失败: {e}")
        raise

代码详细解析:

复制代码
config.load_kube_config()
使用的是 Kubernetes SDK包中的config模块中的load_kube_config函数
作用是加载当前用户目录下的 K8s 认证文件~/.kube/config让程序获得访问 K8s 集群的权限。

self.v1 = client.CoreV1Api()
CoreV1Api () 是一个类的构造方法,同理来自kubernetes.client.api.core_v1_api
提供操作 K8s 核心资源的方法:
list_node () → 获取节点
list_pod_for_all_namespaces () → 获取所有 Pod
list_persistent_volume_claim_for_all_namespaces () → 获取 PVC
list_service_for_all_namespaces () → 获取服务

self.apps_v1 = client.AppsV1Api()
同理AppsV1Api () 是一个类
它能操作什么?
Deployment
StatefulSet
DaemonSet
ReplicaSet

self.alerts = [] 
Python 内置语法,创建一个空列表,不属于任何包

作用

  • 读取服务器上的 K8s 认证配置,连接集群
  • 创建两个 API 客户端,主要用于调用查看集群资源与控制器资源
  • 初始化一个空列表 alerts,专门收集巡检异常

运行前提:脚本所在机器必须配置好 ~/.kube/config,能正常用 kubectl 操作集群。

检查节点健康 check_node_health()

python 复制代码
def check_node_health(self):
    nodes = self.v1.list_node().items
    for node in nodes:
        node_name = node.metadata.name
        # 判断节点是否为 Ready 状态
        ready = any(cond.type == 'Ready' and cond.status == 'True' for cond in node.status.conditions)
        if not ready:
            alert = f"节点 {node_name} 状态异常"
            self.alerts.append(alert)

代码详细解析:

复制代码
nodes = self.v1.list_node().items
self.v1 	来源是__init__ 里的 self.v1 = client.CoreV1Api(),含义是K8s 核心 API 操作客户端
list_node() 调用 K8s API 获取所有节点列表返回一个V1NodeList 对象(节点列表包装类)
.items		来源于V1NodeList 对象,意思是真正的节点数组(list)
整行意思是获取集群所有节点,存入 nodes 变量
 
for node in nodes:
Python 循环语法,node = 每一个V1Node 对象(单个节点)
 
node_name = node.metadata.name
.metadata 	存放节点的元信息:名称、标签、注解等
.name		来自:metadata,含义:节点名称(如 master01、node01)
整行意思是从节点对象里取出节点名字,存到 node_name
 
ready = any(cond.type == 'Ready' and cond.status == 'True' for cond in node.status.conditions)
any(...)  Python 内置函数 只要有一个条件满足,就返回 True
for cond in node.status.conditions 每个节点的状态
cond.type == 'Ready'	K8s 节点状态里 最重要的条件,表示节点是否就绪	
cond.status == 'True'	状态为 True = 正常,False = 异常
整行意思:遍历节点所有状态条件 → 只要有一个是 Ready=True → 节点正常

if not ready: 
如果节点不是 Ready 状态

alert = f"节点 {node_name} 状态异常"
生成告警字符串

self.alerts.append(alert)
self.alerts 来自:__init__ 里定义的列表,用来存放所有告警信息
.append(alert)	Python 列表内置方法,把告警信息加入列表
整行意思:把节点异常信息存入告警列表,后面统一发邮件

功能:

  • 获取所有节点
  • 检查节点状态是否为 Ready
  • 非 Ready → 加入告警列表

检查 Pod 状态 check_pod_status()

python 复制代码
def check_pod_status(self):
    pods = self.v1.list_pod_for_all_namespaces().items
    for pod in pods:
        namespace = pod.metadata.namespace
        pod_name = pod.metadata.name
        phase = pod.status.phase
        if phase != 'Running':
            alert = f"Pod {namespace}/{pod_name} 状态异常: {phase}"
            self.alerts.append(alert)

功能

  • 遍历所有命名空间的 Pod
  • 只要 Pod 不是 Running 状态(如 Pending、Error、Completed)
  • 全部判定为异常,加入告警

检查 PVC 存储状态 check_pvc_status()

python 复制代码
def check_pvc_status(self):
    pvcs = self.v1.list_persistent_volume_claim_for_all_namespaces().items
    for pvc in pvcs:
        status = pvc.status.phase
        if status != 'Bound':
            alert = f"PVC {namespace}/{pvc_name} 状态异常: {status}"
            self.alerts.append(alert)

功能

  • PVC 是 K8s 存储卷声明
  • 正常状态必须是 Bound(已绑定存储)
  • 非 Bound → 异常(挂载失败、存储不存在)

检查服务可用性 check_service_availability()

python 复制代码
def check_service_availability(self):
    services = self.v1.list_service_for_all_namespaces().items
    for service in services:
        endpoints = self.v1.read_namespaced_endpoints(service_name, namespace)
        if not endpoints.subsets:
            alert = f"服务 {namespace}/{service_name} 无可用端点"
            self.alerts.append(alert)

功能

  • Service 必须有后端端点(Endpoint)才能提供服务
  • 如果没有可用后端 Pod → Service 无法访问 → 告警

告警邮件发送 send_alert_email()

python 复制代码
def send_alert_email(self, recipient="收件人邮箱"):
    if not self.alerts:
        print("\n✅ 无告警信息,无需发送邮件")
        return

    # 邮件标题 + 内容
    subject = f"K8s集群告警 - {len(self.alerts)}个问题"
    body = "集群中检测到以下问题:\n\n"
    for alert in self.alerts:
        body += f"- {alert}\n"

    # 163 邮箱配置
    smtp_server = "smtp.163.com"
    smtp_port = 465
    smtp_user = "发件人邮箱"
    smtp_password = "PFgSR33q9SP49yqh"  # 这是 163 授权码,不是登录密码

核心说明

  • 无告警 → 不发邮件
  • 有告警 → 把所有异常汇总成一封邮件
  • 使用 163 邮箱 SSL 465 端口 发送
  • smtp_password邮箱授权码,不是邮箱密码

完整巡检入口 run_inspection()

python 复制代码
def run_inspection(self):
    print(f"\n开始巡检 - {time.strftime('%Y-%m-%d %H:%M:%S')}")
    self.alerts = []  # 清空上一次告警

    # 依次执行所有检查
    self.check_node_health()
    self.check_pod_status()
    self.check_pvc_status()
    self.check_service_availability()

    self.send_alert_email()  # 发送邮件

作用

  • 一键执行全部四项巡检
  • 清空历史告警
  • 最后统一发邮件

脚本主运行入口

bash 复制代码
if __name__ == "__main__":
    try:
        inspector = K8sInspection()
        inspector.run_inspection()
    except Exception as e:
        print(f"巡检执行失败: {e}")

脚本测试

在集群测试

首先安装依赖

复制代码
[root@master01 ~]# dnf install pip -y
[root@master01 ~]# pip install kubernete

运行脚本文件

bash 复制代码
[root@master01 ~]# python inspection.py

运行结果

复制代码
[root@master01 ~]# python inspection.py
✅ Kubernetes客户端初始化成功

开始巡检 - 2026-04-12 19:43:43

=== 节点健康检查 ===
✅ 节点 master01 状态正常
✅ 节点 master02 状态正常
❌ 节点 master03 状态异常
✅ 节点 node01 状态正常
✅ 节点 node02 状态正常

=== Pod状态检查 ===
✅ Pod default/curl-test 状态正常
✅ Pod headlamp/headlamp-97b945999-2h6rl 状态正常
✅ Pod headlamp/headlamp-97b945999-8ksmm 状态正常
✅ Pod headlamp/headlamp-97b945999-ph458 状态正常
✅ Pod ingress-nginx/ingress-nginx-controller-56d766b97d-222b6 状态正常
✅ Pod ingress-nginx/ingress-nginx-controller-56d766b97d-9whlj 状态正常
❌ Pod ingress-nginx/ingress-nginx-controller-56d766b97d-nsqgr 状态异常: Pending
✅ Pod ingress-nginx/ingress-nginx-controller-56d766b97d-thmnr 状态正常
✅ Pod kube-system/calico-kube-controllers-5d8c4fd744-4zk2p 状态正常
✅ Pod kube-system/calico-node-cj6sx 状态正常
✅ Pod kube-system/calico-node-pmj2s 状态正常
✅ Pod kube-system/calico-node-sbn45 状态正常
✅ Pod kube-system/calico-node-tlk4h 状态正常
✅ Pod kube-system/calico-node-vrxbb 状态正常
✅ Pod kube-system/calico-typha-7df5fcc5b-6dc6w 状态正常
✅ Pod kube-system/coredns-f78dcf544-2b6n6 状态正常
✅ Pod kube-system/coredns-f78dcf544-pnrfk 状态正常
✅ Pod kube-system/coredns-f78dcf544-w7qxj 状态正常
✅ Pod kube-system/coredns-f78dcf544-ztxcs 状态正常
✅ Pod kube-system/etcd-master01 状态正常
✅ Pod kube-system/etcd-master02 状态正常
✅ Pod kube-system/etcd-master03 状态正常
✅ Pod kube-system/kube-apiserver-master01 状态正常
✅ Pod kube-system/kube-apiserver-master02 状态正常
✅ Pod kube-system/kube-apiserver-master03 状态正常
✅ Pod kube-system/kube-controller-manager-master01 状态正常
✅ Pod kube-system/kube-controller-manager-master02 状态正常
✅ Pod kube-system/kube-controller-manager-master03 状态正常
✅ Pod kube-system/kube-proxy-g9q8r 状态正常
✅ Pod kube-system/kube-proxy-htcq2 状态正常
✅ Pod kube-system/kube-proxy-qs79w 状态正常
✅ Pod kube-system/kube-proxy-thcjx 状态正常
✅ Pod kube-system/kube-proxy-xb6kf 状态正常
✅ Pod kube-system/kube-scheduler-master01 状态正常
✅ Pod kube-system/kube-scheduler-master02 状态正常
✅ Pod kube-system/kube-scheduler-master03 状态正常
✅ Pod kube-system/metrics-server-85c788996d-9kfnw 状态正常
✅ Pod kube-system/metrics-server-85c788996d-pnrcg 状态正常
✅ Pod longhorn-system/csi-attacher-589b76ddcb-76rvr 状态正常
✅ Pod longhorn-system/csi-attacher-589b76ddcb-k6h7f 状态正常
✅ Pod longhorn-system/csi-attacher-589b76ddcb-m2cgl 状态正常
✅ Pod longhorn-system/csi-provisioner-6d744bccdf-6df2p 状态正常
✅ Pod longhorn-system/csi-provisioner-6d744bccdf-9tx5v 状态正常
✅ Pod longhorn-system/csi-provisioner-6d744bccdf-r8xb9 状态正常
✅ Pod longhorn-system/csi-resizer-64c678dd69-8fcxj 状态正常
✅ Pod longhorn-system/csi-resizer-64c678dd69-9gf6h 状态正常
✅ Pod longhorn-system/csi-resizer-64c678dd69-m6n95 状态正常
✅ Pod longhorn-system/csi-snapshotter-559c9d464b-bfv8z 状态正常
✅ Pod longhorn-system/csi-snapshotter-559c9d464b-dq68w 状态正常
✅ Pod longhorn-system/csi-snapshotter-559c9d464b-mzr75 状态正常
✅ Pod longhorn-system/engine-image-ei-75a03ec3-tbq9v 状态正常
✅ Pod longhorn-system/engine-image-ei-75a03ec3-x8nwc 状态正常
✅ Pod longhorn-system/instance-manager-43e1ac4d24ce2cb53765e97ec75c6776 状态正常
✅ Pod longhorn-system/instance-manager-eb505e2fede72466f477ad7517399268 状态正常
✅ Pod longhorn-system/longhorn-csi-plugin-fl4kr 状态正常
✅ Pod longhorn-system/longhorn-csi-plugin-ftmbg 状态正常
✅ Pod longhorn-system/longhorn-driver-deployer-76cc8bdb6-wzxvr 状态正常
✅ Pod longhorn-system/longhorn-manager-6pzh5 状态正常
✅ Pod longhorn-system/longhorn-manager-7n8c5 状态正常
✅ Pod longhorn-system/longhorn-ui-785fd648-9m6br 状态正常
✅ Pod monitoring/alertmanager-main-0 状态正常
✅ Pod monitoring/alertmanager-main-1 状态正常
✅ Pod monitoring/alertmanager-main-2 状态正常
✅ Pod monitoring/blackbox-exporter-7c56dbff45-r9wv7 状态正常
✅ Pod monitoring/grafana-665bcf59d8-zxcfp 状态正常
✅ Pod monitoring/kube-state-metrics-5d9cccb687-rl4zj 状态正常
✅ Pod monitoring/loki-0 状态正常
✅ Pod monitoring/loki-promtail-2dmrh 状态正常
✅ Pod monitoring/loki-promtail-7v27c 状态正常
✅ Pod monitoring/loki-promtail-mfch2 状态正常
✅ Pod monitoring/loki-promtail-wsgql 状态正常
❌ Pod monitoring/node-exporter-7vj9w 状态异常: Pending
✅ Pod monitoring/node-exporter-8d4pl 状态正常
✅ Pod monitoring/node-exporter-hkvrk 状态正常
✅ Pod monitoring/node-exporter-jthxj 状态正常
❌ Pod monitoring/node-exporter-m8hss 状态异常: Pending
✅ Pod monitoring/node-exporter-q6lpw 状态正常
✅ Pod monitoring/prometheus-adapter-6695cb6f7d-b9bfr 状态正常
✅ Pod monitoring/prometheus-adapter-6695cb6f7d-v9h7f 状态正常
✅ Pod monitoring/prometheus-k8s-0 状态正常
✅ Pod monitoring/prometheus-k8s-1 状态正常
✅ Pod monitoring/prometheus-operator-7f965998bc-2ppsw 状态正常

=== PVC存储检查 ===
✅ PVC monitoring/grafana-storage 状态正常
✅ PVC monitoring/prometheus-k8s-db-prometheus-k8s-0 状态正常
✅ PVC monitoring/prometheus-k8s-db-prometheus-k8s-1 状态正常
✅ PVC monitoring/storage-loki-0 状态正常

=== 服务可用性检查 ===
✅ 服务 default/kubernetes 状态正常
✅ 服务 headlamp/headlamp 状态正常
✅ 服务 ingress-nginx/ingress-nginx-controller 状态正常
✅ 服务 ingress-nginx/ingress-nginx-controller-admission 状态正常
✅ 服务 kube-system/calico-typha 状态正常
✅ 服务 kube-system/kube-dns 状态正常
✅ 服务 kube-system/kubelet 状态正常
✅ 服务 kube-system/metrics-server 状态正常
✅ 服务 longhorn-system/longhorn-admission-webhook 状态正常
✅ 服务 longhorn-system/longhorn-backend 状态正常
✅ 服务 longhorn-system/longhorn-frontend 状态正常
✅ 服务 longhorn-system/longhorn-recovery-backend 状态正常
✅ 服务 monitoring/alertmanager-main 状态正常
✅ 服务 monitoring/alertmanager-operated 状态正常
✅ 服务 monitoring/blackbox-exporter 状态正常
✅ 服务 monitoring/grafana 状态正常
✅ 服务 monitoring/kube-state-metrics 状态正常
✅ 服务 monitoring/loki 状态正常
✅ 服务 monitoring/loki-headless 状态正常
✅ 服务 monitoring/loki-memberlist 状态正常
✅ 服务 monitoring/node-exporter 状态正常
✅ 服务 monitoring/prometheus-adapter 状态正常
✅ 服务 monitoring/prometheus-k8s 状态正常
✅ 服务 monitoring/prometheus-operated 状态正常
✅ 服务 monitoring/prometheus-operator 状态正常

=== 发送告警邮件 ===
邮件已发送至: XXXXXXXXXXXX
告警数量: 4

由于在集群中后面pod数量起来后集群资源不够,把master03关了验证etcd的堆叠高可用集群还能继续使用,导致的有些pod处于pending状态,模拟告警数量。

相关推荐
lichenyang4534 天前
Docker 学习笔记(四):Dockerfile,把项目打成自己的镜像
docker·容器
lichenyang4534 天前
Docker 学习笔记(三):Docker 网络、bridge、子网和容器互通
docker·容器
lichenyang4534 天前
Docker 学习笔记(二):docker run 的参数到底在控制什么?
docker·容器
运维开发故事7 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson8 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生9 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭9 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美10 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵10 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程