kustomize-controller
kustomize-controller copied to clipboard
targetNamespace should create the namespace if not exists
Currently there is a gap between kustomize and helm. Helm creates the namespaces itself on creation. Kustomize is not doing this.
I would love to see that as feature in flux/kustomize
The helm-controller is capable of doing this because it is a Helm feature. Which comes with limitations, as on uninstall the namespace will not be garbage collected.
Given this, I do not think the kustomize-controller will support this feature.
but the flux kustomize could handle that? is this the wrong place than :(
Also this leads into several issues, if the kustomize exists inside a custom namespace, but this needs to be created by another kustomize out of flux-system.
for example:
gotk-sync.yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
secretRef:
name: flux-system
url: https://github.com/
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 5m0s
path: ./clusters/pt-dev
prune: true
sourceRef:
kind: GitRepository
name: flux-system
inside: clusters/pt-dev/playground component.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: example-nginx
spec:
interval: 5m0s
path: ./deployment/k8s/dev
prune: true
force: true
sourceRef:
kind: GitRepository
name: example-nginx
----- kustomize.yaml
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: playground
resources:
- component.yaml
this deployment will not work because the namepsace playground needs to be created before in another yaml inside of flux-system to handle the namespace. That would separate component stuff, that should belong together :(
inside: clusters/pt-dev/playground component.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: example-nginx
spec:
targetNamespace: playground # <- creates namespace if not exists
interval: 5m0s
path: ./deployment/k8s/dev
prune: true
force: true
sourceRef:
kind: GitRepository
name: example-nginx
----- kustomize.yaml
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- component.yaml
The kustomize-controller can handle the creation of the namespace (and garbage collection of it) fine, by simply declaring the namespace object in a Kustomization. Whatever other Kustomization then depends on the existence of this namespace, can hierarchically depend on this being applied first using dependsOn
: https://fluxcd.io/docs/components/kustomize/kustomization/#kustomization-dependencies.
This would split a component into two separate kustomize.toolkit.fluxcd.io/v1beta2 inside of two different namespaces.
This isn't that and a strange dependency :(.
Also, both kustomize.toolkit.fluxcd.io/v1beta2 belong to the flux-system ks and that would lead to a deployment failure when bootstrapping a new environment because one of the ks is not valid due to the fact that the namespace is missing.
This would split a component into two separate kustomize.toolkit.fluxcd.io/v1beta2 inside of two different namespaces
I don't understand this limitation you described. It doesn't limit that way, because the Kustomize controller understands namespaced and non-namespaced resources and the order they should apply. If you create a Namespace inside of a Flux Kustomization, the controller reconciler does the apply in steps: first any Namespaces (and any other Non-Namespaced resources, like CRDs) are created, and second after that any Namespaced Resources and Custom Resources are created.
This is done in steps but in a single transaction via Server-Side Apply, so you should never hit an issue where Kustomize Controller fails to create a resource in the namespace because that namespace had not been declared "upstream." They can be declared in the same Flux Kustomization.
Please reach out if there's some reason this still doesn't meet your needs. I am pretty sure this can be closed.
just use my example and you will see that flux stop working because the namespace playground does not exists.
It's a chicken egg issue, putting a kustomization (flux) inside a namespace this ks reconcilation does not work, because flux can't put a flux kustomization into a namespace that does not exist. To solve this, I need to create another kustomization (flux) to create and handle namespaces, which is part of flux-system. Disaster recovery is not possible or onboarding a new cluster.
There are two steps to implementing a new service inside a new namespace.
Your example simply seems to be missing the Namespace definition:
apiVersion: v1
kind: Namespace
metadata:
name: playground
If you add this definition within the Flux Kustomization or adjacent to the Flux Kustomization, assuming nothing else is different from what you've shown here, I am certain that it will work.
I haven't understood clearly what reason you don't want to define the Namespace directly in either one of those places, but unless you have locked down your cluster for Flux's multi-tenancy, there should be nothing stopping you from creating Namespaces where they are needed.
The Flux Kustomization's targetNamespace
directive will even do you the extra solid of overwriting the name
field on the Namespace
definition above, if it's defined inside of the path at the target as some Namespace with any different name. A good example of an overlay which defines its own namespace is in Podinfo, here is the production
overlay, which pulls in different services from bases, and joins them together in a Namespace that's defined there, within the overlay.
https://github.com/stefanprodan/podinfo/blob/master/deploy/overlays/production/kustomization.yaml
This is the expected pattern, if you have a different approach that didn't work, and you don't understand why, the best way to provide reproduction is with a public repository. Copying and pasting manifests from your partial description inside of a thread is not the ideal way to help you debug your issue.
It is also suggested to start Q&A threads on the fluxcd/flux2 Discussions Q&A label.
Feature requests can go there, Proposals are preferred to feature requests, and PRs generally follow after Proposals turn into RFCs, as we like to help folks implement their own "scratch their own itch."
But these proposals must be thought-out and designed, and given to the community with enough space for feedback and understanding the impact. Flux project does try not to make any fast moves outside of planned roadmap issues and other important fixes we encountered on our way to GA.
Please take a look at the example that I linked, and I hope that it helps unblock you. I do not think there's any strong compelling argument or reason to add targetNamespace
here, it's not compelling to do so just because Helm Controller has this feature. There is no namespace chicken and egg issue for Kustomize controller by itself that I can observe.
Lets try an example:
clusters/dev/flux-system # default flux-system stuff defining the GitRepo to reconcile
---
# clusters/dev/example, inside this git repo
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: example-nginx
spec:
targetNamespace: playground
interval: 5m0s
path: ./k8s/dev
prune: true
force: true
sourceRef:
kind: GitRepository
name: example-nginx
This simple flux example does not work, because the targetNamespace: playground does not exist.
This means I need to create it first with another flux kustomization that is part of flux-system or if created the default namespace. I could also create the namespace inside the main git where everything is stored but this would mix up deployment information and deployments. And the namespace would not be properly versioned anymore.
The flux-system reconciliation stops completely. I hope that helps.
I could also create the namespace inside the main git where everything is stored but this would mix up deployment information and deployments.
IMO namespaces are not part of an app deployment, being cluster wide objects, these should be managed by a Flux Kustomization that's own by cluster admins. The recommended setup, is where the namespaces and the app Flux Kustomizations are placed together in the same dir and applied by the flux-system
root Kustomization.
Please see the example repos:
- https://github.com/fluxcd/flux2-kustomize-helm-example
- https://github.com/fluxcd/flux2-multi-tenancy
that's own by cluster admins.
That is exactly what we don't want. :( Giving developers two kustomizations in hand one "only for namespaces" and the other for the service deployment feels wrong.
And helm solves this issue. That's why I reported this.
@saltyblu If the Flux Kustomization can create namespaces on-demand then it has cluster admin rights. Adding a flag to create namespaces wouldn't solve this, the Flux Kustomization still needs a service account attached to it, either one with the capability to create namespaces or one without it.
If we added the flag to createNamespace to the Flux Kustomization, then we would need more code to solve the problem that you described here, because the Flux Kustomization can either create cluster resources or it cannot. This goes similar for resources that are named and described for creation by the user, with manifests inside the path from the source. There is only one Service Account for each Flux Kustomization.
For rigorous multi-tenancy, you need separate Flux kustomizations and some of them should be isolated within a namespace. That namespace has to be created externally, even if you assign a namespaced cluster-admin so the user has full control within the namespace, the scopes in RBAC are designed so that the damage a user can do is constrained to at most "delete the namespace that I am in, and all of its contents." *Notably this does not include the create namespace perm.
Those Helm releases with createNamespace
are also in a position to create cluster-wide resources. They are not separated from the cluster-admin permission if they can create namespaces. If you want rigorous multi-tenancy then you must follow the hardening guide and steps in flux2-multi-tenancy. It's not something that createNamespace
is in position to offer in the way that you expect here.
The developers wouldn't be managing the Kustomization with namespaces in it. They are assigned a namespace by the cluster admin (a platform team, or someone who should have admin rights on the cluster), and the developers' access should generally be limited to only service accounts which do not have permission to write cluster scoped objects.
Okay thanks got the point. I guess.