CKA — Kubernetes Administrator
Attaching Traffic With Services
Goal
You create the five Service types and an Ingress yourself, and you create and fix a situation where a mismatched selector leaves the endpoints empty.
Why it matters
In the exam, the problem "I created the Service but can't connect" is mostly one of three things: the selector, the port, or Ready. Once you understand that a Service object does not carry traffic but is a declaration that builds a backend list from a selector, the diagnostic order sets itself. You first check whether the endpoints have an IP. If they do, it is a data plane or port problem; if not, it is a selector or Pod Ready problem.
It is also important to distinguish targetPort from port. port is the port the Service opens, and targetPort is the port on the Pod side. If they are the same you can omit one, which makes them easy to confuse, but the mistake shows up the moment you set them differently.
Steps
- Create the namespace
cka-netand the Deploymentweb(2 replicas, imagenginx:1.27, Pod labelapp=web). Then create the ClusterIP Serviceweb-svc. Port 80, targetPort 80, selectorapp=web. - Create the Deployment
api(2 replicas, imagenginx:1.27, Pod labelapp=api). Create the Serviceapi-svcwith the wrong selectorapp=api-server, save the endpoint query result to/root/cka-net/endpoints-before.txt, and then fix the selector toapp=api. - Create the NodePort Service
web-np. Port 80, selectorapp=web, and set nodePort explicitly to30080. - Create the Deployment
db(1 replica, imagenginx:1.27, Pod labelapp=db) and the headless Servicedb-headless. clusterIPNone, port 5432, selectorapp=db. - Create the Service
multi-svc. Selectorapp=web, two ports — namehttp(port 80, targetPort 8080) and namemetrics(port 9090). - Create the Service
ext-db. TypeExternalName, externalNamenas.homelab.internal. - Create the Ingress
web-ing. ingressClassNamenginx, hostcka.homelab.internal; send path/(pathType Prefix) to port 80 ofweb-svc, and path/api(pathType Prefix) to port 80 ofapi-svc.
Reference
- You can also see the endpoints with
kubectl get endpointslice -n cka-net -l kubernetes.io/service-name=web-svc. - In step 2, the order is graded. Be sure to save the result to the file before you fix it.
- Common mistake 1: trying to fix
clusterIP: Nonelater. This field is immutable. - Common mistake 2: omitting
pathTypein the Ingress. It is a required field in v1, so the request is rejected.
ClusterIP Service and endpoints
Create the namespace cka-net and the Deployment web (2 replicas, image nginx:1.27, Pod label app=web). Then create the ClusterIP Service web-svc. Port 80, targetPort 80, selector app=web.
kubectl expose is the fastest, but check what the selector ends up as. Endpoints are filled in only when the Pods are Ready.
A selector typo leaves the endpoints empty
Create the Deployment api (2 replicas, image nginx:1.27, Pod label app=api). Create the Service api-svc with the wrong selector app=api-server, save the endpoint query result to /root/cka-net/endpoints-before.txt, and then fix the selector to app=api.
First create it with the wrong selector, see with your own eyes that the endpoints are empty, leave that in the file, and then fix it. If you do not keep the order, no evidence remains.
Specify the NodePort number directly
Create the NodePort Service web-np. Port 80, selector app=web, and set nodePort explicitly to 30080.
nodePort goes inside the ports array. The default range is 30000–32767, and values outside it are rejected.
Headless Service
Create the Deployment db (1 replica, image nginx:1.27, Pod label app=db) and the headless Service db-headless. clusterIP None, port 5432, selector app=db.
If you set clusterIP to None, no VIP is assigned. This field cannot be changed after creation, so if you created it wrongly, create it again.
Expose two ports
Create the Service multi-svc. Selector app=web, two ports — name http (port 80, targetPort 8080) and name metrics (port 9090).
If there is more than one port, each port must have a name. port and targetPort can be different values.
Point to an external system with ExternalName
Create the Service ext-db. Type ExternalName, externalName nas.homelab.internal.
An ExternalName Service has neither a selector nor ports, and it does not get a ClusterIP. If you created it with another type first, it is cleaner to create it again.
Putting it together: combine two Services with an Ingress
Create the Ingress web-ing. ingressClassName nginx, host cka.homelab.internal; send path / (pathType Prefix) to port 80 of web-svc, and path /api (pathType Prefix) to port 80 of api-svc.
ingressClassName is a field of spec, not an annotation. Each path requires a pathType, and the backend is identified with service.name and service.port.number.