简体   繁体   English

Kubernetes 服务帐号默认权限

[英]Kubernetes service account default permissions

I am experimenting with service accounts.我正在试验服务帐户。 I believe the following should produce an access error (but it doesn't):我相信以下应该会产生访问错误(但不会):

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

What I see is a successful listing of services, but I would expect a permissions error because I never created any RoleBinding s or ClusterRoleBinding s for test-sa .我看到的是成功的服务列表,但我预计会出现权限错误,因为我从未为test-sa创建任何RoleBindingClusterRoleBinding

I'm struggling to find ways to list the permissions available to a particular SA, but according to Kubernetes check serviceaccount permissions , it should be possible with:我正在努力寻找列出特定 SA 可用权限的方法,但根据Kubernetes check serviceaccount permissions ,应该可以:

kubectl auth can-i list services --as=system:serviceaccount:default:test-sa
> yes

Though I'm skeptical whether that command is actually working, because I can replace test-sa with any gibberish and it still says "yes".虽然我怀疑该命令是否真的有效,因为我可以用任何乱码替换test-sa并且它仍然说“是”。


According to the documentation, service accounts by default have "discovery permissions given to all authenticated users" .根据文档,默认情况下服务帐户具有“授予所有经过身份验证的用户的发现权限” It doesn't say what that actually means, but from more reading I found this resource which is probably what it's referring to:它没有说明这实际上意味着什么,但从更多阅读中我发现这个资源可能就是它所指的:

kubectl get clusterroles system:discovery -o yaml
> [...]
> rules:
> - nonResourceURLs:
>   - /api
>   - /api/*
> [...]
>   verbs:
>   - get

Which would imply that all service accounts have get permissions on all API endpoints, though the "nonResourceURLs" bit implies this wouldn't apply to APIs for resources like services, even though those APIs live under that path… (???)这意味着所有服务帐户get有权访问所有 API 端点,尽管“nonResourceURLs”位意味着这不适用于服务等资源的 API,即使这些 API 位于该路径下……(???)


If I remove the Authorization header entirely, I see an access error as expected.如果我完全删除Authorization header,我会看到预期的访问错误。 But I don't understand why it's able to get data using this empty service account.但我不明白为什么它能够使用这个空的服务帐户获取数据。 What's my misunderstanding and how can I restrict permissions correctly?我有什么误解,如何正确限制权限?

It turns out this is a bug in Docker Desktop for Mac's Kubernetes support.事实证明,这是 Docker Desktop for Mac 的 Kubernetes 支持中的一个错误。

It automatically adds a ClusterRoleBinding giving cluster-admin to all service accounts (.).它会自动添加一个ClusterRoleBinding ,为所有服务帐户(.) 提供cluster-admin It only intends to give this to service accounts inside the kube-system namespace.它只打算将其提供给kube-system命名空间内的服务帐户。

It was originally raised in docker/for-mac#3694 but fixed incorrectly.它最初是在docker/for-mac#3694中提出的,但修复不正确。 I have raised a new issue docker/for-mac#4774 (the original issue is locked due to age).我提出了一个新问题docker/for-mac#4774 (原问题由于年龄原因被锁定)。

A quick fix while waiting for the bug to be resolved is to run:等待解决错误时的快速修复是运行:

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

I don't know if that might cause issues with future Docker Desktop upgrades but it does the job for now.我不知道这是否会导致未来 Docker 桌面升级出现问题,但它现在可以完成这项工作。

With that fixed, the code above correctly gives a 403 error, and would require the following to explicitly grant access to the services resource:修复后,上面的代码正确地给出了 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

A useful command for investigating is kubectl auth can-i --list --as system:serviceaccount , which shows the rogue permissions were applying to all service accounts:一个有用的调查命令是kubectl auth can-i --list --as system:serviceaccount ,它显示恶意权限应用于所有服务帐户:

 Resources Non-Resource URLs Resource Names Verbs *.* [] [] [*] [*] [] [*] [...]

The same bug exists in Docker-Desktop for Windows. Windows 的 Docker-Desktop 中存在相同的错误。

It automatically adds a ClusterRoleBinding giving cluster-admin to all service accounts (.).它会自动添加一个 ClusterRoleBinding,为所有服务帐户 (.) 提供 cluster-admin。 It only intends to give this to service accounts inside the kube-system namespace.它只打算将其提供给 kube-system 命名空间内的服务帐户。

This is because in Docker Desktop by default a clusterrolebinding docker-for-desktop-binding gives cluster-admin role to all the service accounts created.这是因为在 Docker Desktop 默认情况下,clusterrolebinding docker docker-for-desktop-binding为所有创建的服务帐户提供cluster-admin角色。

For more details check the issue here有关更多详细信息,请在此处查看问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM