k8s API 通过 pod 内的 python 访问

时间:2021-04-05 10:34:45

标签: python kubernetes microservices

我需要获取 pod 内的资源详细信息,并根据结果执行一些操作。我在 pod 中使用 k8s 客户端 python。在角色/角色绑定之后,我被禁止了。

我已经创建了 Serviceaccount/role/rolebinding,如下所示。

谁能帮我解决这个问题。

apiVersion: v1
kind: ServiceAccount
metadata:
name: myaccount
namespace: dev
          
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: pods-reader-role
rules:
-apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-controller
namespace: dev
subjects:
- kind: ServiceAccount
name: myaccount
apiGroup: ""
roleRef:
kind: Role
name: pods-reader-role
apiGroup: ""


Listing pods with their IPs:
Traceback (most recent call last):
  File "/opt/scripts/bin/PodCont.py", line 792, in <module>
    main()
  File "/opt/scripts/bin/PodCont.py", line 596, in main
    ret = v1.list_pod_for_all_namespaces(watch=False)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/api/core_v1_api.py", line 16864, in list_pod_for_all_namespaces
    return self.list_pod_for_all_namespaces_with_http_info(**kwargs)  # noqa: E501
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/api/core_v1_api.py", line 16981, in list_pod_for_all_namespaces_with_http_info
    collection_formats=collection_formats)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 353, in call_api
    _preload_content, _request_timeout, _host)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 184, in __call_api
    _request_timeout=_request_timeout)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/api_client.py", line 377, in request
    headers=headers)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/rest.py", line 243, in GET
    query_params=query_params)
  File "/usr/local/lib/python3.6/site-packages/kubernetes/client/rest.py", line 233, in request
    raise ApiException(http_resp=r)
kubernetes.client.exceptions.ApiException: (403)
Reason: Forbidden
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'X-Content-Type-Options': 'nosniff', 'Date': 'Mon, 05 Apr 2021 09:47:13 GMT', 'Content-Length': '285'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pods is forbidden: User \"system:serviceaccount:dev:deploy-svc-account\" cannot list resource \"pods\" in API group \"\" at the cluster scope","reason":"Forbidden","details":{"kind":"pods"},"code":403}

1 个答案:

答案 0 :(得分:0)

回答这个问题,我觉得有几点需要考虑:

  • 缩进
  • 运行 Pod 的服务帐户
  • Python 代码和访问范围

由于没有 minimal, reproducible example,我们最多可以假设您的设置是如何准确配置的。


缩进

您包含的 YAML 清单没有正确缩进。正确的清单应如下所示:

  • full.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myaccount
  namespace: dev
---          
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev
  name: pods-reader-role
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pod-controller
  namespace: dev
subjects:
- kind: ServiceAccount
  name: myaccount
  apiGroup: ""
roleRef:
  kind: Role
  name: pods-reader-role
  apiGroup: ""
<块引用>

附注!

考虑为您的用例创建更具限制性的 Role,因为它允许在 dev 命名空间中执行所有操作。


运行 Pod 的服务帐户

这里的潜在问题是您创建了一个名为 serviceAccountmyaccountPod 并且 deploy-svc-account 正在尝试使用 User \"system:serviceaccount:dev:deploy-svc-account\" cannot list resource 进行身份验证。 (serviceAccount)

请确保使用正确的 Pod 来运行 apiVersion: v1 kind: Pod metadata: name: sdk namespace: dev spec: serviceAccountName: myaccount # <-- IMPORTANT containers: - image: google/cloud-sdk command: - sleep - "infinity" imagePullPolicy: IfNotPresent name: sdk restartPolicy: Always

示例:

"Listing pods with their IPs:"

Python 代码和访问范围

假设您使用了 Kubernetes Python API 库 (Role) 文档页面中的代码:

这里有两个主题需要考虑:

  • 访问范围
  • 查询资源

引用官方文档:

<块引用>

角色总是在特定的命名空间内设置权限;创建角色时,必须指定其所属的命名空间。

Kubernetes.io: Docs: Reference: RBAC: Role and ClusterRole

您通过 RoleBindingdev 分配的权限仅适用于 ClusterRole 命名空间。如果您想拥有完整的集群范围,您需要创建一个 ClusterRoleBinding 和一个 from kubernetes import client, config # Configs can be set in Configuration class directly or using helper utility config.load_incluster_config() v1 = client.CoreV1Api() print("Listing pods with their IPs:") ret = v1.list_pod_for_all_namespaces(watch=False) for i in ret.items: print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

我鼓励您查看引文中包含的文档,因为其中有一些示例可供参考,并且对此有很多解释。

另外,关于 Python 代码的一句话:

ret = v1.list_pod_for_all_namespaces(watch=False)

专注于:

Pods

此代码将从所有命名空间中查询 cannot list resource \"pods\" in API group \"\" at the cluster scope",这就是为什么您还会收到错误 Pods

要列出您可以使用的特定命名空间中的 ret = v1.list_namespaced_pod(namespace="dev", watch=False)

python3 program.py

这样你应该能够得到:

  • Listing pods with their IPs: 10.32.0.15 dev sdk
ValueTuple<ElementRowViewModel, SpecificElement>