$ run as a normal user# run as root (or with sudo)
Skills in this chapter
- Services, endpoints and CoreDNS
Know the service types
The type decides who can reach the service.
| Type | Reachable from | Notes |
|---|---|---|
| ClusterIP (default) | Inside the cluster | A virtual IP |
| NodePort | Every node's IP on a port 30000–32767 | For tests or external load balancers |
| LoadBalancer | The internet / network | Asks the cloud for a load balancer |
| ExternalName | Inside the cluster | A DNS alias (CNAME) to an outside name |
Headless (clusterIP: None) | Inside the cluster | DNS returns the pod IPs (StatefulSets) |
Expose a Deployment
kubectl expose creates a Service with the Deployment's labels as selector.
kubectl expose deployment web --port=80 --target-port=8080 -n shop
kubectl expose deployment web --name=web-np --type=NodePort --port=80 --target-port=8080 -n shop
kubectl get svc -n shop
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP 10.96.41.12 <none> 80/TCP 10s
web-np NodePort 10.96.200.7 <none> 80:31452/TCP 5s
curl http://NODE_IP:31452/apiVersion: v1
kind: Service
metadata: { name: web, namespace: shop }
spec:
selector: { app: web }
ports:
- name: http
port: 80
targetPort: 8080| Field | Meaning |
|---|---|
port | The port of the Service |
targetPort | The port of the container |
nodePort | The port on every node (NodePort type) |
selector | Which pods get the traffic |
Check the endpoints
The Service sends traffic only to ready pods that match the selector. The endpoints list shows them.
kubectl get endpointslices -n shop -l kubernetes.io/service-name=web
kubectl describe svc web -n shop | grep -i endpoints
Endpoints: 10.244.1.15:8080,10.244.2.9:8080Remember
No endpoints = the selector labels do not match the pod labels, or the pods are not ready. This is the most common Service problem.
Use cluster DNS
Every Service gets a DNS name: SERVICE.NAMESPACE.svc.cluster.local. Inside the same namespace, the short name SERVICE works.
kubectl run tmp --rm -it --image=busybox:1.36 --restart=Never -- nslookup web.shop.svc.cluster.local
Name: web.shop.svc.cluster.local
Address 1: 10.96.41.12
kubectl run tmp --rm -it --image=busybox:1.36 --restart=Never -- wget -qO- http://web.shop
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system -o yaml| Name | Resolves to |
|---|---|
web | The Service in the same namespace |
web.shop | The Service web in namespace shop |
web.shop.svc.cluster.local | The full name |
10-244-1-15.shop.pod.cluster.local | A pod by its IP |
Know how kube-proxy routes
kube-proxy (or an eBPF CNI like Cilium) programs every node so traffic to a Service IP goes to one of its pods.