Skip to main content

Service

Best Practice Flow

Commands
k get svc/service
k get endpoints

Need to add selectors for pod manually.

warning

The below will not use the pods' labels as selectors; instead it will assume selectors as app=redis.

kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml

Cross-ns Pod Service Reach

Hostname format for cross namespace pod communication, hostname:

svcname.namespace.svc.cluster.local

Expose

tip

Expose first, edit the service later, quicker. This will automatically use the pod's labels as selectors, but you cannot specify the node port. 

warning

When using kubectl expose with --type=NodePort, you cannot specify which port number will be used on the node - Kubernetes will automatically assign one from the 30000-32767 range. If you need a specific nodePort, you'll need to edit the YAML afterward.

kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml
kubectl expose pod nginx --port=80 --name nginx-service --type=NodePort --dry-run=client -o yaml
  • NodePorts can only be between 30,000 - 32767
  • NodePort is superset of ClusterIP type.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort # default is ClusterIP. Also can be LoadBalancer (cloud provided), or ExternalName to route outside (cname)
selector:
app: my-app
ports:
- port: 80 # Service port (inside cluster)
targetPort: 8080 # Pod port
nodePort: 30080 # Optional, otherwise auto-assigned

Local port forwarding

Forwards port to from local machine (8080) to pod (80)

kubectl port-forward pod/nginx 8080:80
kubectl port-forward svc/<service-name> 8080:80

Headless Service

  • If ClusterIP: None then a service is headless.
  • It returns the matchin pod IPs, without doing load balancing.
  • Works well with stateful sets
  • Direct pod communication with client side service discovery.

For Pods

  • pod.spec.subdomain should match headless service name and pod.spec.hostname should have value.
  • But for deployments it won't work as multiple pods will get the same subdomain.

For StatefulSets

pod.spec.serviceName should match the headless service name.