Kustomize: namespace set in an overlay’s kustomization.yaml does not override the namespace for the subjects of a cluster role binding

Created on 25 Jun 2018  ·  11Comments  ·  Source: kubernetes-sigs/kustomize

I have the following cluster role binding in my base/worker/crb.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: worker-crb
subjects:
- kind: ServiceAccount
  name: worker
  namespace: default
roleRef:
  kind: ClusterRole
  name: worker-cr
  apiGroup: rbac.authorization.k8s.io

I have the following kustomization.yaml in an overlay called test

bases: 
- ../base/postgres
- ../base/queuer
- ../base/rabbitmq
- ../base/worker
patches: 
- ./worker/deployment.yaml
- ./rabbitmq/statefulset.yaml
namespace: test

The issue is, when I run kustomize build test I do not get a cluster role binding with an augmented namespace despite it being in the list of bases. My current solution is to lock each overlay to a namespace. One might also separate cluster roles and bindings from apps so that the different namespaces you might want to deploy to have the relevant cluster roles and bindings, but it is still true that the namespace var in the kustomization.yaml does not get applied to the subjects of the cluster role binding.

help wanted

Most helpful comment

The fix is to improve the namespace transformers. Currently ClusterRoleBinding is skipped. We need to add the path config subjects.namespace for ClusterRoleBinding.

All 11 comments

@sethpollack Can you take a look at this issue? In current kustomize codebase, ClusterRoleBining and ClusterRole are skipped in namespace transformer.

Yes, because they are cluster level objects and don't get a namespace.

Yes but the subjects of a cluster role binding requires a namespace field.

Yes, but I'm not sure that it is a given that they should be set to the namespace from the kustomization file. If it was, then it would probably make more sense as a Role/RoleBinding.

@Liujingfang1 thoughts?

That's a good point.
Maybe sharing my use case will help. I have a service that is responsible for creating namespaces for each user of the service. The user-specific namespace have resource limits etc.

For a service in namespace default to be able to create other namepsaces requires a cluster role binding (unless I'm just been horribly wrong about this the whole time).

@gaigepr I'm not quite familiar with RBAC, trying to understand your usage. Is the kustomization.yaml for the service you mentioned? What do you intend to do by

subjects:
- kind: ServiceAccount
  name: worker
  namespace: default

If you want to limit it one namespace, you can use RoleBinding instead of ClusterRoleBinding. In RoleBinding, you can also refer a ClusterRole.

At the same time, can you also take a look at kubernetes RBAC doc?

I have confirmed that for a service account to be able to conduct crud operations on namespaces, a cluster role binding must bind a cluster role to that service account with the relevant permission on namespaces.

From the docs:

Role and ClusterRole
In the RBAC API, a role contains rules that represent a set of permissions. Permissions are purely additive (there are no “deny” rules). A role can be defined within a namespace with a Role, or cluster-wide with a ClusterRole.
A Role can only be used to grant access to resources within a single namespace. Here’s an example Role in the “default” namespace that can be used to grant read access to pods[...]

Since my use case requires the service account to have access to resources (jobs and namespaces) in many namespaces, a cluster role and cluster role binding are required. I hope this explanation helps clarify what I am trying to do. If not I can explain in more detail.

The root of my problem is, for each overlay that has cluster role bindings, I must set the namespace in the kustomization.yaml file AND in each of the cluster role bindings. This isn't unusable but I wonder if somehow this can be made better.

I've got a similar use case (deploying a CRD controller that will own resources in multiple namespaces).
Granted, this could be simplified by requiring the user to install my controller into a hardcoded namespace.

My attempt at a workaround was to define a variable:

# kustomization.yaml
vars:
- name: SERVICEACCOUNT_NAMESPACE
  objref:
    kind: ServiceAccount
    name: my-crd
    apiVersion: v1
  fieldref:
    fieldpath: metadata.namespace
# clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-crd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: my-crd
  namespace: $(SERVICEACCOUNT_NAMESPACE)

Unfortunately, it seems that this variable does not get interpolated because NewRefVarTransformer doesn't include a PathConfig for ClusterRoleBinding.

The fix is to improve the namespace transformers. Currently ClusterRoleBinding is skipped. We need to add the path config subjects.namespace for ClusterRoleBinding.

Was this page helpful?
0 / 5 - 0 ratings