MicroK8s - Use multiple namespaces and contexts

Kubernetes is a powerful tool to host and orchestrate containerized backend solutions for production. What about our staging environments? Or small other apps we need to host somewhere? 🤔

In this article, I’ll use kubernetes namespaces and contexts to host multiple projects on the same kubernetes cluster.

Namespaces

Namespaces allow me to work on my current project and hide the other deployments. In a single namespace, you can’t have two resources with the same name, names have to be unique. But it’s allowed to have two resources with the same name, one on each namespace (for instance, the “web-api” service). It’s pretty handy. 🖐

Create a new namespace

1
kubectl create namespace my-namespace-name

Use a namespace in a command

1
kubectl -n my-namespace-name .....

Now that we know how to use namespaces for basic commands. Let’s use a context.

Contexts

For namespaces, kubernetes contexts are awesome. They allow us to set a current-context that includes a namespace we want to work on, so we can get rid of the -n my-namespace-name option after the kubectl command.

1
kubectl config current-context

Create a new context tied to a namespace

1
2
# kubesys is the new context name
kubectl config set-context kubesys --namespace=kube-system --user admin --cluster=microk8s-cluster

Switch to a specific context

1
kubectl config use-context kubesys

Ingress and multi-namespaces

My own use case of namespaces and contexts is to work on multiple projects, for example two websites. In an other article, I explained how to route your URLs/domains to multiple services. Basically, we need one ingress definition file, which will tell the ingress controller how to handle the routes.

It might depend on the cloud provider, but on a microk8s cluster, you can use the included ingress controller with multiple namespaces. All you need is a single ingress definition file for each namespace. The ingress controller will automatically merge them and route the incoming requests to the requested services.

Following is an example for two ingress files, for two namespaces/domains/projects. I noticed that it doesn’t seem to work if I try to use two namespaces with only one domain, though.

First ingress (with its own namespace)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: default-ingress
namespace: my-first-project # SET THE NAMESPACE HERE (or set it with the command line or context)
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- my-first-project.com
secretName: default-tls-secret
rules:
- host: my-first-project.com
http:
paths:
- path: /
backend:
serviceName: hello-deployment
servicePort: 80
Second ingress (with its own namespace)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: default-ingress
namespace: my-second-project # SET THE NAMESPACE HERE (or set it with the command line or context)
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- my-second-project.com
secretName: default-tls-secret
rules:
- host: my-second-project.com
http:
paths:
- path: /
backend:
serviceName: hello-deployment
servicePort: 80