Working with Namespaces and Services in Kubernetes
Table of contents
- What are Namespaces and Services in k8s:
- Services in Kubernetes
- Task 1:
- Load Balancing, and Networking in Kubernetes:
- Networking in Kubernetes
- Working with Services in Kubernetes:
- Task-1:
- Create a Service for your todo-app Deployment
- Create a Service definition for your todo-app Deployment in a YAML file.
- Apply the Service definition to your K8s (minikube) cluster using the kubectl apply -f service.yml -n <namespace-name> command.
- Verify that the Service is working by accessing the todo-app using the Service's IP and Port in your Namespace.
- Step 1: Create the service.yml file
- Step 2: Apply the Service definition
- Step 3: Get Service Details
- Step 4: Access the Todo-App
- Task-2:
- Create a ClusterIP Service for accessing the todo-app from within the cluster
- Create a ClusterIP Service definition for your todo-app Deployment in a YAML file.
- Apply the ClusterIP Service definition to your K8s (minikube) cluster using the kubectl apply -f cluster-ip-service.yml -n <namespace-name> command.
- You can verify that the ClusterIP Service is working by accessing the to-do app from another Pod in the cluster in your Namespace.
- Step 1: Create cluster-ip-service.yml
- Step 2: Apply the ClusterIP Service Definition
- Step 3: Verify the Service
- Step 4: Access the Todo-App from Another Pod
- Task-3:
- Create a LoadBalancer Service for accessing the todo-app from outside the cluster
- Create a LoadBalancer Service definition for your todo-app Deployment in a YAML file.
- Apply the LoadBalancer Service definition to your K8s (minikube) cluster using the kubectl apply -f load-balancer-service.yml -n <namespace-name> command.
- Verify that the LoadBalancer Service is working by accessing the todo-app from outside the cluster in your Namespace.
- Step 1: Create load-balancer-service.yml
- Step 2: Apply the LoadBalancer Service Definition
- Step 3: Verify the Service
- Step 4: Access the Todo-App from Outside the Cluster
- Alternative (Using Port Forwarding if LoadBalancer Doesn't Work in Minikube)
What are Namespaces and Services in k8s:
Namespaces in Kubernetes
Namespaces in Kubernetes logically separate resources within a cluster. They help organize workloads, especially in large environments where multiple teams or projects share the same cluster.
Key Features of Namespaces:
Logical Isolation: Separate resources for different teams, applications, or environments (e.g.,
dev
,staging
,prod
).Resource Quotas: Define CPU, memory, and storage limits for different namespaces.
Scoped Access Control: Apply Role-Based Access Control (RBAC) to limit access within specific namespaces.
Unique Naming within a Namespace: Resources like pods, services, and deployments must have unique names only within their namespace, allowing duplication across different namespaces.
Common Namespace Commands:
List all namespaces
kubectl get namespaces
Create a new namespace
kubectl create namespace my-namespace
Delete a namespace
kubectl delete namespace my-namespace
Run commands in a specific namespace
kubectl get pods -n my-namespace
By default, Kubernetes includes namespaces like:
default
: Where resources are created if no namespace is specified.kube-system
: Contains system-related components (e.g., CoreDNS, API server).kube-public
: Readable by everyone, typically used for public information.kube-node-lease
: Stores heartbeat information for node monitoring.
Services in Kubernetes
A Service in Kubernetes is an abstraction that enables stable networking for a set of Pods. Since Pods are ephemeral, their IP addresses change when they restart, and services provide a consistent way to access them.
Types of Services:
ClusterIP (Default)
Exposes the service internally within the cluster.
Not accessible from outside.
Example:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080
NodePort
Exposes the service on each node’s IP at a static port.
Accessible externally using
NodeIP:NodePort
.Example:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: NodePort selector: app: my-app ports: - port: 80 targetPort: 8080 nodePort: 30000
LoadBalancer
Integrates with cloud providers to expose the service via an external load balancer.
Used in cloud-based Kubernetes deployments.
Example:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: LoadBalancer selector: app: my-app ports: - port: 80 targetPort: 8080
ExternalName
Maps a service to an external DNS name instead of routing traffic to a set of pods.
Example:
apiVersion: v1 kind: Service metadata: name: my-external-service spec: type: ExternalName externalName: example.com
Common Service Commands:
List all services
kubectl get services
Describe a service
kubectl describe service my-service
Expose a deployment as a service
kubectl expose deployment my-deployment --type=ClusterIP --port=80 --target-port=8080
Service Discovery:
Services can be discovered within the cluster via DNS resolution (if CoreDNS is enabled).
Applications running inside the cluster can reach a service using its name (e.g.,
my-service.default.svc.cluster.local
).
Task 1:
Create a Namespace for your Deployment
Use the command
kubectl create namespace <namespace-name>
to create a NamespaceUpdate the deployment.yml file to include the Namespace
Apply the updated deployment using the command:
kubectl apply -f deployment.yml -n <namespace-name>
Verify that the Namespace has been created by checking the status of the Namespaces in your cluster.
Step 1: Create a Namespace
Run the following command to create a new namespace:
kubectl create namespace my-namespace
Replace my-namespace
with your desired namespace name.
To verify the creation, list all namespaces:
kubectl get namespaces
Step 2: Update the deployment.yml
File
Modify your deployment.yml
to specify the namespace:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: my-namespace # Add this line
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx
ports:
- containerPort: 80
Make sure the namespace
the field is added under metadata
.
Step 3: Apply the Deployment to the Namespace
Use the following command to apply the deployment in the namespace:
kubectl apply -f deployment.yml -n my-namespace
This ensures that your deployment is created within the specified namespace.
Step 4: Verify the Namespace and Deployment
Check if the namespace exists:
kubectl get namespaces
Verify that the deployment is created in the namespace:
kubectl get deployments -n my-namespace
Check the running pods inside the namespace:
kubectl get pods -n my-namespace
Describe the deployment (optional but useful for debugging):
kubectl describe deployment my-deployment -n my-namespace
Once verified, your deployment should successfully run within the specified namespace.
Load Balancing, and Networking in Kubernetes:
Load balancing in Kubernetes distributes traffic across multiple pods or nodes. Kubernetes provides built-in load-balancing mechanisms:
Internal Load Balancing
Handled by ClusterIP or NodePort services within the cluster.
Kubernetes Service selects pods based on Label Selectors.
External Load Balancing
The LoadBalancer service provides an external IP for applications.
In cloud environments, Kubernetes automatically provisions a cloud provider’s load balancer.
Ingress Controller
Used for advanced routing and load balancing.
Works as an alternative to LoadBalancer services.
Example of an Ingress resource:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-clusterip-service port: number: 80
This routes traffic from
myapp.example.com
to the ClusterIP service.
Networking in Kubernetes
Kubernetes networking follows these principles:
Every Pod gets its IP address.
Pods within the same cluster can communicate without NAT.
Containers in the same Pod communicate via
localhost
.Network Policies can restrict access between Pods.
Key Networking Components
Pod-to-Pod Communication
Kubernetes assigns a unique IP to each pod.
Communication is direct, meaning pods can talk to each other without NAT.
Pod-to-Service Communication
Services abstract multiple pods behind a single IP.
Kubernetes DNS resolves service names automatically.
Ingress for External Access
- Ingress controllers allow domain-based routing and SSL termination.
Network Policies
Used to restrict or allow traffic between Pods.
Example:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-specific namespace: my-namespace spec: podSelector: matchLabels: app: my-app policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: trusted-app
This allows only Pods labeled
trusted-app
to communicate withmy-app
.
Working with Services in Kubernetes:
In Kubernetes, Services are objects that provide stable network identities for Pods and abstract the details of Pod IP addresses. They enable Pods to receive traffic from other Pods, Services, and external clients.
Task-1:
Create a Service for your todo-app Deployment
Create a Service definition for your todo-app Deployment in a YAML file.
Apply the Service definition to your K8s (minikube) cluster using the
kubectl apply -f service.yml -n <namespace-name>
command.Verify that the Service is working by accessing the todo-app using the Service's IP and Port in your Namespace.
Step 1: Create the service.yml
file
Save the following content as service.yml
:
apiVersion: v1
kind: Service
metadata:
name: todo-app-service
namespace: <namespace-name> # Replace with your actual namespace
spec:
selector:
app: todo-app # This should match the label of your Deployment
ports:
- protocol: TCP
port: 80 # Service port
targetPort: 8080 # The container port your app is running on
type: NodePort # Exposes the service on a port accessible externally
Step 2: Apply the Service definition
Run the following command to apply the Service:
kubectl apply -f service.yml -n <namespace-name>
Step 3: Get Service Details
To check if the Service is running, use:
kubectl get services -n <namespace-name>
It will show an output similar to this:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
todo-app-service NodePort 10.96.24.112 <none> 80:30007/TCP 10s
Step 4: Access the Todo-App
Since we used NodePort
, you can access your application using:
minikube service todo-app-service -n <namespace-name> --url
This command will return a URL like:
http://192.168.49.2:30007
Open this URL in your browser or use curl
to verify:
curl http://192.168.49.2:30007
This should return the app’s homepage or API response.
Task-2:
Create a ClusterIP Service for accessing the todo-app from within the cluster
Create a ClusterIP Service definition for your todo-app Deployment in a YAML file.
Apply the ClusterIP Service definition to your K8s (minikube) cluster using the
kubectl apply -f cluster-ip-service.yml -n <namespace-name>
command.You can verify that the ClusterIP Service is working by accessing the to-do app from another Pod in the cluster in your Namespace.
Step 1: Create cluster-ip-service.yml
Save the following content as cluster-ip-service.yml
:
apiVersion: v1
kind: Service
metadata:
name: todo-app-clusterip-service
namespace: <namespace-name> # Replace with your actual namespace
spec:
selector:
app: todo-app # Ensure this matches the label of your Deployment
ports:
- protocol: TCP
port: 80 # The port to expose within the cluster
targetPort: 8080 # The port on the todo-app container
type: ClusterIP # Default service type for internal cluster communication
Step 2: Apply the ClusterIP Service Definition
Run the following command:
kubectl apply -f cluster-ip-service.yml -n <namespace-name>
Step 3: Verify the Service
Check if the Service is running:
kubectl get services -n <namespace-name>
Expected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
todo-app-clusterip-service ClusterIP 10.96.32.125 <none> 80/TCP 10s
Step 4: Access the Todo-App from Another Pod
To test if the Service is reachable within the cluster:
Run a test Pod inside the same Namespace:
kubectl run test-pod --image=busybox --restart=Never -n <namespace-name> -- sleep 3600
Access the Pod’s shell:
kubectl exec -it test-pod -n <namespace-name> -- sh
Use
curl
orwget
to access the Service:curl http://todo-app-clusterip-service:80
If your app is running correctly, this should return an expected response.
Exit the Pod:
exit
Cleanup the test Pod (optional):
kubectl delete pod test-pod -n <namespace-name>
Task-3:
Create a LoadBalancer Service for accessing the todo-app from outside the cluster
Create a LoadBalancer Service definition for your todo-app Deployment in a YAML file.
Apply the LoadBalancer Service definition to your K8s (minikube) cluster using the
kubectl apply -f load-balancer-service.yml -n <namespace-name>
command.Verify that the LoadBalancer Service is working by accessing the todo-app from outside the cluster in your Namespace.
Step 1: Create load-balancer-service.yml
Save the following content as load-balancer-service.yml
:
apiVersion: v1
kind: Service
metadata:
name: todo-app-loadbalancer-service
namespace: <namespace-name> # Replace with your actual namespace
spec:
selector:
app: todo-app # Ensure this matches the label of your Deployment
ports:
- protocol: TCP
port: 80 # The external port exposed by the service
targetPort: 8080 # The port on the todo-app container
type: LoadBalancer # Exposes the service externally using a cloud provider's LB
Step 2: Apply the LoadBalancer Service Definition
Run the following command:
kubectl apply -f load-balancer-service.yml -n <namespace-name>
Step 3: Verify the Service
Check if the Service is running:
kubectl get services -n <namespace-name>
Expected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
todo-app-loadbalancer-service LoadBalancer 10.96.55.200 <pending> 80:31234/TCP 10s
In Minikube, the EXTERNAL-IP
the field usually stays as <pending>
because Minikube does not provide a cloud-based load balancer. Instead, use the following command:
minikube service todo-app-loadbalancer-service -n <namespace-name> --url
This will return a URL similar to:
http://192.168.49.2:31234
Step 4: Access the Todo-App from Outside the Cluster
Open the provided URL in a web browser or use curl
to test:
curl http://192.168.49.2:31234
Alternative (Using Port Forwarding if LoadBalancer Doesn't Work in Minikube)
If minikube service
doesn't work, you can use port forwarding as an alternative:
kubectl port-forward svc/todo-app-loadbalancer-service -n <namespace-name> 8080:80
Then access the app at:
http://localhost:8080