Deep Dive into Kubernetes Namespaces
Kubernetes Namespaces provide a mechanism for isolating groups of resources within a single cluster. In this hands-on exercise, we’ll explore Namespaces in depth by creating multiple Kubernetes resources and examining how they interact across namespace boundaries.
What are Kubernetes Namespaces?
Namespaces in Kubernetes serve several important purposes:
- Provide isolation of resources
- Help avoid accidental deletion or modification of resources
- Allow separation of resources by type, environment, domain, etc.
- Enable resources to access each other within the same namespace using their first name, while requiring fully qualified domain names (FQDNs) for cross-namespace communication
Let’s dive into our hands-on exercise to see these concepts in action.
Hands-on Exercise
Step 1: Create Namespaces
First, let’s create two namespaces:
kubectl create namespace ns1
kubectl create namespace ns2
Step 2: Create Deployments
Now, let’s create a deployment in each namespace:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-ns1
namespace: ns1
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ns1
template:
metadata:
labels:
app: nginx-ns1
spec:
containers:
- name: nginx
image: nginx
Save this as deploy-ns1.yaml
and create a similar file for ns2
. Then apply both:
kubectl apply -f deploy-ns1.yaml
kubectl apply -f deploy-ns2.yaml
Step 3: Get Pod IP Addresses
Retrieve the IP addresses of the pods:
kubectl get pods -n ns1 -o wide
kubectl get pods -n ns2 -o wide
Step 4: Test Pod-to-Pod Communication
Exec into the pod in ns1
and curl the pod in ns2
:
kubectl exec -it -n ns1 $(kubectl get pod -n ns1 -o jsonpath='{.items[0].metadata.name}') -- /bin/bash
curl <IP-of-pod-in-ns2>
This should return the nginx welcome page.
Step 5: Scale Deployments
Scale both deployments to 3 replicas:
kubectl scale deployment -n ns1 deploy-ns1 --replicas=3
kubectl scale deployment -n ns2 deploy-ns2 --replicas=3
Step 6: Create Services
Create services to expose the deployments:
apiVersion: v1
kind: Service
metadata:
name: svc-ns1
namespace: ns1
spec:
selector:
app: nginx-ns1
ports:
- protocol: TCP
port: 80
targetPort: 80
Create a similar file for ns2
and apply both:
kubectl apply -f svc-ns1.yaml
kubectl apply -f svc-ns2.yaml
Step 7: Test Pod-to-Service Communication
Exec into a pod in ns1
and curl the service in ns2
:
kubectl exec -it -n ns1 $(kubectl get pod -n ns1 -o jsonpath='{.items[0].metadata.name}') -- /bin/bash
curl <IP-of-svc-in-ns2>
This should work and return the nginx welcome page.
Step 8: Test Service Name Resolution
Try to curl the service using just its name:
curl svc-ns2
This will fail with a name resolution error.
Step 9: Test FQDN Service Name Resolution
Now, try using the Fully Qualified Domain Name (FQDN) of the service:
curl svc-ns2.ns2.svc.cluster.local
This should work and return the nginx welcome page.
Step 10: Clean Up
Delete both namespaces to clean up all resources:
kubectl delete namespace ns1
kubectl delete namespace ns2
Key Takeaways
- Namespace Isolation: Namespaces provide a level of isolation between resources.
- Cross-Namespace Communication: Pods can communicate across namespaces using IP addresses or FQDNs.
- DNS Resolution: Within a namespace, services can be reached by their short names. Across namespaces, FQDNs are required.
- Resource Management: Deleting a namespace removes all resources within it, simplifying cleanup.
Conclusion
Kubernetes Namespaces are a powerful feature for organizing and isolating resources within a cluster. They provide a way to divide cluster resources between multiple users and are essential for multi-tenant environments. Understanding how to work with and communicate across namespaces is crucial for effective Kubernetes management and application design.