JDev
JDev

Reputation: 2541

Kubectl apply "all in one deployment" - replace ClusterRoleBinding subject namespace?

I want to create all-in-one.yaml kubernetes installer. But ran into the following error.

If I create ClusterRoleBinding, then subject.namespace is a required field. But during a kubectl apply, it is not replaced by a given namespace.

kubectl apply -f all-in-one.yaml --namespace=infra

Her is ClusterRoleBinding from all-in-one.yaml

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

Is this a bug or should it be? Accordingly, the installation does not work correctly, because the ClusterRoleBinding does not bound with correct ServiceAccount. How can i solve this problem?

If i remove namespace from subject then I get an error.

The ClusterRoleBinding "my-crb" is invalid: subjects[0].namespace: Required value

The only thing I can do is create ClusterRoleBinding separately from the all-in-one installation, then it works as it should.

kubectl create clusterrolebinding my-crb --clusterrole=my-cr --serviceaccount=infra:my-sa

Thanks for the tips.

Upvotes: 1

Views: 629

Answers (1)

David Maze
David Maze

Reputation: 158847

It's not a bug. When kubectl apply creates or updates objects, --namespace sets the namespace those objects are in, but it doesn't try to otherwise affect or modify object contents.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-sa
  # namespace: infra  # <-- kubectl --namespace affects this only

A templating tool like Helm can help here. Helm lets you substitute parts of the YAML specification with variables or expressions, and it knows at install time what namespace it's installing into. So in Helm you could say

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ template "my.name" . }}-crb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ template "my.name" . }}-cr
subjects:
  - kind: ServiceAccount
    name: {{ template "my.name" . }}-sa
    namespace: {{ .Release.Namespace }}

The last line substitutes the installation namespace in the CRB; I've also called a helper template to make the names of these various objects dynamic, so your application can be installed multiple times. (helm create supplies a template chart that includes this helper for you.)

Upvotes: 1

Related Questions