plugins/kubernetes-operations/skills/k8s-manifest-generator/references/service-spec.md
Comprehensive reference for Kubernetes Service resources, covering service types, networking, load balancing, and service discovery patterns.
A Service provides stable network endpoints for accessing Pods. Services enable loose coupling between microservices by providing service discovery and load balancing.
Exposes the service on an internal cluster IP. Only reachable from within the cluster.
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: production
spec:
type: ClusterIP
selector:
app: backend
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
sessionAffinity: None
Use cases:
Exposes the service on each Node's IP at a static port (30000-32767 range).
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: NodePort
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30080 # Optional, auto-assigned if omitted
protocol: TCP
Use cases:
Limitations:
Exposes the service using a cloud provider's load balancer.
apiVersion: v1
kind: Service
metadata:
name: public-api
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
spec:
type: LoadBalancer
selector:
app: api
ports:
- name: https
port: 443
targetPort: 8443
protocol: TCP
loadBalancerSourceRanges:
- 203.0.113.0/24
Cloud-specific annotations:
AWS:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # or "external"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:..."
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
Azure:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-pip-name: "my-public-ip"
GCP:
annotations:
cloud.google.com/load-balancer-type: "Internal"
cloud.google.com/backend-config: '{"default": "my-backend-config"}'
Maps service to external DNS name (CNAME record).
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.external.example.com
ports:
- port: 5432
Use cases:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: production
labels:
app: my-app
tier: backend
annotations:
description: "Main application service"
prometheus.io/scrape: "true"
spec:
# Service type
type: ClusterIP
# Pod selector
selector:
app: my-app
version: v1
# Ports configuration
ports:
- name: http
port: 80 # Service port
targetPort: 8080 # Container port (or named port)
protocol: TCP # TCP, UDP, or SCTP
# Session affinity
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
# IP configuration
clusterIP: 10.0.0.10 # Optional: specific IP
clusterIPs:
- 10.0.0.10
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
# External traffic policy
externalTrafficPolicy: Local
# Internal traffic policy
internalTrafficPolicy: Local
# Health check
healthCheckNodePort: 30000
# Load balancer config (for type: LoadBalancer)
loadBalancerIP: 203.0.113.100
loadBalancerSourceRanges:
- 203.0.113.0/24
# External IPs
externalIPs:
- 80.11.12.10
# Publishing strategy
publishNotReadyAddresses: false
Use named ports in Pods for flexibility:
Deployment:
spec:
template:
spec:
containers:
- name: app
ports:
- name: http
containerPort: 8080
- name: metrics
containerPort: 9090
Service:
spec:
ports:
- name: http
port: 80
targetPort: http # References named port
- name: metrics
port: 9090
targetPort: metrics
spec:
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: https
port: 443
targetPort: 8443
protocol: TCP
- name: grpc
port: 9090
targetPort: 9090
protocol: TCP
Distributes requests randomly across pods.
spec:
sessionAffinity: None
Routes requests from same client IP to same pod.
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 3 hours
Use cases:
Cluster (Default):
spec:
externalTrafficPolicy: Cluster
Local:
spec:
externalTrafficPolicy: Local
spec:
internalTrafficPolicy: Local # or Cluster
Controls traffic routing for cluster-internal clients.
Service without cluster IP for direct pod access.
apiVersion: v1
kind: Service
metadata:
name: database
spec:
clusterIP: None # Headless
selector:
app: database
ports:
- port: 5432
targetPort: 5432
Use cases:
DNS returns:
<pod-name>.<service-name>.<namespace>.svc.cluster.localClusterIP Service:
<service-name>.<namespace>.svc.cluster.local
Example:
curl http://backend-service.production.svc.cluster.local
Within same namespace:
curl http://backend-service
Headless Service (returns pod IPs):
<pod-name>.<service-name>.<namespace>.svc.cluster.local
Kubernetes injects service info into pods:
# Service host and port
BACKEND_SERVICE_SERVICE_HOST=10.0.0.100
BACKEND_SERVICE_SERVICE_PORT=80
# For named ports
BACKEND_SERVICE_SERVICE_PORT_HTTP=80
Note: Pods must be created after the service for env vars to be injected.
Kubernetes uses random selection by default. For advanced load balancing:
Service Mesh (Istio example):
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-service
trafficPolicy:
loadBalancer:
simple: LEAST_REQUEST # or ROUND_ROBIN, RANDOM, PASSTHROUGH
connectionPool:
tcp:
maxConnections: 100
Use pod disruption budgets and resource limits:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: my-app
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: my-service
subset: v2
- route:
- destination:
host: my-service
subset: v1
weight: 90
- destination:
host: my-service
subset: v2
weight: 10
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: backend
labels:
app: user-service
tier: backend
spec:
type: ClusterIP
selector:
app: user-service
ports:
- name: http
port: 8080
targetPort: http
protocol: TCP
- name: grpc
port: 9090
targetPort: grpc
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: api-gateway
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:..."
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: api-gateway
ports:
- name: https
port: 443
targetPort: 8443
protocol: TCP
loadBalancerSourceRanges:
- 0.0.0.0/0
apiVersion: v1
kind: Service
metadata:
name: cassandra
spec:
clusterIP: None
selector:
app: cassandra
ports:
- port: 9042
targetPort: 9042
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
spec:
serviceName: cassandra
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
containers:
- name: cassandra
image: cassandra:4.0
apiVersion: v1
kind: Service
metadata:
name: external-database
spec:
type: ExternalName
externalName: prod-db.cxyz.us-west-2.rds.amazonaws.com
---
# Or with Endpoints for IP-based external service
apiVersion: v1
kind: Service
metadata:
name: external-api
spec:
ports:
- port: 443
targetPort: 443
protocol: TCP
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-api
subsets:
- addresses:
- ip: 203.0.113.100
ports:
- port: 443
apiVersion: v1
kind: Service
metadata:
name: web-app
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"
spec:
type: ClusterIP
selector:
app: web-app
ports:
- name: http
port: 80
targetPort: 8080
- name: metrics
port: 9090
targetPort: 9090
Control traffic to services:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
For high traffic:
spec:
externalTrafficPolicy: Local
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600
For WebSocket/long connections:
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 86400 # 24 hours
# Check service exists
kubectl get service <service-name>
# Check endpoints (should show pod IPs)
kubectl get endpoints <service-name>
# Describe service
kubectl describe service <service-name>
# Check if pods match selector
kubectl get pods -l app=<app-name>
Common issues:
# Test DNS from pod
kubectl run debug --rm -it --image=busybox -- nslookup <service-name>
# Check CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
# Check load balancer status
kubectl describe service <service-name>
# Check events
kubectl get events --sort-by='.lastTimestamp'
# Verify cloud provider configuration
kubectl describe node