Kubernetes服务账户默认权限

3

我正在进行服务账户的实验。我认为以下代码应该产生访问错误(但实际上没有产生):

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 defaultkubectl get clusterrole,clusterrolebinding 命令的输出吗? - Arghya Sadhu
你是否创建了一个ClusterRoleBinding,用于将这个服务账户绑定到cluster-admin的ClusterRole? - Arghya Sadhu
如果有帮助的话:这是使用Docker内置的“启用Kubernetes”选项进行的本地测试部署。我相信它没有自定义配置。就其价值而言,运行 kubectl cluster-info dump | grep authorization-mode 显示访问控制模式为 Node,RBAC - Dave
我会请一些同事在不同的环境下尝试。也许这与Docker桌面捆绑Kubernetes的方式有关? - Dave
1
@ArghyaSadhu 一位同事帮我找到了 clusterrolebinding docker-for-desktop-binding,它将 cluster-admin 添加到了 system:serviceaccounts 中(?!)。因此看来这确实是一个 Docker 桌面应用程序的问题。 - Dave
显示剩余4条评论
3个回答

3
事实证明,这是Docker Desktop for Mac的Kubernetes支持中的一个错误。它会自动添加一个ClusterRoleBinding,将cluster-admin授权给所有服务帐户(!)。它只想将其授予kube-system命名空间内的服务帐户。最初在docker/for-mac#3694中提出,但修复不正确。我已经提出了一个新问题docker/for-mac#4774(原始问题由于年龄而被锁定)。在等待解决此错误的快速修复是运行:
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: docker-for-desktop-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:serviceaccounts:kube-system
EOF

我不知道这是否会影响未来的Docker Desktop升级,但现在它可以完成工作。
修复后,上述代码会正确返回403错误,并需要以下内容才能显式授予对服务资源的访问权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: service-reader
rules:
- apiGroups: [""]
  resources: [services]
  verbs: [get, list]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-sa-service-reader-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: service-reader
subjects:
- kind: ServiceAccount
  name: test-sa

一个有用的命令用于调查是kubectl auth can-i --list --as system:serviceaccount,它显示我们正在应用于所有服务账户的恶意权限:
Resources                       Non-Resource URLs   Resource Names   Verbs
*.*                             []                  []               [*]
                                [*]                 []               [*]
[...]

1
同样的错误也存在于Windows的Docker桌面版中。
它会自动添加一个ClusterRoleBinding,将cluster-admin授权给所有的服务账户(!)。但它只是想将其授予kube-system命名空间内的服务账户。

0

这是因为在 Docker Desktop 中,默认情况下,clusterrolebinding docker-for-desktop-binding 会将 cluster-admin 角色授予所有创建的服务帐户。

有关更多详细信息,请查看 此处 的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接