使用Kubernetes Python API列出节点时遇Connection refused错误求助
问题分析与解决方案
核心问题定位
你遇到的ConnectionRefusedError(连接localhost:80失败),本质是Kubernetes Python API未正确加载集群内配置,导致尝试用默认的localhost地址访问API Server,而非集群内正确的kubernetes.default.svc服务地址。同时还存在Dockerfile指令顺序错误、默认服务账户权限不足的潜在问题。
具体问题点及修复步骤
1. Dockerfile指令顺序错误
你的Dockerfile先执行pip install kubernetes再复制requirements.txt,会导致requirements.txt中的依赖无法被安装(若文件内有其他依赖),还浪费Docker缓存层。
修正后的Dockerfile:
FROM python WORKDIR /app # 先复制依赖文件,利用Docker缓存 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 再复制代码文件 COPY main.py . CMD [ "python", "main.py" ]
(确保requirements.txt中包含kubernetes)
2. Pod服务账户配置异常
config.load_incluster_config()依赖两个关键条件:
- Pod内自动注入
KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT环境变量 - Pod自动挂载服务账户的token和CA证书到
/var/run/secrets/kubernetes.io/serviceaccount/目录
如果你的Pod YAML中设置了automountServiceAccountToken: false,或指定了不存在的serviceAccountName,就会导致配置加载失败,进而 fallback到localhost:80。
正确的Pod YAML示例:
apiVersion: v1 kind: Pod metadata: name: node-list-pod spec: containers: - name: node-list-container image: your-image-tag:latest # 以下为默认配置,可省略,确保未禁用自动挂载 # serviceAccountName: default # automountServiceAccountToken: true
3. 默认服务账户权限不足
即使连接API Server成功,默认的default服务账户也没有list nodes的权限,会返回403错误,需提前配置RBAC权限:
第一步:创建ClusterRole(允许节点访问)
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-reader rules: - apiGroups: [""] resources: ["nodes"] verbs: ["list", "get"]
第二步:绑定ClusterRole到默认服务账户
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: node-reader-binding subjects: - kind: ServiceAccount name: default namespace: default roleRef: kind: ClusterRole name: node-reader apiGroup: rbac.authorization.k8s.io
4. 验证Python代码正确性
确保代码正确捕获配置加载异常,避免静默失败:
from kubernetes import config, client def main(): try: # 加载集群内配置 config.load_incluster_config() except config.ConfigException: raise RuntimeError("无法加载集群内配置,请确认Pod运行在Kubernetes集群中") v1 = client.CoreV1Api() print("集群节点列表:") nodes = v1.list_node() for node in nodes.items: print(f"节点名称: {node.metadata.name}, 状态: {node.status.conditions[-1].type}") if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者finks
相关产品推荐
相关产品推荐

