Search code examples
kubernetesk8s-serviceaccountk8s-rolebindingk8s-cluster-role

Deploy ServiceAccount, ClusterRole & ClusterRoleBinding failure


My NodeJS microservice is deployed to k8s cluster.

I would like this microservice to access the k8s API server. For that, I guess I need to create a ServiceAccount for it. So I did this:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-service-account
  namespace: myapp-ns

Then, I also created a ClusterRole to define the permissions:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: myapp-cluster-role
  namespace: myapp-ns
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

Finally, I created a ClusterRoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-app-role-binding
  namespace: myapp-ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: myapp-cluster-role
subjects:
  kind: ServiceAccount
  name: my-app-service-account

When I deploy them (I use Ansible to do the deployment), I get the following error:

"error": 400, "msg": "Failed to create object: b'{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"ClusterRoleBinding in version \\\\\"v1\\\\\" cannot be handled as a ClusterRoleBinding: json: cannot unmarshal object into Go struct field ClusterRoleBinding.subjects of type []v1.Subject\",\"reason\":\"BadRequest\",\"code\":400}\\n'",

Why this error? Where am I wrong?


Solution

  • I'd reckon the issue is with the resources, not with Ansible.

    Take a look:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: myapp-cluster-role
      namespace: myapp-ns # <-- NOT A NAMESPACED RESOURCE
    rules:
    - apiGroups: ["*"]
      resources: ["*"]
      verbs: ["*"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: my-app-role-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: myapp-cluster-role
    subjects:
    - kind: ServiceAccount # <-- Added (-)
      name: my-app-service-account
      namespace: myapp-ns # <-- MOVED FROM METADATA
    

    To summarize:

    • Clusterrole is a not a namespaced resource, hence you should not specify it
    • You've missed a - in the .subjects
    • You should move .namespace from .metadata to .suspects...

    More explanation on namespaced/non namespaced resources:

    • kubectl api-resources
    NAME                              SHORTNAMES   APIVERSION 
    roles                                          rbac.authorization.k8s.io/v1           true         Role
    clusterrolebindings                            rbac.authorization.k8s.io/v1           false        ClusterRoleBinding
    clusterroles                                   rbac.authorization.k8s.io/v1           false        ClusterRole
    rolebindings                                   rbac.authorization.k8s.io/v1           true         RoleBinding
    

    I encourage you to check on the following docs: