Creating and Managing Services
1. Creating ClusterIP Service
Example: ClusterIP
apiVersion: v1
kind: Service
metadata: { name: web }
spec:
type: ClusterIP
selector: { app: web }
ports:
- { name: http, port: 80, targetPort: 8080, protocol: TCP }
| Field | Meaning |
| port | Service-side port |
| targetPort | Pod port (number or name) |
| protocol | TCP / UDP / SCTP |
2. Creating NodePort Service
spec:
type: NodePort
ports:
- { port: 80, targetPort: 8080, nodePort: 30080 }
| Property | Detail |
| nodePort range | 30000-32767 (configurable) |
| Access | NODE_IP:nodePort from anywhere |
| When nodePort omitted | Auto-assigned |
3. Creating LoadBalancer Service
spec:
type: LoadBalancer
loadBalancerClass: service.k8s.aws/nlb
externalTrafficPolicy: Local
ports:
- { port: 443, targetPort: 8443 }
| Annotation Family | Cloud |
service.beta.kubernetes.io/aws-load-balancer-* | AWS |
cloud.google.com/load-balancer-type | GCP |
service.beta.kubernetes.io/azure-* | Azure |
4. Creating Headless Service
spec:
clusterIP: None
selector: { app: db }
ports: [{ port: 5432 }]
| Effect | Detail |
| No VIP | DNS returns A/AAAA records for pods |
| Use | StatefulSet, client-side LB |
5. Listing Services
kubectl get svc -A
kubectl get svc -o wide
kubectl get endpoints web # legacy
kubectl get endpointslices -l kubernetes.io/service-name=web
| Column | Meaning |
| CLUSTER-IP | Internal VIP |
| EXTERNAL-IP | LoadBalancer address |
| PORT(S) | Service ports (and nodePort if any) |
6. Describing Service Details
| Field | Info |
| Selector | Pod label filter |
| Endpoints | Backing pod IPs |
| Session Affinity | None / ClientIP |
| Events | LB provisioning, etc. |
7. Exposing Deployments
kubectl expose deploy web --port=80 --target-port=8080 --type=ClusterIP
kubectl expose deploy web --port=80 --type=LoadBalancer --name=web-public
| Flag | Effect |
--type | ClusterIP / NodePort / LoadBalancer |
--port | Service port |
--target-port | Pod port |
8. Configuring Service Selectors
| Approach | Detail |
| Label selector | Auto-managed Endpoints |
| No selector | Manually managed Endpoints (e.g., external DB) |
# Service without selector
apiVersion: v1
kind: Service
metadata: { name: external-db }
spec:
ports: [{ port: 5432 }]
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: external-db-1
labels: { kubernetes.io/service-name: external-db }
addressType: IPv4
endpoints: [{ addresses: ["10.0.99.5"] }]
ports: [{ port: 5432, name: "" }]
9. Configuring Session Affinity
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP: { timeoutSeconds: 10800 }
| Value | Effect |
| None (default) | Random per-connection |
| ClientIP | Sticky by source IP |
10. Setting External IPs
spec:
externalIPs: ["203.0.113.10"] # admin-routed external IP
Warning: Cluster does not manage externalIPs routing; must be advertised by network admin.
11. Using ExternalName Services
apiVersion: v1
kind: Service
metadata: { name: db }
spec:
type: ExternalName
externalName: db.prod.example.com
| Property | Detail |
| No proxy | CoreDNS CNAME redirect |
| Use | Stable in-cluster name for external service |
12. Viewing Service Endpoints
kubectl get endpointslices -l kubernetes.io/service-name=web
kubectl describe svc web
kubectl get pods -l app=web -o wide
| Resource | Status |
| EndpointSlice | Modern API (default since 1.21) |
| Endpoints | Legacy, capped at 1000 endpoints |