我正在进行服务账户的实验。我认为以下代码应该产生访问错误(但实际上没有产生):
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
serviceAccountName: test-sa
containers:
- image: alpine
name: test-container
command: [sh]
args:
- -ec
- |
apk add curl;
KUBE_NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)";
curl \
--cacert "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
"https://kubernetes.default.svc/api/v1/namespaces/$KUBE_NAMESPACE/services";
while true; do sleep 1; done;
kubectl apply -f test.yml
kubectl logs test-pod
我看到的是服务成功列出,但我预期应该会出现权限错误,因为我从未为`test-sa`创建任何`RoleBinding`或`ClusterRoleBinding`。
我正在努力寻找列出特定SA可用权限的方法,但根据Kubernetes check serviceaccount permissions,可以使用以下命令实现:
kubectl auth can-i list services --as=system:serviceaccount:default:test-sa
> yes
虽然我怀疑那个命令是否真正有效,因为我可以用任何无意义的词替换test-sa
并且它仍然显示“是”。
根据文档,服务帐户默认情况下向所有经过身份验证的用户授予“发现权限(discovery permissions)”。它没有说明具体意思,但从更多的阅读中,我找到了这个资源,这可能就是它所指的:
kubectl get clusterroles system:discovery -o yaml
> [...]
> rules:
> - nonResourceURLs:
> - /api
> - /api/*
> [...]
> verbs:
> - get
这意味着所有服务账户都对所有API端点具有get
权限,尽管“nonResourceURLs”位表明这不适用于资源类型的API(例如services),即使这些API位于该路径下……(???)
如果完全删除Authorization
头,则会按预期看到访问错误。但我不明白为什么可以使用此空服务帐户获取数据。我的误解是什么,如何正确地限制权限?
kubectl get role,rolebinding -n default
和kubectl get clusterrole,clusterrolebinding
命令的输出吗? - Arghya Sadhucluster-admin
的ClusterRole? - Arghya Sadhukubectl cluster-info dump | grep authorization-mode
显示访问控制模式为Node,RBAC
。 - Daveclusterrolebinding docker-for-desktop-binding
,它将cluster-admin
添加到了system:serviceaccounts
中(?!)。因此看来这确实是一个 Docker 桌面应用程序的问题。 - Dave