In the fast-paced world of container orchestration, managing resources efficiently and securely is essential. Kubernetes, the leading container orchestration platform, offers a powerful tool for this: namespaces. Whether you are managing a multi-tenant environment or organizing your microservices, understanding namespaces is key to maintaining an efficient and scalable Kubernetes environment. In this blog, we will delve into what namespaces are, why they are essential, and how you can leverage them to streamline your Kubernetes operations. Let's get started
What are Namespaces?
Namespaces in Kubernetes are a way to divide cluster resources between multiple users. They are intended for use in environments with many users spread across multiple teams or projects, providing a scope for names. They help in organizing and managing resources within a cluster, especially when there are many objects, such as pods, services, and deployments.
Here are some key points about namespaces:
Isolation: Namespaces provide a mechanism for isolating groups of resources within a single cluster. This helps in preventing conflicts and ensuring that resources do not interfere with each other.
Resource Quotas: Namespaces allow you to apply resource quotas, which can limit the number of resources (like CPU and memory) that can be used within a namespace. This ensures fair resource distribution and prevents any single team or project from monopolizing cluster resources.
Access Control: Namespaces work with Kubernetes' Role-Based Access Control (RBAC) to define fine-grained access control policies. You can grant or restrict permissions for specific namespaces, providing better security and control over who can do what within each namespace.
Environment Segregation: Different environments (such as development, staging, and production) can be managed within the same cluster using namespaces. This makes it easier to segregate and manage resources based on their environment.
Default Namespace: Kubernetes provides a default namespace called
default
. If no namespace is specified, Kubernetes objects are created in thedefault
namespace.Special Namespaces:
kube-system: This namespace is used for system components managed by Kubernetes, such as the Kubernetes API server, scheduler, and controller manager.
kube-public: This namespace is readable by all users (including those not authenticated). It is reserved for cluster usage, in case some resources should be visible and readable publicly throughout the whole cluster.
kube-node-lease: This namespace holds lease objects associated with each node. These objects are used for node heartbeats, and the associated namespace helps improve the performance of the node heartbeats.
Until my previous blogs in this CKA series, we created many resources like pods, deployments, and ReplicaSets, all in the default namespace of Kubernetes.
Working with Namespaces
- Viewing Namespaces:
kubectl get namespaces
# or
kubectl get ns
Creating a Namespace:
You can create a namespace both declaratively and imperatively.
Declaratively: Create a
ns.yaml
file with the following content:
apiVersion: v1
kind: Namespace
metadata:
name: demo
Imperatively:
kubectl create ns demo
- Getting Namespace Details:
kubectl get all -n <name-of-namespace> #or
kubectl get all --namespace <name-of-namespace>
- Deleting a Namespace:
kubectl delete ns <namespace-name>
Interaction Between Namespaces
To illustrate how different namespaces interact within a cluster, we'll create two namespaces: default
and demo
.
- Create the
demo
Namespace:
kubectl create ns demo
- Deploy Nginx in the
demo
Namespace:
kubectl create deploy nginx-deploy --image=nginx -n demo
- Deploy Nginx in the
default
Namespace:
kubectl create deploy nginx-test --image=nginx
Now we have two deployments: nginx-deploy
in the demo
namespace and nginx-test
in the default
namespace. To test the interaction, follow these steps:
- Get the IPs of the Pods:
kubectl get pods -n <namespace-name> -o wide
Access Pods from Different Namespaces:
Exec into the
nginx-deploy
pod:kubectl exec -it <nginx-deploy-pod-name> -n demo -- sh
Curl the IP of the
nginx-test
pod:curl <nginx-test-pod-ip>
- Similarly, exec into the
nginx-test
pod and curl the IP of thenginx-deploy
pod.
use exit
to exit from the pod or press Ctrl+d
Scale Deployments:
Scale the replicas to 3 in both deployment nginx-deploy and nginx-test.
kubectl scale --replicas=3 deploy/<deploy-name> -n <namespace-name>
- Expose Deployments as Services:
kubectl expose deploy/<deployment-name> --name=<service-name> --port 80 -n <namespace-name>
- Access Services:
Now, exec into each pod and try to curl the IP address of the service running in the other namespace; for example, exec into the nginx-deploy
pod in the demo
namespace and curl the IP of the svc-test
service in the default
namespace to access the application.
Similarly, exec into the nginx-test
pod in the default
namespace and curl the IP of the svc-demo
service in the demo
namespace to access the application.
Note: For better understanding, refer to my images, see the commands, and then use them on your machine.
Now, try curling the service name instead of the IP, and you will notice an error indicating that the host cannot be resolved.
A similar error will occur when we curl svc-test
in the nginx-deploy
pod.
Now use the Fully Qualified Domain Name (FQDN) of the service and try curling again; this should work.
To find the FQDN, exec into your pod and use the cat /etc/resolv.conf
command.
Now, exec into nginx-deploy
and curl the FQDN of nginx-test
, and it works.
Similarly, exec into nginx-test
and curl the FQDN of nginx-deploy
, and it works.
Conclusion
To access pods and services in different namespaces, we can use their IPs or Fully Qualified Domain Names (FQDN), but not their hostnames.
Thank you for reading my blog; for better understanding, please try the tasks above on your local machine.
For understanding Kubernetes, please go through my Kubernetes blog series.
Important commands
Create a temporary Pod using the
busybox
image:kubectl run busybox --rm -it --image=busybox -- /bin/sh
You have noticed while writing commands, I am not using
kubectl
as a whole word, other side I am just writing likek get pods
. This is because I have given an alias name to the kubectl. If you want to set this alias name in your system also, follow the steps:Go to your home directory and list all hidden files
ls -a
You will observe a file name with
.bash_profile
.Open the file in editor mode
vi .bash_profile
and type this command:
alias 'k=kubectl'
After that save and exit through
Esc → :wq!
Then restart the server and see the magic!!!