Back to Blog

CKA Networking Deep Dive: Services, Ingress, and Network Policies (2026)

Master the 20% networking domain on the CKA exam. Hands-on guide to Services (ClusterIP, NodePort, LoadBalancer), Ingress, Gateway API, DNS, and NetworkPolicy with copy-paste YAML and exam-ready patterns.

By Sailor Team , April 27, 2026

Networking is 20% of the CKA exam — second-largest domain after troubleshooting. It’s also the domain candidates underestimate the most. Every other topic has a clean imperative shortcut; networking forces you to write YAML, debug DNS, and reason about traffic across pods, services, ingress, and policies. Get networking right and you bank a quarter of your score on questions that look intimidating but follow predictable patterns.

This guide walks through every networking concept the CKA tests, with exam-ready YAML templates and a debug recipe for each. By the end, you’ll know exactly what to do when the question says “expose this app” or “restrict traffic to this namespace.”

The Networking Layer Cake

Kubernetes networking is four layers stacked on each other. CKA questions can target any layer, so know which is which:

  1. Pod-to-pod: Provided by your CNI plugin (Calico, Flannel, Cilium). Every pod gets an IP that any other pod can reach by default.
  2. Service: A stable virtual IP and DNS name in front of one or more pods. The exam tests ClusterIP, NodePort, and LoadBalancer.
  3. Ingress / Gateway API: HTTP/HTTPS routing into the cluster, typically with hostnames and paths.
  4. NetworkPolicy: Firewall rules at the pod level, restricting which pods can talk to which.

Most CKA networking questions are at layers 2 and 4. Ingress shows up in 1-2 questions per exam.

Services: The 80/20 of Networking Questions

A Service exposes a set of Pods identified by labels under a single virtual IP and DNS name. Master three variants and you’ll handle most service questions.

ClusterIP (the default)

In-cluster only. Every pod can reach the service via its name.

# Imperative: expose an existing deployment
kubectl expose deploy nginx --port=80 --target-port=80

# Imperative: create from scratch
kubectl create svc clusterip my-svc --tcp=80:8080

# YAML
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-svc
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080
EOF

Critical detail: selector must match the pod’s labels exactly. The #1 cause of “service has no endpoints” is a typo here.

NodePort

Exposes the service on every node’s IP at a specific port (30000-32767 by default).

kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort

# Or with a specific nodePort
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: my-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
EOF

Test from any node IP: curl http://<node-ip>:30080.

LoadBalancer

Creates a cloud load balancer in front of NodePort. On bare metal CKA clusters, the external IP stays <pending> unless MetalLB or similar is configured — that’s expected, and the exam grades the spec, not external reachability.

kubectl expose deploy nginx --port=80 --type=LoadBalancer

Headless Service (less common, but tested)

clusterIP: None — DNS returns pod IPs directly instead of a virtual IP. Used for StatefulSets.

apiVersion: v1
kind: Service
metadata:
  name: db-headless
spec:
  clusterIP: None
  selector:
    app: postgres
  ports:
    - port: 5432

DNS Inside the Cluster

Every Service gets a DNS record at <svc>.<namespace>.svc.cluster.local. Pod-to-service communication uses this name; you almost never use IPs.

# Test resolution from inside a pod
kubectl run tmp --rm -it --image=busybox:1.28 --restart=Never -- \
  nslookup my-svc.dev.svc.cluster.local

# Short forms
# Same namespace: my-svc
# Different namespace: my-svc.dev
# Fully qualified: my-svc.dev.svc.cluster.local

CoreDNS handles this. If DNS fails, it’s almost always:

  • CoreDNS pods crashed (kubectl get pods -n kube-system -l k8s-app=kube-dns)
  • A NetworkPolicy blocking egress from your pod to kube-system:53
  • The CoreDNS configmap was edited and broken

For a full DNS troubleshooting playbook, see our CKA troubleshooting guide.

Endpoints: The Bridge Between Service and Pod

When a Service is created, Kubernetes auto-creates an Endpoints (or EndpointSlice) object listing the matching pod IPs. If the Endpoints object is empty, the Service has no backends.

kubectl get endpoints
kubectl get endpointslices

# Diagnose "service has no endpoints"
kubectl get svc <svc> -o yaml | grep -A 5 selector
kubectl get pods --show-labels

Fix the mismatch: relabel the pods or update the service selector.

Ingress: HTTP Routing Into the Cluster

Ingress provides HTTP/HTTPS routing with hostnames and paths. It needs an ingress controller running in the cluster (NGINX, Traefik, etc.). The CKA usually has one preinstalled.

Basic Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-svc
                port:
                  number: 80
kubectl get ingress
kubectl describe ingress app-ingress

Multi-Path Ingress

spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-svc
                port: { number: 80 }
          - path: /web
            pathType: Prefix
            backend:
              service:
                name: web-svc
                port: { number: 80 }

Ingress with TLS

spec:
  tls:
    - hosts: ["app.example.com"]
      secretName: app-tls
  rules:
    - host: app.example.com
      http: { ... }

The app-tls secret must be of type kubernetes.io/tls:

kubectl create secret tls app-tls --cert=tls.crt --key=tls.key

Gateway API (New on the CKA in 2026)

The Gateway API is replacing Ingress as the standard for L4/L7 routing. The CKA now includes basic Gateway API questions.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: app-gateway
spec:
  gatewayClassName: nginx
  listeners:
    - name: http
      port: 80
      protocol: HTTP
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
spec:
  parentRefs:
    - name: app-gateway
  hostnames:
    - app.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-svc
          port: 80

Three resources work together: GatewayClass → Gateway → HTTPRoute. Practice this on a kind cluster with the Gateway API CRDs installed.

NetworkPolicy: The Other Half of the Domain

NetworkPolicies are firewall rules at the pod level. They’re 100% YAML — no imperative shortcut — so memorize the templates.

Default Deny All Ingress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: dev
spec:
  podSelector: {}
  policyTypes:
    - Ingress

This blocks all incoming traffic to every pod in the dev namespace. Good starting point for “lock down this namespace” questions.

Allow From a Specific Namespace

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-prod
  namespace: dev
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: prod
      ports:
        - protocol: TCP
          port: 80

The kubernetes.io/metadata.name label is automatically applied to every namespace by Kubernetes — use it instead of trying to label namespaces manually.

Allow Egress to DNS Only

spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53

Most “default-deny egress” questions still need DNS to work. Memorize this DNS exception.

Allow From Specific Pods (PodSelector)

spec:
  podSelector:
    matchLabels:
      app: db
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: api
      ports:
        - protocol: TCP
          port: 5432

This says: “Pods labeled app: db accept traffic only from pods labeled app: api in the same namespace, on port 5432.”

NetworkPolicy Combinator Logic (The Trap)

Inside a single from rule, conditions are AND-ed. Across multiple from blocks, conditions are OR-ed.

# This means: from pods that are BOTH in namespace=prod AND labeled app=api
- from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: prod
      podSelector:
        matchLabels:
          app: api

# vs. this: from pods in namespace=prod, OR pods labeled app=api anywhere
- from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: prod
    - podSelector:
        matchLabels:
          app: api

The hyphen (-) makes this a list. Reading the indentation carefully is the difference between right and wrong.

Testing Connectivity

Knowing how to write a NetworkPolicy isn’t enough — you need to verify it works. The CKA grader runs traffic tests behind the scenes.

# From a pod inside the cluster
kubectl run tmp --rm -it --image=busybox --restart=Never -- \
  wget -qO- --timeout=3 http://my-svc.dev.svc.cluster.local

# Test from a specific namespace
kubectl run tmp -n prod --rm -it --image=busybox --restart=Never -- \
  wget -qO- --timeout=3 http://api-svc.dev:80

# nc (netcat) for raw TCP testing
kubectl run tmp --rm -it --image=busybox --restart=Never -- \
  nc -zv api-svc.dev 80

The --timeout=3 flag is essential. Without it, blocked traffic hangs forever.

CNI Awareness (Just Enough to Pass)

The CKA doesn’t test installing a CNI from scratch, but it does test understanding which CNI is in use and where to find its config.

# CNI config files
ls /etc/cni/net.d/

# CNI plugin pods
kubectl get pods -n kube-system | grep -E "calico|flannel|cilium|weave"

# Logs for the CNI agent on a node
kubectl logs -n kube-system <cni-pod-name>

If pods can’t reach each other across nodes, suspect the CNI. If the CNI pods themselves are crashing, look at their logs and the node’s kubelet and containerd logs.

Service Account & Pod Network Identity

A pod’s identity to other pods is its IP and labels. To Services, it’s the labels. To NetworkPolicy, both. To external services, it’s the source IP — usually the node’s IP after SNAT, unless service.spec.externalTrafficPolicy: Local.

This becomes important for NetworkPolicy questions like “allow traffic from pods labeled X” — they target the labels on the source pod, not the destination.

A Networking Question Walkthrough

Here’s an exam-style question and the full solution:

Q: In namespace production, expose the deployment web (containers listen on 8080) on port 80 of a stable cluster-internal address. Then create a NetworkPolicy that allows traffic to web only from pods in namespace monitoring.

Step 1: Switch context and namespace.

kubectl config use-context cka-prod
kubectl config set-context --current --namespace=production

Step 2: Expose the deployment.

kubectl expose deploy web --port=80 --target-port=8080

Step 3: Verify.

kubectl get svc web
kubectl get endpoints web    # must list pod IPs

Step 4: Create the NetworkPolicy.

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-from-monitoring
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
EOF

Step 5: Test (this is the part most candidates skip).

# Should succeed
kubectl run tmp -n monitoring --rm -it --image=busybox --restart=Never -- \
  wget -qO- --timeout=3 http://web.production:80

# Should fail
kubectl run tmp -n default --rm -it --image=busybox --restart=Never -- \
  wget -qO- --timeout=3 http://web.production:80

This entire question takes 4 minutes if you’ve drilled the YAML templates.

How to Practice Networking

  1. Build a kubeadm cluster with Calico or Cilium (CNIs that fully support NetworkPolicy).
  2. Deploy three apps in three namespaces (frontend, backend, db).
  3. Practice these scenarios:
    • Expose each as ClusterIP, then NodePort.
    • Add an Ingress for the frontend.
    • Add a default-deny-ingress NetworkPolicy in db.
    • Layer on allow rules until frontend → backend → db works.
    • Verify each step with wget from a busybox pod.

If you can do all that in under 30 minutes, networking won’t be the domain that fails you.

Validate Your Networking Skills Under Exam Conditions

Building scenarios in your own lab is necessary, but the CKA tests speed under pressure with unfamiliar cluster configurations. Take a scored, exam-realistic networking simulator with our CKA Mock Exam Bundle to see how fast you can finish a NetworkPolicy + Service + Ingress task chain. The number on the result page is the one that predicts whether you pass on exam day.

Frequently Asked Questions

Q: Do I need to install a CNI on the exam? A: No, the cluster comes pre-installed with one. You may need to know which one is in use to debug it.

Q: How many networking questions appear on the CKA? A: Typically 3-5 questions covering Services, Ingress, and NetworkPolicy. Roughly 20% of the score.

Q: Is the Gateway API tested? A: As of 2026, yes — basic Gateway and HTTPRoute questions appear occasionally. Practice the basics.

Q: What’s the difference between port and targetPort on a Service? A: port is what the Service exposes; targetPort is the port on the pod. They’re often the same but don’t have to be.

Q: How do I know if a NetworkPolicy is taking effect? A: Test from a busybox pod with wget --timeout=3. NetworkPolicy is denied by silently dropping packets, so without a timeout, your test hangs.

Q: What if the cluster CNI doesn’t enforce NetworkPolicy? A: kubeadm clusters with Flannel don’t enforce NetworkPolicy by default. The CKA always uses a CNI that does (Calico or Cilium). If your lab cluster doesn’t, switch CNIs for practice.

Q: How do I expose a service externally without LoadBalancer? A: Use NodePort. The exam grades the spec, not external reachability — <pending> for LoadBalancer external IP is normal on bare metal.

Ready to put your networking skills to the test? Take a full-length scored simulator with our CKA Mock Exam Bundle and find out exactly where you’d score today.

Limited Time Offer: Get 80% off all Mock Exam Bundles | Sale ends in 7 days. Start learning today.

Claim Now