GitHub link - https://github.com/SUBHAM-NANDI/40DaysKubernetes/blob/main/Day%209/Readme.md
Kubernetes Services Explained: ClusterIP, NodePort, LoadBalancer and External
1. Introduction to Kubernetes Services
Kubernetes services define a logical set of pods and provide a reliable mechanism to access them, regardless of pod IP changes. Services act as an abstraction layer over individual pods and enable communication both within and outside the cluster.
Key Concept: What is a Kubernetes Service?
A Kubernetes service is an abstraction that groups pods with specific labels and provides a consistent interface to access them. Without services, communication between pods would be challenging due to dynamic IP changes each time pods are restarted or rescheduled.
2. Problem Definition
Let’s consider a deployment of four nginx pods serving a frontend application. While these pods are accessible internally within the Kubernetes cluster, they are not exposed to external users. Our goal is to make this application accessible externally using Kubernetes services.
3. Types of Kubernetes Services
1. ClusterIP: For Internal Communication
The ClusterIP service is the default Kubernetes service type. It creates an internal IP within the cluster that is accessible only to other services or pods inside the cluster. This makes it ideal for service-to-service communication.
Example Use Case: Internal Pod Communication
In a scenario where a frontend application needs to communicate with a backend or database service, a ClusterIP can ensure stable communication without worrying about changing pod IPs. For instance, a frontend pod running Nginx may need to communicate with backend pods running Node.js or database pods running MySQL.
Key Benefit: Pods don't need to rely on dynamic IP addresses; they can access services through a consistent ClusterIP.
ClusterIP Service YAML Example
Here is how you can define a simple ClusterIP service in Kubernetes:
apiVersion: v1
kind: Service
metadata:
name: cluster-svc
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 80
Explanation:
-
selector: This matches the backend pods using the label
app: backend
. - port: Defines the port on which the service will be exposed internally.
- targetPort: Refers to the port where the backend application (Node.js) is running inside the pod.
Deploying a ClusterIP Service
- Apply the Service:
kubectl apply -f cluster-ip.yaml
- Verify the Service:
kubectl get svc
Once created, your frontend pods can now use the service name (cluster-svc
) to access the backend service reliably.
2. NodePort: Exposing Services Outside the Cluster
The NodePort service type allows applications to be accessed externally by assigning a specific port (between 30,000-32,767
) on each node in the Kubernetes cluster. External users can access services via NodeIP:NodePort
.
Example Use Case: External Communication
Consider a scenario where you want users to access your frontend application externally without using a load balancer. By setting up a NodePort, the service will be accessible via a specific port on the cluster nodes.
NodePort Service YAML Example
Here is how you can define a NodePort service:
apiVersion: v1
kind: Service
metadata:
name: nodeport-svc
labels:
env: demo
spec:
type: NodePort
selector:
env: demo
ports:
- nodePort: 30001
port: 80
targetPort: 80
nodePort: 30001
Explanation:
- type: NodePort: This specifies that the service will be accessible via a node port.
-
selector: Matches the pods with the label
env: demo
. - port: Defines the internal port (80) where the service is available.
-
nodePort: Assigns a fixed external port (
30001
) through which the service will be accessible outside the cluster.
Deploying a NodePort Service
- Apply the Service:
kubectl apply -f nodeport.yaml
- Verify the Service:
kubectl get svc
Once created, you can access your service externally using http://<Node-IP>:30001
.
Special Case: Using NodePort with Kind Cluster
If you're using Kind (Kubernetes in Docker), the NodePort services are not automatically accessible externally due to Kind's internal network structure. To solve this, you must map the NodePort to your local machine using port mapping in the Kind configuration.
Example Kind Cluster Configuration for Port Mapping:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30001
hostPort: 30001
protocol: TCP
After configuring this file, you will need to recreate the Kind cluster:
- Delete the existing cluster:
kind delete cluster --name <your-cluster-name>
- Create a new cluster with the updated configuration:
kind create cluster --config kind-config.yaml --name <your-cluster-name>
You can then access your service locally using localhost:30001
.
3. LoadBalancer: Production-Level Scaling for External Traffic
The LoadBalancer service type is commonly used in cloud environments (such as AWS, GCP, Azure) to distribute traffic to multiple backend pods. It automatically provisions a cloud provider's load balancer, assigns a public IP, and routes external traffic to the application.
Example Use Case: Scaling for External Traffic
In a production environment, you may have multiple backend pods running your application. A LoadBalancer service allows you to evenly distribute incoming traffic across these pods, ensuring high availability and fault tolerance.
LoadBalancer Service YAML Example
Here’s a sample YAML file for creating a LoadBalancer service:
apiVersion: v1
kind: Service
metadata:
name: lb-svc
spec:
type: LoadBalancer
selector:
app: backend
ports:
- port: 80
targetPort: 80
Explanation:
- type: LoadBalancer: Specifies that a cloud provider's load balancer should be used.
-
selector: Matches the backend pods with the label
app: backend
. -
port: Exposes the service on port
80
externally. -
targetPort: Refers to the internal application port (
80
).
Deploying a LoadBalancer Service
- Apply the Service:
kubectl apply -f lb.yaml
- Check for the External IP:
kubectl get svc
Once the service is created, an external IP will be provisioned by the cloud provider. You can use this IP to access the service externally.
4. ExternalName: Mapping Services to External DNS
The ExternalName service type maps an internal Kubernetes service to an external DNS name. This can be useful when you want to access external resources, such as a database hosted outside your Kubernetes cluster, through Kubernetes services.
Example: Mapping to an External Database
Here is an example of creating an ExternalName service that maps to an external database:
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com
Once this service is applied, any internal application that needs to access the external database can use external-db
as the hostname, which resolves to db.example.com
.
Top comments (0)