Kubernetes From Zero to Hero – Part 6: Exposing Your Applications with Kubernetes Services

Manas UpadhyayManas Upadhyay
3 min read

Quick Recap – Where We Are

In the last blog, we:

  • Understood how Deployments manage ReplicaSets and Pods

  • Learned to scale applications manually

  • Performed rolling updates without downtime

  • Saw how Kubernetes ensures self-healing by replacing failed Pods

But all this happens within the cluster. What if we want the outside world (users, clients, APIs) to access our app?

That’s where Kubernetes Services come in.


Why Do We Need a Service?

Let’s say you deployed 3 replicas of an Nginx Pod.

These pods:

  • Get dynamic IPs that change on restart

  • Are managed by a ReplicaSet

  • Cannot be accessed reliably unless we know their IPs (which we don’t)

Problem:

No static endpoint to reach your app.

Solution:

Create a Service, which provides:

  • A stable IP

  • A DNS name

  • Load balancing across Pods


Types of Kubernetes Services

TypeUse CaseAccessible From
ClusterIPDefault, internal-only communicationInside cluster only
NodePortExpose on a port on each NodeExternal via <NodeIP>:<Port>
LoadBalancerUses cloud provider’s external LBInternet (if cloud-based)
ExternalNameMaps to external DNSInside cluster

When to Use What?

SituationUse Type
Pod-to-pod communicationClusterIP
Local testing from browser or PostmanNodePort
Production deployment on cloudLoadBalancer
Talk to external DB/service via DNSExternalName

Example: Exposing Nginx via NodePort

nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

Apply it:

kubectl apply -f nginx-service.yaml

Check service:

kubectl get svc

Access the App (Minikube)

If you’re using Minikube:

minikube service nginx-service

It will open the URL in your browser.

If not using Minikube, open:

http://<NodeIP>:30080

You can get Node IP by:

kubectl get nodes -o wide

ClusterIP Example (Internal Only)

Used by backends or services that should not be exposed publicly.

apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
    - port: 8080
      targetPort: 8080

DNS in Kubernetes

Kubernetes assigns DNS records for services automatically.

If you have a service called backend-service in namespace dev, it can be accessed by:

http://backend-service.dev.svc.cluster.local

This works inside the cluster only.


Bonus: Headless Service

Want service without load balancing, just for DNS?

Use:

clusterIP: None

Used in stateful apps like Kafka, Elasticsearch, etc.


Summary

ConceptRole in App Exposure
ServiceStable network identity for Pods
ClusterIPInternal-only service
NodePortExposes app via each node’s IP and port
LoadBalancerCreates external cloud-based endpoint
DNSBuilt-in DNS for service discovery

What’s Next?

In the next post, we’ll explore:

  • What is Ingress and why it’s better than NodePort/LoadBalancer

  • How to install Ingress controllers

  • Route traffic to multiple apps using clean URLs

It’s time to bring the NGINX Ingress Controller into the mix and build a proper gateway for your cluster.

0
Subscribe to my newsletter

Read articles from Manas Upadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Manas Upadhyay
Manas Upadhyay

I am an experienced AWS Cloud and DevOps Architect with a strong background in designing, deploying, and managing cloud infrastructure using modern automation tools and cloud-native technologies.