我目前正在尝试使用 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
}
这是我应用于集群的清单:
---
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
我不知道你如何在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
也应该可以工作!