首页 > 解决方案 > 正确使用 Role.rules.resourceNames 来创建对资源的访问受限的 pod

问题描述

我正在尝试创建一个能够使用Role.rules.resourceNames. 我能够从 pod 中对 API 执行资源获取请求,但我无法创建资源,而是获取

$ kubectl logs rbac-test
Error from server (Forbidden): error when creating "/config/aaa.yaml": configmaps is forbidden: User "system:serviceaccount:default:rbac-test" cannot create resource "configmaps" in API group "" in the namespace "default"

如果我删除该resourceNames属性,我可以创建 configmap,但我不一定希望这个 pod 能够随意创建和更新 configmap。如何限制 serviceAccount 的角色,以便这个 pod 只能操作命名的 configmap aaa

编辑

我在 kubernetes slack 中得到了一些帮助(谢谢你,Alan)。RBAC 发生在 URL 级别,因此资源名称受限的授权不能用于创建 URL,因为 URL 中没有资源名称!

kind: Pod
apiVersion: v1
metadata:
  name: rbac-test
spec:
  restartPolicy: Never
  serviceAccountName: rbac-test
  imagePullSecrets:
    - name: docker-hub-creds 
  containers:
    - name: rbac-test
      image: bitnami/kubectl
      command: [ "kubectl" ]
      args: [ "apply", "-f", "/config/aaa.yaml" ]
      volumeMounts:
        - name: aaa-config
          mountPath: /config/
  volumes:
    - name: aaa-config
      configMap:
        name: aaa-config

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: aaa-config
data:
  aaa.yaml: |
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: aaa
    data:
      value: na

---
apiVersion: v1     
kind: ServiceAccount
metadata:
  name: rbac-test

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-test
rules:
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    verbs: [ "get", "create", "update" ]
    resourceNames: [ "aaa" ]

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

标签: kuberneteskubernetes-podkubernetes-rbac

解决方案


正如 Shai Katz 根据文档在之前的回答中提到的那样:使用 RBAC 授权 - 参考资源

您不能通过 限制createdeletecollection请求resourceName。对于 create,这个限制是因为在授权时对象名称是未知的。

编辑部分提供的解决方案 - 仍然不起作用。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-test
rules:
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    verbs: [ "get", "create", "update" ]
    resourceNames: [ "aaa" ]

此配置仅允许您获取和更新已命名的现有配置映射aaa,而创建操作毫无意义,因为无法创建此资源。

如何限制 serviceAccount 的角色,以便此 pod 只能操作命名的 configmap

如果您将编辑您的角色,您可以实现您想要的

解决方案 1

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-test
rules:
  - apiGroups: [ "" ]             #this rule will allow to update existing configmap aaa referenced by resourcename 
    resources: [ "configmaps" ]
    verbs: [ "get", "update" ]    
    resourceNames: [ "aaa" ]
  - apiGroups: [ "" ]             #this rule will allow you to create configmaps
    resources: [ "configmaps" ]
    verbs: [ "get", "create" ]   

可以通过执行以下命令来验证:

$ kubectl auth can-i update configmaps/aaa --as=system:serviceaccount:default:rbac-test
yes
$ kubectl auth can-i create configmaps/new-aaa --as=system:serviceaccount:default:rbac-test
yes

但是,在这种情况下rbac-test pod/sa可以update通过执行kubectl replace命令 fe 来执行操作:

$ kubectl replace -f /config/aaa.yaml

我你有兴趣$ kubectl apply可能你应该使用patch下面的例子中的动词。

  - apiGroups: [ "" ]       
    resources: [ "configmaps" ]
    verbs: [ "get", "patch" ]    
    resourceNames: [ "aaa" ]

解决方案 2 - 更严格的方法。

而不是授予您serviceAccount: rbac-test在 k8s api 中创建配置的权限。请考虑创建两个配置映射:

一个)

$ kubectl create cm aaa ### an empty "aaa" configmap

b)

kubectl apply -f - <<EOF
kind: ConfigMap
apiVersion: v1
metadata:
  name: aaa-config
data:
  aaa.yaml: |
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: aaa
    data:
      value: na
EOF

configmap将被填充到PODusing volumes中。Configmap.data将存储在pods目录下/config/aaa.yaml

kind: ConfigMap
apiVersion: v1
metadata:
  name: aaa
data:
  value: na

配置这个RBAC Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-test
rules:
  - apiGroups: [ "" ]             #this rule will allow to patch existing empty "aaa" configmap aaa referenced by resourcename 
    resources: [ "configmaps" ]
    verbs: [ "get", "patch" ]    
    resourceNames: [ "aaa" ]

在这种情况下,您将预先配置为aaaconfigmap,并且您pod的关联rbac-test serviceAccount将能够patch使用存储/config/aaa.yamlPod.

$ kubectl auth can-i patch configmaps/aaa --as=system:serviceaccount:default:rbac-test
yes
$ kubectl auth can-i create configmaps/new-aaa --as=system:serviceaccount:default:rbac-test
no

要检查哪些动词可以RBAC用于ConfigMap执行:

$ kubectl api-resources -o wide | grep configmap
configmaps                        cm                                          true         ConfigMap                        [create delete deletecollection get list patch update watch]

推荐阅读