尝试列出 Pod 时出现 HTTP 403 禁止

问题描述 投票:0回答:1

问题

我目前正在尝试使用 Kubernetes Server API 客户端 (Python) 来访问集群资源。

但是,我似乎无法使其发挥作用。由于某种原因,即使已配置应用的清单,我也无法列出 Pod,并且正确配置:

$ kubectl auth can-i list pods --as=system:serviceaccount:default:my-service-account
yes
import kubernetes as k8s

from kubernetes.client.api.core_api import ApiClient
from kubernetes import client, config

service_account_name = "my-service-account"
SA_TOKEN = "the-token"

# Configure API key authorization: BearerToken
configuration = k8s.client.Configuration(
    host="https://192.168.49.2:8443",
    api_key={"authorization": SA_TOKEN},
    api_key_prefix={"authorization": "Bearer"},
    username=service_account_name,
    discard_unknown_keys=True
)

configuration.verify_ssl = False
configuration.client_side_validation = False

api_client = k8s.client.ApiClient(configuration=configuration)
v1 = k8s.client.CoreV1Api(api_client)

v1.list_namespaced_pod("default")

输出:

ApiException: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'Audit-Id': 'c0ec14f1-80fb-4177-b719-273c76230f6c', 'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Thu, 24 Aug 2023 09:00:59 GMT', 'Content-Length': '129'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Unauthorized","reason":"Unauthorized","code":401}

我尝试手动发出

curl
请求,结果相同:

$ curl --cert ~/.minikube/ca.crt --key ~/.minikube/ca.key -k \
        -H "Authorization: Bearer $(kubectl get secret my-secret -o jsonpath='{.data.token}')" \
        https://192.168.49.2:8443/api/v1/namespaces/default/pods

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods is forbidden: User \"minikubeCA\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
}

Kubernetes 清单

这是我应用于集群的清单:

---
apiVersion: v1
kind: ServiceAccount

metadata:
  name: my-service-account
  namespace: default

secrets:
  - name: my-secret


---
apiVersion: v1
kind: Secret

metadata:
  name: my-secret
  namespace: default
  annotations:
    kubernetes.io/service-account.name: my-service-account

type: kubernetes.io/service-account-token


---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role

metadata:
  namespace: default
  name: reader-role

rules:
- apiGroups: [""]  # Empty string ("") indicates core API group
  resources: ["pods", "pods/logs"]
  verbs: ["get", "watch", "list"]


---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding

metadata:
  name: reader-binding
  namespace: default

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: reader-role

subjects:
- kind: ServiceAccount
  name: my-service-account
  namespace: default
kubernetes minikube
1个回答
0
投票

我不知道你如何在Python脚本中获得

SA_TOKEN
,但是如果
curl
命令发出完全相同的请求,那么问题就来自于你没有在之后
base64
解码令牌从秘密中取回它。

要获取令牌,您应该编写:

kubectl get secret my-secret -o jsonpath='{.data.token}' | base64 -d

而不是:

kubectl get secret my-secret -o jsonpath='{.data.token}'

注意

base64 -d
操作。

然后:

curl -k \
    -H "Authorization: Bearer $(kubectl get secret my-secret -o jsonpath='{.data.token}' | base64 -d)" \
    https://192.168.49.2:8443/api/v1/namespaces/default/pods

应该按预期工作:

{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "857"
  },
  "items": []
}

所以,对于你的Python脚本,

SA_TOKEN=$(kubectl get secret my-secret -o jsonpath='{.data.token}' | base64 -d) python my_script.py
也应该可以工作!

© www.soinside.com 2019 - 2024. All rights reserved.