CKAD — Ingress & Network Policies Lab

3 minute read

Lab 1: Ingress Routing

# Create two deployments and services
kubectl create deployment web --image=nginx:1.27
kubectl expose deployment web --port=80

kubectl create deployment api --image=httpd:2.4
kubectl expose deployment api --port=80

# Create an Ingress with path-based routing
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 80
EOF

kubectl get ingress app-ingress
kubectl describe ingress app-ingress

Lab 2: Network Policies

# Create test Pods
kubectl run web --image=nginx:1.27 --labels=app=web --port=80
kubectl run api --image=busybox:1.36 --labels=app=api -- sleep 3600
kubectl run blocked --image=busybox:1.36 --labels=app=blocked -- sleep 3600

# Expose the web Pod
kubectl expose pod web --port=80

# Test: both can reach web initially
kubectl exec api -- wget -qO- --timeout=3 http://web
kubectl exec blocked -- wget -qO- --timeout=3 http://web
# Both should succeed

# Apply Network Policy: only allow api -> web
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-allow-api
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api
    ports:
    - protocol: TCP
      port: 80
EOF

# Test again
kubectl exec api -- wget -qO- --timeout=3 http://web
# Expected: Success

kubectl exec blocked -- wget -qO- --timeout=3 http://web
# Expected: Timeout — blocked by NetworkPolicy

Practice Questions

Q1: Create an Ingress that routes api.example.com to a Service named api-svc on port 8080 and web.example.com to web-svc on port 80.

Show Answer ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: host-ingress spec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-svc port: number: 8080 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-svc port: number: 80 ``` Or imperatively: ```bash kubectl create ingress host-ingress \ --class=nginx \ --rule="api.example.com/*=api-svc:8080" \ --rule="web.example.com/*=web-svc:80" ```

Q2: Create a NetworkPolicy that denies all ingress traffic to Pods labeled app=db except from Pods labeled app=api on port 5432.

Show Answer ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: db-allow-api spec: podSelector: matchLabels: app: db policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: api ports: - protocol: TCP port: 5432 ``` This policy: - Selects Pods with `app=db` - Declares Ingress policy type (denies all ingress by default) - Allows ingress only from `app=api` Pods on TCP port 5432

Q3: What is the difference between these two Network Policy snippets?

Snippet A:

- from:
  - namespaceSelector:
      matchLabels:
        env: prod
    podSelector:
      matchLabels:
        app: web

Snippet B:

- from:
  - namespaceSelector:
      matchLabels:
        env: prod
  - podSelector:
      matchLabels:
        app: web
Show Answer **Snippet A (AND):** Allow traffic from Pods that are labeled `app=web` AND are in namespaces labeled `env=prod`. Both conditions must be true. **Snippet B (OR):** Allow traffic from: - Any Pod in namespaces labeled `env=prod`, OR - Pods labeled `app=web` in the current namespace The key difference is the YAML structure: - Same list item (no `-` before `podSelector`) = AND - Separate list items (`-` before both selectors) = OR

Q4: Add TLS to an Ingress for app.example.com using a Secret named app-tls-cert.

Show Answer ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-app spec: ingressClassName: nginx tls: - hosts: - app.example.com secretName: app-tls-cert rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: app-svc port: number: 80 ``` The Secret must be of type `kubernetes.io/tls` containing `tls.crt` and `tls.key`: ```bash kubectl create secret tls app-tls-cert --cert=tls.crt --key=tls.key ```

Q5: Create a default deny-all Network Policy for both ingress and egress in the production namespace.

Show Answer ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: production spec: podSelector: {} policyTypes: - Ingress - Egress ``` This selects all Pods in the `production` namespace (`podSelector: {}`) and declares both Ingress and Egress policy types with no rules — meaning all traffic is denied. You would then create additional policies to allow specific traffic flows.

← Previous: Services & Networking Next: Exam Tips & Mock Exam →

Updated: