You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:51:16