π Overview
Kubernetes provides multiple ways to expose your applications running inside Pods. The most commonly used Service types are:
-
ClusterIP
β internal communication -
NodePort
β external access via node IP and port -
LoadBalancer
β production-grade public access via cloud load balancer
In this blog, weβll build a real-world E-commerce Web App with:
-
Frontend (ReactJS) β exposed via
LoadBalancer
-
Backend (Spring Boot or FastAPI) β exposed via
NodePort
-
Database (MySQL) β exposed via
ClusterIP
π§© Application Architecture
+------------------+ +------------------+ +------------------+
| React Frontend | <---> | Backend (API) | <---> | MySQL DB |
| (LoadBalancer) | | (NodePort) | | (ClusterIP) |
+------------------+ +------------------+ +------------------+
β
Public Internet
βοΈ 1. MySQL Service (ClusterIP)
πΉ Why ClusterIP?
We donβt want the database to be accessible from outside. It should be reachable only by internal Pods like the backend.
π§Ύ Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
π§Ύ Service
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: ClusterIP
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
βοΈ 2. Backend API Service (NodePort)
πΉ Why NodePort?
For non-production use or internal teams, we may want to access the backend using the node's external IP and a fixed port.
π§Ύ Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: mycompany/backend:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "mysql"
π§Ύ Service
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: NodePort
selector:
app: backend
ports:
- port: 80
targetPort: 8080
nodePort: 30080
π Access via
http://<NodeIP>:30080
βοΈ 3. Frontend Service (LoadBalancer)
πΉ Why LoadBalancer?
This service needs to be accessed publicly by customers, so we use LoadBalancer
to provision a cloud load balancer.
π§Ύ Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: mycompany/frontend:latest
ports:
- containerPort: 80
π§Ύ Service
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
type: LoadBalancer
selector:
app: frontend
ports:
- port: 80
targetPort: 80
βοΈ Cloud providers like AWS, GCP, and Azure will assign a public IP to this service.
π Application Flow
+---------------------------+
| Public Internet |
+------------+-------------+
β
[LoadBalancer Service]
β
[Frontend Pod]
β
[NodePort to Backend]
β
[ClusterIP to MySQL]
π Summary Table
Component | Service Type | Exposed To | Access Method |
---|---|---|---|
MySQL | ClusterIP | Internal Pods | DNS: mysql:3306
|
Backend | NodePort | Devs / Node IP | http://<NodeIP>:30080 |
Frontend | LoadBalancer | Public Internet | http://<external-ip> |
β Best Practices
-
Use
ClusterIP
for internal-only services (e.g., DBs, caches). -
Use
NodePort
sparinglyβonly for development, testing, or where cloud load balancer isn't an option. -
Use
LoadBalancer
in production for services needing public access. - Use Ingress Controllers and domain routing when dealing with multiple
LoadBalancer
services. - Add liveness and readiness probes for all deployments.
- Parameterize all ports, replicas, and resource limits using Helm charts for reusability.
π¦ Bonus: Ingress Alternative
If you want to expose multiple services under one domain, consider using an Ingress Controller instead of multiple LoadBalancers.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ecommerce-ingress
spec:
rules:
- host: frontend.mysite.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
π― Conclusion
Understanding and using the right Kubernetes Service type is key to building scalable, secure, and manageable cloud-native apps.
Need | Use This Service |
---|---|
Internal access only | ClusterIP |
Basic external access | NodePort |
Cloud-managed public access | LoadBalancer |
Most tech companies β especially those building secure, scalable, cloud-native applications β follow this common architecture pattern when using Kubernetes:
β Industry-Standard Approach (Used by Most Tech Companies)
π Backend = ClusterIP
- Not exposed to the public
- Only accessible internally by the frontend
- Protects business logic and APIs from direct attack
- Communication via internal DNS (e.g.,
http://backend:8080
)
π Frontend = LoadBalancer
or Ingress
- Exposed to the public Internet
- Acts as the only entry point to the system
- Sends requests to backend over internal network
ποΈ Database = ClusterIP
- Always kept internal
- Accessed only by backend
π§ Why This Architecture Is Preferred
Benefit | Description |
---|---|
Security | Minimizes attack surface; only the frontend is public |
Control & Monitoring | Easier to monitor and throttle access through a single public endpoint |
Scalability | You can scale frontend/backend independently |
Compliance | Meets security standards (SOC 2, ISO 27001, etc.) by isolating sensitive services |
π’ Real-World Examples
Company | Approach Used |
---|---|
Netflix | Frontend via edge gateway + service mesh; backends internal |
Airbnb | Load balancer to frontend + ClusterIP for internal APIs |
Stripe | Ingress controller at edge + everything else via ClusterIP |
Shopify | Uses Envoy/Gloo mesh at the edge, then internal ClusterIP |
Amazon (AWS) | ALB/NLB at edge β internal services over private VPCs |
π§Ύ Optional: Using an Ingress Controller
Most companies also place an Ingress controller (like NGINX, Traefik, or Istio Gateway) in front of the frontend to manage:
- SSL termination
- URL path routing
- Rate limiting
- Authentication
π Pro Tip: Zero Trust Model
Larger orgs go a step further with:
- mTLS between services
- Network Policies to restrict pod communication
- Service Mesh (like Istio or Linkerd) for traffic control, observability, and security
β TL;DR: What Most Tech Companies Use
Component | Service Type | Publicly Exposed? | Typical Practice |
---|---|---|---|
Frontend | LoadBalancer / Ingress | β Yes | Public entry point |
Backend | ClusterIP | β No | Internal-only, accessed by frontend |
Database | ClusterIP | β No | Internal-only, accessed by backend |
Would you like a production-grade setup with Helm, Ingress, TLS, and best practices bundled into one YAML or chart?
Top comments (0)