Exposing Services
Choose ClusterIP, NodePort, LoadBalancer, or Ingress depending on who needs to reach your app.
There are several ways to make a workload reachable, from internal-only to public.
| Type | Reachable from | Typical use |
|---|---|---|
ClusterIP | Inside the cluster only | App-to-app traffic |
NodePort | Any node IP on a high port | Quick external access |
LoadBalancer | External IP (ServiceLB on k3s) | Exposing a single service |
| Ingress | Hostname / path via Traefik | Many HTTP services on port 80/443 |
For web apps, an Ingress is usually the cleanest choice. For a single non-HTTP service, a LoadBalancer or NodePort is simpler.
Example
# Quickly expose a Deployment as a NodePort service
kubectl expose deployment web \
--type=NodePort --port=80 --target-port=8080
# See the assigned node port
kubectl get svc webWhen to use it
- A developer uses ClusterIP to keep a database service reachable only inside the cluster while exposing the frontend via an Ingress.
- An ops team uses NodePort to give QA testers direct access to a staging service on a specific port without configuring DNS.
- A production operator combines a LoadBalancer Service with Traefik Ingress to terminate TLS at the ingress layer while letting ServiceLB handle IP assignment.
More examples
Expose a Deployment as NodePort
Creates a NodePort Service that maps a random cluster port to the pod's port 3000, reachable on any node IP.
kubectl expose deployment my-app \
--type=NodePort \
--port=80 \
--target-port=3000
kubectl get svc my-appCreate a ClusterIP service manifest
Defines a ClusterIP Service for a database so only pods within the cluster can reach port 5432.
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP
selector:
app: backend
ports:
- port: 5432
targetPort: 5432Test service connectivity in-cluster
Launches a throwaway pod to test that a ClusterIP service is reachable by DNS name from within the cluster.
kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -- \
curl -s http://backend:5432
kubectl delete pod curl-test --ignore-not-found
Discussion