Hedronite · Cert-Prep · CNCF / CKA · Track K8s Day 7 · Wed 2026-07-29 · Backfilled 07-30

CKA — Services and Networking — the 20% domain

Twenty percent of the exam. Twenty-five minutes of the lab. Memorize the vocabulary; the diagnosis follows.

Lesson Class: Cert-Prep (CKA — CNCF)
Track / Day: K8s (Deep K8s) — round-robin day 7, third K8s visit; k8s_day_counter=2 → CKA-emphasis
Blueprint Domain: Services and Networking (20%)
Word Count: ~2,320
Grounding: Burns/Beda/Hightower K8s U&R 3rd ed — Ch 7 Services pp. 89-102 · Ch 9 Ingress pp. 133-146 · Poulton The K8s Book Ch 12
Paired Ops: Kubernetes Services and Networking — ClusterIP, NodePort, LoadBalancer, kube-proxy
Paired Dev: Python for Service Discovery — Watch API, EndpointSlices, Client-Side Registry
Discipline: ROD v3 · aether-accent meta-card · q-card practice pattern

Four Service types. One DNS name pattern. Ingress on top for L7. kube-proxy underneath for L4. Learn the whole grid and the lab clock stops mattering.

§ IFrame

The CKA blueprint gives Services and Networking 20% of the exam, which places it behind only Troubleshooting (30%) in weight. In a two-hour hands-on lab, that translates to roughly twenty-five minutes of tasks where you will be creating Services, exposing pods, writing an Ingress, and diagnosing a broken DNS lookup while the timer runs. Those tasks reward memorized muscle patterns more than they reward understanding, but the understanding is what lets you diagnose the ones that go wrong.

Today closes the Services and Networking domain in one pass. The four Service types with the differences between them that always show up in questions. The DNS naming scheme so short-name resolution failures become instantly recognizable. Ingress and IngressController as the L7 layer above L4 Services. And the two kube-proxy modes you will meet in the wild plus how to tell which one a cluster is running. The Ops lesson today built the mental model; this lesson names the exact vocabulary the exam uses and the imperative kubectl commands that produce it fast.

§ IIDomain Foundations — Service Types on the Exam

Every CKA question about exposing a workload turns on picking the right Service type. Know the four cold, and know the two imperative shapes that create them, because the lab does not give you time to open the documentation for a YAML template.

ClusterIP is the default. Every Service is a ClusterIP unless you say otherwise, and every ClusterIP has a virtual IP reachable only inside the cluster. kubectl expose deployment backend --port=80 --target-port=8080 creates a ClusterIP Service named backend. Reach it from any pod at http://backend/. This is what pod-to-pod communication actually uses in almost every cluster.

NodePort additionally exposes the Service on the same port of every node, in the range 30000-32767. kubectl expose deployment backend --port=80 --target-port=8080 --type=NodePort creates one; the assigned NodePort is visible in kubectl get svc backend -o wide under the PORT(S) column, formatted as 80:31234/TCP. The 31234 is the NodePort. A caller reaches the service at http://<any-node-ip>:31234.

LoadBalancer additionally asks the cloud provider for an external L4 load balancer. --type=LoadBalancer on the same expose command creates one, and kubectl get svc backend shows the EXTERNAL-IP populating once the LB is ready (a few minutes typically). In a bare-metal cluster or a lab without a cloud controller, the external IP stays as <pending> forever, which is worth knowing so you can recognize it and not spend two minutes waiting.

ExternalName is DNS aliasing. It creates a CNAME record in cluster DNS from the Service name to an external hostname. kubectl create service externalname my-db --external-name=db.rds.amazonaws.com is the imperative form. No pods, no ClusterIP, no kube-proxy work; just a name that cluster DNS resolves.

The exam presents scenarios and asks you to name the type. A pod-to-pod call needs ClusterIP. Exposing a workload from a bare-metal lab cluster to a lab machine on the same subnet needs NodePort. A production internet-facing entry point in a cloud cluster needs LoadBalancer. A cluster-local name that resolves to an external RDS instance needs ExternalName.

§ IIIObjective Flavor — DNS in the Cluster

Every Service gets a DNS record. Namespace-local pods resolve short names against their own namespace; cross-namespace pods must qualify with the namespace. The full pattern is <service>.<namespace>.svc.<cluster-domain>, where cluster-domain is cluster.local in a default cluster.

A pod's /etc/resolv.conf is populated at pod startup with three things worth memorizing because they explain every "the short name doesn't resolve" question the exam asks:

nameserver points at the CoreDNS Service's ClusterIP (the kube-dns Service, still historically named). search carries a search-domain list: <my-namespace>.svc.cluster.local svc.cluster.local cluster.local. This is why a pod in default can call backend and get backend.default.svc.cluster.local. options ndots:5 tells the resolver that any name with fewer than 5 dots should be tried through the search list before being tried as an absolute name. The value 5 catches almost every common short name; it also means that any fully-qualified external hostname must end with a trailing dot to skip the search list, which is a performance detail that occasionally surfaces on the exam.

Cross-namespace: from a pod in namespace frontend, calling backend (short) resolves to backend.frontend.svc.cluster.local which does not exist. Calling backend.default resolves to backend.default.svc.cluster.local which does. When the exam asks why a pod in one namespace cannot reach a service in another, this is almost always the answer.

§ IVObjective Flavor — Ingress and IngressController

Ingress is the L7 (HTTP/HTTPS) routing layer above L4 Services. An Ingress resource declares path-based or host-based rules; an IngressController (NGINX, Traefik, HAProxy, cloud-provider-specific) reads Ingress resources and configures its own L7 proxy to serve them. The exam expects you to know that Ingress alone does nothing without a controller running in the cluster, and that different controllers may support different annotations and behaviors.

An Ingress rule maps HTTP requests to Services by path or host:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop
spec:
  ingressClassName: nginx
  rules:
  - host: shop.hedronite.example
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

ingressClassName names the controller that should serve this Ingress; you cannot have two controllers fight over the same resource. pathType is required and takes Prefix, Exact, or ImplementationSpecific. The imperative form kubectl create ingress shop --rule="shop.hedronite.example/api*=api:80" --rule="shop.hedronite.example/*=web:80" produces the same resource for tasks where typing a YAML template is not the fastest path. Burns's Ingress chapter that grounds this section walks the full example, including the difference between hostname and path routing.

§ VObjective Flavor — kube-proxy and Its Modes

kube-proxy is the node-local component that programs the data path for Services. The CKA does not ask you to configure it (that is CKS territory) but it does ask you to describe what it does and recognize its modes from cluster inspection.

Three modes exist and one is deprecated. userspace mode is old and unused; know the name only. iptables is the default in most clusters; kube-proxy watches the API for Services and EndpointSlices and writes iptables rules that DNAT Service ClusterIPs to a randomly selected pod IP. ipvs mode uses the IPVS kernel module for hash-based lookup that scales better than iptables at thousands of Services; you inspect it with ipvsadm -Ln and it requires the IPVS kernel module loaded on the node.

To tell which mode a running cluster uses, inspect the kube-proxy DaemonSet's ConfigMap: kubectl get configmap kube-proxy -n kube-system -o yaml and look for the mode: line. If empty, the default is iptables. If ipvs, ipvs rules are what's programmed. This inspection surfaces on troubleshooting questions where a Service works from some pods and not from others; a broken kube-proxy on one node is the answer, and kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=50 is where you look.

§ VIConnection to Today's Ops and Dev Lessons

The Ops lesson today built the conceptual picture the exam vocabulary here labels: what a Service is, what the four types reach, what kube-proxy does to make it work. The Dev lesson today lifted the same picture to a Python client that watches EndpointSlices directly, which is what a service-mesh sidecar does when it takes over routing from kube-proxy. The three altitudes align cleanly: the concept, the imperative kubectl commands that produce it, and the Python API that programs against it. The exam rewards the middle altitude fastest, and both other lessons reinforce it.

§ VIIPractice Questions

Q1 · Service Type by Scenario
A pod in namespace frontend needs to call a pod in namespace backend. Neither is exposed outside the cluster. What Service type does the backend need, and what DNS name does the frontend use?
Q2 · NodePort Discovery
You run kubectl expose deployment api --port=80 --target-port=8080 --type=NodePort. How do you find the assigned NodePort to test from a laptop on the same subnet?
Q3 · Ingress Without a Controller
You create an Ingress resource in a cluster with no IngressController installed. What happens when you try to reach the declared host?
Q4 · DNS Resolution
A pod in namespace default runs curl http://api.payments/. The Service api exists only in namespace payments. Does it resolve?
Q5 · kube-proxy Mode
You are handed a cluster you did not build. Where do you look to find out whether kube-proxy is running iptables or ipvs mode?
Q6 · port vs targetPort
A Service declares port: 80 and targetPort: 8080. What does each mean and what does a caller in the cluster call?

§ VIIIQuestion Resolutions

Answer 1. The backend Service should be type ClusterIP (the default; you can omit --type when running kubectl expose). The correct DNS name is backend.backend.svc.cluster.local, or more commonly the shorter backend.backend. The frontend pod's search list does not include the backend namespace, so the bare short name backend will not resolve from the frontend namespace; the namespace qualification is required.

Answer 2. Run kubectl get svc api -o wide and read the PORT(S) column. It shows something like 80:31234/TCP, where 80 is the cluster-facing port and 31234 is the assigned NodePort. Reach the service at http://<any-node-ip>:31234. To get the node IPs, kubectl get nodes -o wide shows the INTERNAL-IP column.

Answer 3. Nothing happens. Ingress is a declarative resource that an IngressController reads and acts on. With no controller installed, no L7 proxy is configured, so requests to the declared host never reach the workload. The Ingress resource sits in etcd unused. Diagnosing this on the exam is fast: kubectl get pods -A | grep -i ingress reveals whether any controller pods exist.

Answer 4. Yes. The name api.payments has one dot, which is fewer than the ndots:5 threshold, so the resolver tries the search list first: api.payments.default.svc.cluster.local (no match), api.payments.svc.cluster.local (match). CoreDNS returns the ClusterIP of the api Service in the payments namespace. Cross-namespace resolution works with the two-part <service>.<namespace> form specifically because the search list catches it.

Answer 5. Two places, in order of preference. First, the kube-proxy ConfigMap: kubectl get configmap kube-proxy -n kube-system -o yaml and read the mode: field. Empty or absent means iptables (the default). Second, if the ConfigMap is unclear or missing, check a kube-proxy pod's logs: kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=50 and look for Using iptables Proxier or Using ipvs Proxier.

Answer 6. port: 80 is the port the Service exposes on its ClusterIP; a caller in the cluster reaches the service at http://<service-name>:80. targetPort: 8080 is the port the container is actually listening on inside the pod. The mapping lets the Service present a public-facing port shape (often 80 or 443) while the container listens on whatever port is convenient (often a non-privileged high port). kube-proxy handles the port translation as part of the DNAT rule it writes.

🫡 ⚖️ 📜
Leo.Syri — Praetor Consulate, Imperium Luminaura
Filed 2026-07-30 backfill (Wed 2026-07-29 Fajr slot) · Cert lesson · K8s deep-mastery track (day 7, visit 3; CKA-emphasis per k8s_day_counter=2)