Lesson 11 Ingress + cert-manager + DNS
Theme:

Homework 11 — Ingress + cert-manager + DNS

Lesson 11 · Cloud Infrastructure & DevOps · Three tasks

These three tasks deepen the Ingress + cert-manager foundation from the lab. Task 1 is chart-level (rate limiting), Task 2 introduces dns-01 and wildcard certs, and Task 3 covers the multi-app sharing pattern. You will need a working Ingress controller and cert-manager installation from the lab.

Task 1 — Add rate-limit annotations to the Ingress

ingress-nginx supports per-IP rate limiting via the nginx.ingress.kubernetes.io/limit-rps annotation. Add this feature to the chart so the rate limit is controlled by a values key rather than hardcoded in the template.

  1. Add two new values keys to values.yaml:
    • ingress.rateLimitRps (integer, default 0) — requests per second per source IP. Value 0 means disabled (no annotation rendered).
    • ingress.rateLimitBurst (integer, default 0) — burst multiplier. Value 0 falls back to the nginx default of 5.
  2. Update templates/ingress.yaml to conditionally add the annotations when rateLimitRps > 0:
    • nginx.ingress.kubernetes.io/limit-rps: "<value>"
    • nginx.ingress.kubernetes.io/limit-burst-multiplier: "<value>"
  3. Verify the template renders correctly: helm template ... --set ingress.enabled=true --set ingress.host=test.example.com --set ingress.rateLimitRps=5 should show both annotations. With rateLimitRps=0 (the default), neither annotation should appear.
  4. If you have a running cluster, load-test with hey -z 30s -c 50 -q 100 https://shortener.<host>/healthz and confirm 429 responses appear beyond the configured RPS.

✓ Self-check: helm template ... --set ingress.rateLimitRps=5 renders both annotations. helm template ... --set ingress.rateLimitRps=0 renders neither. helm lint passes.

Task 2 — Wildcard cert via dns-01

http-01 challenges cannot validate wildcard certificates (*.example.com) because there is no single host to serve the challenge file from. dns-01 is required for wildcards — cert-manager places a TXT record at _acme-challenge.example.com instead of serving a file.

  1. Write a ClusterIssuer that uses the Cloudflare dns-01 solver. Store the Cloudflare API token in a Kubernetes Secret:
    kubectl create secret generic cloudflare-api-token \
      --from-literal=token=<your-token> \
      -n cert-manager
  2. Write a standalone Certificate resource (not inferred from an Ingress) that requests *.example.com and example.com as dnsNames, references the dns-01 ClusterIssuer, and stores the result in Secret example-com-wildcard-tls. Place this in the shortener namespace.
  3. In 3–4 sentences, explain: why is dns-01 required for wildcards? What is the trade-off compared to http-01?

✓ Self-check: kubectl get certificate -n shortener shows the wildcard cert as Ready: True. kubectl describe secret example-com-wildcard-tls -n shortener lists a SAN of *.example.com.

Task 3 — A second app sharing the same Ingress controller

A key Ingress controller property is that it is cluster-wide: one controller (and one LoadBalancer) serves every app, with routing by HTTP Host header. This task adds a second app, greeter, in its own namespace, sharing the same ingress-nginx controller and the same ClusterIssuer.

  1. Create a namespace greeter and deploy a simple Hello-World Service (nginx:alpine or hashicorp/http-echo is fine — the routing, not the app, is the point).
  2. Write an Ingress resource in namespace greeter that:
    • Uses ingressClassName: nginx.
    • Routes greeter.example.com to the greeter Service on port 80.
    • Requests a TLS cert from letsencrypt-prod (or letsencrypt-staging for testing) via the cert-manager.io/cluster-issuer annotation.
    • Stores the cert in Secret greeter-tls in namespace greeter.
  3. In 4 sentences, document the cluster-wide vs per-namespace boundary: which resources are cluster-wide and which are namespaced? Can shortener’s TLS Secret be used by greeter? What is the standard pattern if you want to share a wildcard cert across namespaces?

✓ Self-check: both apps’ Ingresses show ADDRESS set; both Certificates are Ready: True in their own namespaces; curl -H "Host: greeter.example.com" http://<LB-IP> routes to the greeter service.

View solutions →