In this section, we will look briefly at the option to use a single cluster to host systems for multiple users or multiple user communities. The idea is that those users are totally isolated and may not even be aware that they share the cluster with other users. Each user community will have its own resources, and there will be no communication between them (except maybe through public endpoints). The Kubernetes namespace concept is the ultimate expression of this idea.
Why should you run a single cluster for multiple isolated users or deployments? Isn't it simpler to just have a dedicated cluster for each user? There are two main reasons: cost and operational complexity. If you have many relatively small deployments and you want to create a dedicated cluster to each one, then you'll have a separate master node and possibly a three-node etcd
cluster for each one. That can add up. Operational complexity is very important too. Managing tens or hundreds or thousands of independent clusters is no picnic. Every upgrade and every patch needs to be applied to each cluster. Operations might fail and you'll have to manage a fleet of clusters where some of them are in slightly different state than the others. Meta-operations across all clusters may be more difficult. You'll have to aggregate and write your tools to perform operations and collect data from all clusters.
Let's look at some use cases and requirements for multiple isolated communities or deployments:
Kubernetes namespaces are the perfect answer to safe multi-tenant clusters. This is not a surprise as this was one of the design goals of namespaces.
You can easily create namespaces in addition to the built-in kube-system and default. Here is a YAML file that will create a new namespace called custom-namespace. All it has is a metadata item called name
. It doesn't get any simpler:
apiVersion: v1 kind: Namespace metadata: name: custom-namespace
Let's create the namespace:
> Kubectl create -f custom-namespace.yaml namespace "custom-namespace" created > kubectl get namesapces NAME STATUS AGE custom-namespace Active 39s default Active 32d kube-system Active 32d
The status field can be active or terminating. When you delete a namespace, it will get into the terminating state. When the namespace is in this state you will not be able to create new resources in this namespace. This simplifies the clean-up of namespace resources and ensures the namespace is really deleted. Without it, the replication controller might create new pods when existing pods are deleted.
To work with a namespace, you add the --namespace
argument to kubectl
commands:
> kubectl create -f some-pod.yaml --namespace=custom-namespace pod "some-pod" created
Listing pods in the custom-namespace returns only the pod we just created:
> kubectl get pods --namespace=custom-namespace NAME READY STATUS RESTARTS AGE some-pod 1/1 Running 0 6m
Listing pods without the namespace returns the pods in the default namespace:
> Kubectl get pods NAME READY STATUS RESTARTS AGE echo-3580479493-n66n4 1/1 Running 16 32d leader-elector-191609294-lt95t 1/1 Running 4 9d leader-elector-191609294-m6fb6 1/1 Running 4 9d leader-elector-191609294-piu8p 1/1 Running 4 9d pod-with-secret 1/1 Running 1 1h
Namespaces are great, but they can add some friction. When you use just the default namespace, you can simply omit the namespace. When using multiple namespaces, you must qualify everything with the namespace. This can add some burden, but doesn't present any danger. However, if some users (for example, cluster administrators) can access multiple namespaces, then you're open to accidentally modifying or querying the wrong namespace. The best way to avoid this situation is to hermetically seal the namespace and require different users and credentials for each namespace.
Also, tools that help make clear what namespace you're operating on (for example, shell prompt if working from commandline or listing the namespace prominently in a web interface).
Make sure that users that can operate on a dedicated namespace don't have access to the default namespace. Otherwise, every time they forget to specify a namespace, they'll operate quietly on the default namespace.