CKA Networking Master Reference Link to heading

Domain 3 — Services and Networking Link to heading

DNS Link to heading

# Short form works everywhere inside cluster
<service>.<namespace>

# Full FQDN — never needed on exam
<service>.<namespace>.svc.cluster.local

# Examples
backend.data        # service "backend" in namespace "data"
store.cache         # service "store" in namespace "cache"
agent.receiver      # service "agent" in namespace "receiver"

curl Testing Patterns Link to heading

# Basic connectivity test (-s silent, -m timeout)
k -n <ns> exec deploy/<name> -- curl -s -m 2 <service>.<namespace>

# Should timeout (blocked)
k -n app exec deploy/proxy -- curl -s -m 2 api.app

# HTTPS with self-signed cert
curl -k https://$IP               # -k skips cert verification
curl -k -v https://$IP            # -v shows TLS details (goes to stderr)
curl -k -v https://$IP 2>&1       # redirect stderr to stdout for piping

# Get ClusterIP
IP=$(k -n <ns> get svc <name> -o jsonpath='{.spec.clusterIP}')

# Get LoadBalancer external IP
IP=$(k -n <ns> get svc <name> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Test distribution (canary)
for i in $(seq 1 20); do curl -s http://imagine.app:30080/web; done

flags: -s = silent (no progress), -m 2 = 2 second timeout, -k = skip TLS verify


NetworkPolicy Link to heading

Default Deny (ingress) Link to heading

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

Same-Namespace Allow Link to heading

spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: proxy
    ports:
    - port: 80

Cross-Namespace Allow (AND logic) Link to heading

ingress:
- from:
  - namespaceSelector:
      matchLabels:
        kubernetes.io/metadata.name: app
    podSelector:
      matchLabels:
        app: api
  ports:
  - port: 80

OR Logic (two separate sources) Link to heading

ingress:
- from:
  - namespaceSelector:
      matchLabels:
        kubernetes.io/metadata.name: metrics
  - podSelector:
      matchLabels:
        role: monitoring

AND vs OR — Critical Rule Link to heading

YAMLLogicMeaning
Same - entry (no dash before second selector)ANDPod must match BOTH
Separate - entriesORPod matches EITHER

Namespace label: kubernetes.io/metadata.name: <ns> — auto-applied since K8s 1.21

Troubleshooting NetPol Link to heading

k get netpol -n <ns> -o yaml          # inspect policy
k describe netpol <name> -n <ns>      # human-readable
# Compare from.podSelector.matchLabels against actual pod labels
# Common issues: label typo, AND vs OR mismatch

Services Link to heading

NodePort → LoadBalancer (no NodePort assigned) Link to heading

k edit svc <name> -n <ns>
spec:
  type: LoadBalancer
  allocateLoadBalancerNodePorts: false
  ports:
  - port: 80
    targetPort: 80
k -n <ns> get svc <name> -w    # wait for external IP

Gateway API Link to heading

apiVersion Link to heading

gateway.networking.k8s.io/v1

Gateway Resource Link to heading

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: main
  namespace: traffic
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: imagine.app

HTTPRoute — Path-Based Routing Link to heading

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: apps
  namespace: traffic
spec:
  parentRefs:
  - name: main
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: api
      port: 8080
  - matches:
    - path:
        type: PathPrefix
        value: /admin
    backendRefs:
    - name: admin
      port: 7777

HTTPRoute — Canary (Weighted Traffic Split) Link to heading

rules:
- matches:
  - path:
      type: PathPrefix
      value: /web
  backendRefs:
  - name: web-v1
    port: 80
    weight: 90
  - name: web-v2
    port: 80
    weight: 10

Trap: parentRefs required — without it route attaches to nothing Trap: namespace required in metadata — missing causes route to deploy to wrong ns Trap: One matches, one backendRefs for canary — don’t duplicate the block


CoreDNS Link to heading

# CoreDNS crashing
k -n kube-system logs deploy/coredns       # find bad directive
k -n kube-system edit cm coredns           # fix Corefile
k -n kube-system rollout restart deploy coredns

# Pods don't reload CM automatically — must rollout restart

# Set env var for cross-namespace DNS
k -n sender set env deploy client TARGET_URL=agent.receiver

TLS Secrets Link to heading

Generate Self-Signed Cert (memorize this) Link to heading

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout tls.key -out tls.crt \
  -subj "/CN=shield.local"
  • -x509 = self-signed (not a CSR)
  • -nodes = no passphrase
  • One command produces both files

Create TLS Secret Link to heading

k create secret tls <name> --cert=tls.crt --key=tls.key -n <ns>

CSR Workflow (user cert — different from above) Link to heading

openssl genrsa -out user.key 2048
openssl req -new -key user.key -out user.csr -subj "/CN=username"

Enforce TLS Version (nginx ConfigMap) Link to heading

k edit cm <nginx-cm> -n <ns>    # change ssl_protocols TLSv1.3;
k rollout restart deploy <name> -n <ns>

# Test
IP=$(k -n <ns> get svc <name> -o jsonpath='{.spec.clusterIP}')
curl -k --tlsv1.3 https://$IP      # should work
curl -k --tlsv1.2 --tls-max 1.2 https://$IP   # should fail

Note: -v output goes to stderr → use 2>&1 to pipe/redirect it