Kubernetes Pod内调用API报403 无法在集群范围访问资源
kubernetes v1.23.6 rancher-desktop v1.3.0
在Pod内部调用Kubernetes API HTTP接口,已配置具备对应API访问权限的ServiceAccount,请求预期有权限访问的资源时返回403 Forbidden错误。
执行的curl请求命令如下:
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://kubernetes.default.svc/api/v1/default/pods/ubuntu
其中$KUBE_TOKEN为从路径/var/run/secrets/kubernetes.io/serviceaccount/token读取的ServiceAccount令牌值。
请求返回结果:
{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "default \"pods\" is forbidden: User \"system:serviceaccount:default:podkiller\" cannot get resource \"default/ubuntu\" in API group \"\" at the cluster scope", "reason": "Forbidden", "details": { "name": "pods", "kind": "default" }, "code": 403 }
最初配置Role时可正常调用API,未配置对应权限前所有请求均返回403,已排查排除命名空间配置错误、角色与账号未绑定类问题,相关配置如下:
ServiceAccount配置
apiVersion: v1 kind: ServiceAccount metadata: name: podkiller automountServiceAccountToken: true
ClusterRole配置
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: podkiller rules: - apiGroups: [""] resources: ["pods","nodes"] verbs: ["get", "watch", "list", "delete"]
ClusterRoleBinding配置
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: podkiller subjects: - kind: ServiceAccount name: podkiller namespace: default roleRef: kind: ClusterRole name: podkiller apiGroup: rbac.authorization.k8s.io
Pod配置
apiVersion: v1 kind: Pod metadata: name: ubuntu labels: app: ubuntu spec: serviceAccountName: podkiller automountServiceAccountToken: true containers: - image: ubuntu command: - "sleep" - "604800" imagePullPolicy: IfNotPresent name: ubuntu restartPolicy: Always
问题和RBAC权限配置无关,核心原因是Kubernetes API请求路径写错。
Kubernetes核心API组(空组,即apiGroups: [""])的命名空间级资源请求路径固定格式为:/api/v1/namespaces/{命名空间名}/{资源类型}/{资源名}
你写的路径是/api/v1/default/pods/ubuntu,缺少了namespaces路径段,API服务器会将该请求识别为集群范围请求,尝试访问名为default的资源类型下的对象,而非访问default命名空间下的pods资源,最终触发权限校验失败返回403。
这也和你之前用Role能正常调用的现象吻合:用Role时你写的是包含namespaces段的正确路径,换ClusterRole测试时写错了路径,才会误以为是RBAC配置问题。
将curl请求的URL修正为正确格式即可:
# 访问default命名空间下名为ubuntu的Pod curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://kubernetes.default.svc/api/v1/namespaces/default/pods/ubuntu
后续遇到Kubernetes API 403问题时,可以先用kubectl auth can-i命令预检权限,快速区分是路径错误还是真的权限配置问题:
# 预检指定ServiceAccount是否有default命名空间下get pod的权限,在配置了对应kubeconfig的节点上执行 kubectl auth can-i get pods -n default --as=system:serviceaccount:default:podkiller
如果命令返回yes说明RBAC配置完全正常,问题出在请求路径、请求方法等环节,不用反复排查Role/ClusterRole绑定配置。
内容的提问来源于stack exchange,提问作者clbx

