It's a simple question, but I could not find a definite answer for it. Is it possible to create a namespace only if it doesn't exist. My objective is to create some service accounts without caring if their namespaces exist or not (if not, then they should be created on the fly).
The thing is I'm using CDK to deploy some basics K8S resources (including service accounts). To safely do this, I need to make sure the namespace (given in the service account manifest) already exists. However I'm not able to find any solution.
I tried patch
, but it seems to expect the resource to exist already (i.e. it fails with NotFound
error).
Two limitations:
a. I can't query to see if the namespace exists or not.
b. I can't use apply
since I don't have the exact definition of the namespace.
Is there any way to achieve this?
The “default” Namespace In most Kubernetes distributions, the cluster comes out of the box with a Namespace called “default.” In fact, there are actually three namespaces that Kubernetes ships with: default, kube-system (used for Kubernetes components), and kube-public (used for public resources).
i wouldn't go for any other solution except the following code snippet:
kubernetes 1.19 and above (included)
kubectl create namespace <add-namespace-here> --dry-run=client -o yaml | kubectl apply -f -
kubernetes 1.18 and below (included)
kubectl create namespace <add-namespace-here> --dry-run -o yaml | kubectl apply -f -
it creates a namespace in dry-run and outputs it as a yaml. The output will be passed as stdin to kubectl apply -f -
The last hyphen is important while passing kubectl to read from stdin.
Also see the examples in:
kubectl apply --help
Given the limitations I can only think of one way which is to apply a namespace yaml always before you apply the service account yaml. If the namespace exists already it will give you a message that namespace already exists
.You can ignore that message and move ahead.
apiVersion: v1
kind: Namespace
metadata:
name: test
So here we are being declarative and it does not matter what exists and what does not. You just define what the desired state should look like and kubernetes will take care of making sure that happens.
The options highlighted by @Panoptik and @Arghya Sadhu got me to use this one liner in a deployment pipeline:
echo -e "apiVersion: v1\nkind: Namespace\nmetadata:\n name: ${NS_NAME}" | kubectl
apply -f -
Why an one liner: I needed to avoid line breaks in the pipeline. The code was tested on Debian and also the official Google Cloud Build image "gcloud".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With