3
votes

I have 2 teams:

  • devs: they create a new Kubernetes namespace each time they deploy a branch/tag of their app
  • ops: they manage access control to the cluster with (cluster)roles and (cluster)rolebindings

The problem is that 'devs' cannot kubectl their namespaces until 'ops' have created RBAC resources. And 'devs' cannot create RBAC resources themselves as they don't have the list of subjects to put in the rolebinding resource (sharing the list is not an option).

I have read the official documentation about Admission webhooks but what I understood is that they only act on the resource that triggered the webhook.

Is there a native and/or simple way in Kubernetes to apply resources whenever a new namespace is created?

3
One thing that was not clear to me, are the roles always the same for the newly created namespaces?Will R.O.F.
Yes they are, only the rolebinding will potentially change (by adding/removing subjects).blakelead

3 Answers

5
votes

I've come up with a solution by writing a custom controller.

With the following custom resource deployed, the controller injects the role and rolebinding in namespaces matching dev-.* and fix-.*:

kind: NamespaceResourcesInjector
apiVersion: blakelead.com/v1alpha1
metadata:
  name: nri-test
spec:
  namespaces:
  - dev-.*
  - fix-.*
  resources:
  - |
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: dev-role
    rules:
      - apiGroups: [""]
        resources: ["pods","pods/portforward", "services", "deployments", "ingresses"]
        verbs: ["list", "get"]
      - apiGroups: [""]
        resources: ["pods/portforward"]
        verbs: ["create"]
      - apiGroups: [""]
        resources: ["namespaces"]
        verbs: ["list", "get"]
  - |
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: dev-rolebinding
    subjects:
    - kind: User
      name: dev
    roleRef:
      kind: Role
      name: dev-role
      apiGroup: rbac.authorization.k8s.io

The controller is still in early stages of development but I'm using it successfully in more and more clusters.

Here it is for those interested: https://github.com/blakelead/nsinjector

3
votes

Yes, there is a native way but not an out of the box feature.

You can do what you have described by using/creating an operator. Essentially extending Kubernetes APIs for your need.

As operator is just an open pattern which can implement things in many ways, in the scenario you gave one way the control flow could look like could be:

  1. Operator with privileges to create RBAC is deployed and subscribed to changes to a k8s namespace object kind
  2. Devs create namespace containing an agreed label
  3. Operator is notified about changes to the cluster
  4. Operator checks namespace validation (this can also be done by a separate admission webhook)
  5. Operator creates RBAC in the newly created namespace
  6. If RBACs are cluster wide, same operator can do the RBAC cleanup once namespace is deleted
1
votes

It's kind of related to how the user is authenticated to the cluster and how they get a kubeconfig file.You can put a group in the client certificate or the bearer token that kubectl uses from the kubeconfig. Ahead of time you can define a clusterrole having a clusterrolebinding to that group which gives them permission to certain verbs on certain resources(for example ability to create namespace)

Additionally you can use an admission webhook to validate if the user is supposed to be part of that group or not.