如何使用Python获取运行Kubernetes的服务器操作系统版本
实现方案
完全可以通过Python实现,核心逻辑是:Kubelet启动时会自动将宿主机的操作系统版本、内核版本等信息上报给API Server,存储在Node资源的status.nodeInfo.osImage字段中,不需要登录宿主机、不需要挂载宿主机系统目录,通过官方Kubernetes Python客户端调用集群API即可拿到目标值。
前置要求
- 运行代码的Pod需要绑定最小RBAC权限:允许读取自身Pod信息、允许读取Node资源
- 容器默认会自动挂载ServiceAccount的访问凭证,不需要手动上传认证文件
最小权限的ClusterRole配置参考:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: read-host-os-info rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get"] - apiGroups: [""] resources: ["pods"] verbs: ["get"]
将该ClusterRole通过ClusterRoleBinding绑定到Pod使用的ServiceAccount即可。
基于官方kubernetes Python客户端的实现
首先安装依赖:pip install kubernetes
实现代码:
from kubernetes import client, config import os def get_current_host_os(): # 自动加载容器内的ServiceAccount认证配置,无需指定kubeconfig config.load_incluster_config() v1 = client.CoreV1Api() # 读取当前Pod所在命名空间 namespace_path = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" current_namespace = open(namespace_path).read().strip() # 读取当前Pod名称,提前通过Downward API注入环境变量 current_pod_name = os.getenv("POD_NAME") # 查询当前Pod信息,拿到所在节点名称 current_pod = v1.read_namespaced_pod(name=current_pod_name, namespace=current_namespace) target_node_name = current_pod.spec.node_name # 查询节点信息,提取OS版本 target_node = v1.read_node(name=target_node_name) return target_node.status.node_info.os_image if __name__ == "__main__": print(f"当前宿主机操作系统版本:{get_current_host_os()}")
Pod配置中需要通过Downward API注入Pod名称环境变量,配置片段:
env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name
轻量实现(无kubernetes客户端依赖)
如果不想引入全量Kubernetes客户端依赖,可以直接调用API Server的原生REST接口,仅需requests库即可实现:
安装依赖:pip install requests
实现代码:
import os import requests def get_current_host_os_lightweight(): api_server = "https://kubernetes.default.svc" sa_root = "/var/run/secrets/kubernetes.io/serviceaccount" # 读取内置认证凭证 with open(f"{sa_root}/token", "r") as f: token = f.read().strip() with open(f"{sa_root}/namespace", "r") as f: namespace = f.read().strip() ca_cert = f"{sa_root}/ca.crt" pod_name = os.getenv("POD_NAME") headers = {"Authorization": f"Bearer {token}"} # 查询当前Pod所在节点 pod_resp = requests.get( f"{api_server}/api/v1/namespaces/{namespace}/pods/{pod_name}", headers=headers, verify=ca_cert ) pod_resp.raise_for_status() node_name = pod_resp.json()["spec"]["nodeName"] # 查询节点OS信息 node_resp = requests.get( f"{api_server}/api/v1/nodes/{node_name}", headers=headers, verify=ca_cert ) node_resp.raise_for_status() return node_resp.json()["status"]["nodeInfo"]["osImage"]
注意事项
- 不推荐通过hostPath挂载宿主机
/etc/os-release的方式获取信息,该方案需要配置特权级目录挂载,存在安全风险 - 接口返回的
osImage字段值和宿主机本地执行lsb_release -d的输出完全一致,例如Ubuntu 20.04节点会返回Ubuntu 20.04.1 LTS,完全匹配你需要的版本标识格式 - 代码仅能在集群内的容器中运行,本地调试时可以替换
load_incluster_config()为config.load_kube_config()加载本地kubeconfig测试
内容的提问来源于stack exchange,提问作者twome
相关产品推荐
相关产品推荐

