By Alwyn Botha, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Kubernetes namespaces are used to keep the work of different teams or projects separate. For example if you work in a company with 50+ other developers in 5 different teams, you do not want to see all the Kubernetes resources created by all those people all the time.

You want to see only the resources in your team — much shorter list of Pods, Deployments, and around 25 other Kubernetes resources. By the same logic you may want to set up your own mini environment where you see only the Kubernetes resources you work with. All the above can be done using Kubernetes namespaces.

Namespaces are easy to define, and once you switch to such a namespace all your work is automatically kept in that separate namespace — not visible to others on the same development server.

Minor note: The official documentation inconsistently refers to namespaces with upper or lower case first letter. I did the same throughout this tutorial; globally replacing it with lowercase will give your yaml syntax errors.

Default Kubernetes Namespaces

Get a list of current namespaces:

kubectl get namespaces
NAME STATUS AGE
default Active 11d
kube-public Active 11d
kube-system Active 11d

These three Namespaces are all automatically created during a new Kubernetes install.

Create Two Namespaces

We are now going to create two new namespaces so that we can create Kubernetes objects in it — to see how the separation works.

Create and read YAML file below to see how we create a development Namespace.

nano dev-namespace.yamlkind: Namespace
apiVersion: v1
metadata:
name: development
labels:
name: development

Create and read YAML file below to see how we create a tutorials Namespace.

nano tutorials-namespace.yamlkind: Namespace
apiVersion: v1
metadata:
name: tutorials
labels:
name: tutorials

Run kubectl create to create those two Namespaces.

kubectl create -f dev-namespace.yamlkubectl create -f tutorials-namespace.yaml

Get detail about just created Namespaces.

kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 11d <none>
development Active 3m48s name=development
kube-public Active 11d <none>
kube-system Active 11d <none>
tutorials Active 9s name=tutorials

Our 2 new objects are listed and ready for use.

Set-Context to Switch between Namespaces

In order to easily switch between Namespaces we use the concept of switching context.

Switching between Namespaces directly would have been quite straightforward to understand, but as it is Kubernetes decided to implement switching Namespaces only via switching contexts .

Let’s investigate our current context:

kubectl config viewapiVersion: v1
clusters:
- cluster:
certificate-authority: C:\Users\alwyn\.minikube\ca.crt
server: https://192.168.99.117:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: C:\Users\alwyn\.minikube\client.crt
client-key: C:\Users\alwyn\.minikube\client.key

Only one context available: minikube.

To see the current context we are working in, use:

kubectl config current-contextminikube

Let’s create contexts for our 2 Namespaces : development and tutorials.

kubectl config set-context development --namespace=development --cluster=minikube --user=minikubeContext "development" created.kubectl config set-context tutorials --namespace=tutorials --cluster=minikube --user=minikubeContext "tutorials" created.

To keep it simple the name of the context is equal to the Namespace name.

Let’s view config again:

kubectl config viewapiVersion: v1
clusters:
- cluster:
certificate-authority: C:\Users\alwyn\.minikube\ca.crt
server: https://192.168.99.117:8443
name: minikube
contexts:
- context:
cluster: minikukbe
namespace: development
user: minikube
name: dev

- context:
cluster: minikube
namespace: development
user: minikube
name: development
- context:
cluster: minikube
user: minikube
name: minikube
- context:
cluster: minikube
namespace: tutorials
user: minikube
name: tutorials
- context:
cluster: minikukbe
namespace: tutorials
user: minikube
name: tuts
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: C:\Users\alwyn\.minikube\client.crt
client-key: C:\Users\alwyn\.minikube\client.key

Easily readable we can see our contexts pointing to the correct Namespaces.

To get the current context, use:

kubectl config current-contextminikube

minikube is the default context. If you are not following these tutorials on a minikube installation your default context will probably have a different name.

Not a problem; the context your are in now is your default context.

Let’s create a Pod in this context to see how it is kept separate / hidden from other contexts.

nano myNamespacedPod-3.yamlapiVersion: v1
kind: Pod
metadata:
name: my-minikube-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The Pod is running ... now sleeping && sleep 3600']

IMPORTANT : Note that nowhere in that YAML spec do we specify a Namespace to create this Pod in.

Kubernetes objects are automatically created in the current context.

Create the Pod.

kubectl create -f myNamespacedPod-3.yaml 

pod/my-minikube-pod created

List all available / visible Pods:

kubectl get po 

NAME READY STATUS RESTARTS AGE
my-minikube-pod 1/1 Running 0 22s

Create Pod in Development Namespace

Let’s switch context to development and create a Pod there.

kubectl config use-context development Switched to context "development".

Create YAML file for the Pod.

nano myNamespacedPod-1.yamlapiVersion: v1
kind: Pod
metadata:
name: my-development-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The Pod is running ... now sleeping && sleep 3600']

Create the Pod.

kubectl create -f myNamespacedPod-1.yaml 

pod/my-development-pod created

List all available / visible Pods:

kubectl get poNAME                 READY   STATUS    RESTARTS   AGE
my-development-pod 1/1 Running 0 7s

Only this one Pod that I created in this Namespace is listed.

my-minikube-pod in default minikube Namespace / context not visible and not listed.

Create Pod in Tutorials Namespace

For experience let us create one Pod in our last context : tutorials .

Let’s switch context to tutorials and create a Pod there.

kubectl config use-context tutorials Switched to context "tutorials".

YAML source spec for our Pod.

nano myNamespacedPod-2.yamlapiVersion: v1
kind: Pod
metadata:
name: my-tutorials-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The Pod is running ... now sleeping && sleep 3600']

Create the Pod.

kubectl create -f myNamespacedPod-2.yaml 

pod/my-tutorials-pod created

List all available / visible Pods:

kubectl get poNAME                 READY   STATUS    RESTARTS   AGE
my-tutorials-pod 1/1 Running 0 7s

Only this one Pod that I created in this Namespace is listed.

my-minikube-pod and my-development-pod in other 2 Namespaces / contexts not visible and not listed.

Using Namespaces

To separate your Kubernetes resources just switch context and do your work there. Objects automatically created in your current context.

Let’s quickly investigate the resources visible in our Namespaces.

Each context only shows its single Pod.

kubectl config use-context tutorials
Switched to context "tutorials".
kubectl get poNAME READY STATUS RESTARTS AGE
my-tutorials-pod 1/1 Running 0 78s
kubectl config use-context developmentSwitched to context "development".kubectl get po
NAME READY STATUS RESTARTS AGE
my-development-pod 1/1 Running 0 2m48s
kubectl config use-context minikube
Switched to context "minikube".
kubectl get po
NAME READY STATUS RESTARTS AGE
my-minikube-pod 1/1 Running 0 10m

Kubectl api-resources in Namespaces

Not all Kubernetes resources are in a Namespace.

Get a list of Kubernetes API resources in a Namespace:

kubectl api-resources --namespaced=true

Expected output :

NAME                        SHORTNAMES   APIGROUP                    NAMESPACED   KIND
bindings true Binding
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
persistentvolumeclaims pvc true PersistentVolumeClaim
pods po true Pod
podtemplates true PodTemplate
replicationcontrollers rc true ReplicationController
resourcequotas quota true ResourceQuota
secrets true Secret
serviceaccounts sa true ServiceAccount
services svc true Service
controllerrevisions apps true ControllerRevision
daemonsets ds apps true DaemonSet
deployments deploy apps true Deployment
replicasets rs apps true ReplicaSet
statefulsets sts apps true StatefulSet
localsubjectaccessreviews authorization.k8s.io true LocalSubjectAccessReview
horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler
cronjobs cj batch true CronJob
jobs batch true Job
leases coordination.k8s.io true Lease
events ev events.k8s.io true Event
daemonsets ds extensions true DaemonSet
deployments deploy extensions true Deployment
ingresses ing extensions true Ingress
networkpolicies netpol extensions true NetworkPolicy
replicasets rs extensions true ReplicaSet
networkpolicies netpol networking.k8s.io true NetworkPolicy
poddisruptionbudgets pdb policy true PodDisruptionBudget
rolebindings rbac.authorization.k8s.io true RoleBinding
roles rbac.authorization.k8s.io true Role

Get a list of Kubernetes API resources not in a Namespace:

kubectl api-resources --namespaced=false

Expected output :

NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
componentstatuses cs false ComponentStatus
namespaces ns false Namespace
nodes no false Node
persistentvolumes pv false PersistentVolume
mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition
apiservices apiregistration.k8s.io false APIService
tokenreviews authentication.k8s.io false TokenReview
selfsubjectaccessreviews authorization.k8s.io false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io false SubjectAccessReview
certificatesigningrequests csr certificates.k8s.io false CertificateSigningRequest
podsecuritypolicies psp extensions false PodSecurityPolicy
podsecuritypolicies psp policy false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io false ClusterRole
priorityclasses pc scheduling.k8s.io false PriorityClass
storageclasses sc storage.k8s.io false StorageClass
volumeattachments storage.k8s.io false VolumeAttachment

Quick comments about some resources NOT in a Namespace :

We have seen throughout this tutorial that Pods ARE created in Namespaces.

Switch between the Namespaces and you will see the 2 commands below show the full list of nodes and Namespaces.

kubectl get nsNAME          STATUS   AGE
default Active 12d
development Active 16m
kube-public Active 12d
kube-system Active 12d
tutorials Active 16m
kubectl get noNAME STATUS ROLES AGE VERSION
minikube Ready master 12d v1.12.4

Namespaces Are Not a Secure Feature

As you have just seen I can easily create contexts and use it to switch Namespaces.

Also, Namespaces names are by default visible to everyone.

There is built-in functionality to show all resources while in ANY Namespace:

It is called adding the — all-namespaces=true flag.

kubectl get po --all-namespaces=trueNAMESPACE     NAME                                    READY   STATUS    RESTARTS   AGE
default my-minikube-pod 1/1 Running 2 134m
development my-development-pod 1/1 Running 2 126m
kube-system coredns-576cbf47c7-28l4x 1/1 Running 16 12d
kube-system coredns-576cbf47c7-6lh8g 1/1 Running 16 12d
kube-system etcd-minikube 1/1 Running 8 7d19h
kube-system kube-addon-manager-minikube 1/1 Running 17 12d
kube-system kube-apiserver-minikube 1/1 Running 0 3h48m
kube-system kube-controller-manager-minikube 1/1 Running 0 3h48m
kube-system kube-proxy-dh4vs 1/1 Running 0 3h47m
kube-system kube-scheduler-minikube 1/1 Running 17 12d
kube-system kubernetes-dashboard-5bff5f8fb8-h25d5 1/1 Running 48 12d
kube-system storage-provisioner 1/1 Running 48 12d
tutorials my-tutorials-pod 1/1 Running 2 125m

That list is a bit messy, let us exclude kube-system Pods.

kubectl get po --all-namespaces=true | grep -v systemNAMESPACE     NAME                                    READY   STATUS    RESTARTS   AGE
default my-minikube-pod 1/1 Running 2 136m
development my-development-pod 1/1 Running 2 128m
tutorials my-tutorials-pod 1/1 Running 2 127m

All Pods created in this tutorial show — across 3 Namespaces.

Out of the box Namespaces are a convenience feature.

You have to use the Kubernetes Authorization Plugin to properly secure each Namespaces in isolation.

Kubernetes Authorization Plugins controls not just Namespaces. It also enables fine-grained-access control for specific containers, other Kubernetes objects and general Kubernetes administrator operations.

Clean Up

Our previous command showed we have 3 Pods running.

Let us now delete it.

Note each delete command will take 30 seconds since I did not force delete it immediately using — force — grace-period=0 on the delete command.

kubectl config use-context minikubekubectl delete pod/my-minikube-podkubectl config use-context development kubectl delete pod/my-development-podkubectl config use-context tutorials  kubectl delete pod/my-tutorials-pod

Important : switch to default context: minikube

kubectl config use-context minikube

Otherwise you will delete the context you are currently switched to:

kubectl config delete-context development
kubectl config delete-context tutorials
kubectl delete namespaces development
kubectl delete namespaces tutorials

Reference:https://www.alibabacloud.com/blog/kubernetes-namespaces_594726?spm=a2c41.12820927.0.0

Written by

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store