Hey everyone! 👋
As part of my DevOps learning in public, I’ve been diving deep into Kubernetes and exploring how Services work—particularly how to expose applications inside and outside the cluster using different service types.
In this blog, I’ll walk you through my experiments using ClusterIP, NodePort, and LoadBalancer, along with a quick intro to manual pod scheduling on specific nodes.
Let’s go! 🚀
⚙️ Step 1: Create a ReplicaSet
First, I created a simple ReplicaSet using the following YAML:
# myapp.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: webapp
spec:
replicas: 5
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: mycontainer
image: nginx
Apply it:
kubectl apply -f myapp.yml
Demo 1: ClusterIP
ClusterIP is the default service type and is only accessible within the cluster.
# cip.yml
apiVersion: v1
kind: Service
metadata:
name: mysvc
spec:
type: ClusterIP
ports:
- targetPort: 80 # container port
port: 5000 # service port
selector:
app: web
Or expose it using the CLI:
kubectl expose rs webapp --target-port=80 --port=5000 --name=mysvc
Access It:
- Get the service IP:
kubectl get svc
- Get any node name:
kubectl get nodes -o wide
- Start a debug pod on that node:
kubectl debug node/ -it --image=nginx
- Inside the pod:
apt-get update -y && apt-get install curl -y
curl :5000
Demo 2: NodePort
NodePort allows you to access your service externally on a static port on any worker node.
# nodeport.yml
apiVersion: v1
kind: Service
metadata:
name: web-node-port
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30002
selector:
app: web
Or use:
kubectl expose rs webapp --target-port=80 --port=80 --type=NodePort
Access It:
- Get the node IP:
kubectl get nodes -o wide
- Curl from a debug pod:
curl :30002
Demo 3: LoadBalancer
LoadBalancer is commonly used in cloud environments to expose services publicly using an external IP.
# lb.yml
apiVersion: v1
kind: Service
metadata:
name: mysvc
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
selector:
app: web
Or via CLI:
kubectl expose rs webapp --target-port=80 --port=80 --type=LoadBalancer
Access It:
kubectl get svc
# Use the external IP shown to access your app in the browser
Note: This works on cloud providers like GCP, AWS, or Azure. On Minikube or bare metal, you may need MetalLB or another load balancer.
Bonus: Manual Scheduling
I also tried manually scheduling a pod to a specific node. This can be helpful when testing specific node configurations or behavior.
# pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-container
image: nginx
nodeName:
Just replace with a real node name from:
kubectl get nodes
Apply it:
kubectl apply -f pod.yml
Key Learnings
_
- ClusterIP: Great for internal communication between services.
- NodePort: Exposes apps on every node's IP at a static port.
- LoadBalancer: Best for public access when running on cloud providers.
- Manual scheduling gives control, but use it with caution in production. _
If you're also learning Kubernetes, let’s connect and grow together! 🌱
Drop a comment if this was helpful or if you’ve got tips of your own 🙌