Lesson 11 Ingress + cert-manager + DNS
Theme:
Lesson 11 · Slide 1

Lesson 11 — Ingress + cert-manager + DNS

From port-forward to a real domain with TLS in 15 minutes.

Cloud DevOps Module 4 Ingress TLS
Lesson 11 · Slide 2

Where we left off

L10 chart state

L10 chart has ingress.enabled: false; we access via port-forward.

Today’s goal

We flip the bit. Ingress controller + cert-manager + ExternalDNS = real hostname + HTTPS, with DNS records the cluster manages itself.

Lesson 11 · Slide 3

The three moving parts

Lesson 11 · Slide 4

Ingress resource shape

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shortener
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-staging
    external-dns.alpha.kubernetes.io/hostname: shortener.example.com
spec:
  ingressClassName: nginx
  tls:
    - hosts: [shortener.example.com]
      secretName: shortener-tls
  rules:
    - host: shortener.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service: {name: shortener-api, port: {number: 80}}

Annotations wire cert-manager + ExternalDNS to the same resource; the controller handles the rest.

Lesson 11 · Slide 5

Installing ingress-nginx

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx --create-namespace \
  --set controller.publishService.enabled=true

A Service of type LoadBalancer is created — on EKS/GKE/AKS this provisions a cloud LB; on kind you use the kind-specific shim (see slide 11).

Lesson 11 · Slide 6

Installing cert-manager

helm repo add jetstack https://charts.jetstack.io
helm upgrade --install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --set crds.enabled=true

CRDs install with the chart now (used to be a separate step); Issuer / ClusterIssuer / Certificate resources become available cluster-wide.

Lesson 11 · Slide 7

ClusterIssuer for Let’s Encrypt staging

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata: {name: letsencrypt-staging}
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef: {name: letsencrypt-staging-key}
    solvers:
      - http01:
          ingress: {class: nginx}

Always start with staging. Let’s Encrypt rate-limits production hard; you’ll get blocked by misconfigurations.

Lesson 11 · Slide 8

Cert lifecycle

You write tls: on the Ingress + the cert-manager.io/cluster-issuer annotation. cert-manager sees the Ingress, creates a Certificate resource, the Certificate controller runs the ACME http-01 challenge through ingress-nginx, stores the cert in a Secret named per secretName, and ingress-nginx serves it. Cert renewal is automatic.

Lesson 11 · Slide 9

ExternalDNS

# Helm values for ExternalDNS targeting Cloudflare:
provider: cloudflare
cloudflare:
  apiToken: REPLACE_ME      # from a Secret in real installs
sources: [ingress]
policy: sync
domainFilters: ["example.com"]

ExternalDNS watches Ingress hosts and writes A/CNAME records at your DNS provider — no manual DNS edits.

Lesson 11 · Slide 10

The 15-minute path

  1. Install ingress-nginx.
  2. Install cert-manager + ClusterIssuer (staging).
  3. Install ExternalDNS.
  4. Flip the chart’s ingress.enabled: true with host: shortener.<your-domain>.
  5. helm upgrade --install.
  6. Wait for cert-manager to report Ready.
  7. Visit https://shortener.<your-domain> — the browser warns (“staging issuer”) but TLS works.
Lesson 11 · Slide 11

Local-only: kind + cloud-provider-kind

go install sigs.k8s.io/cloud-provider-kind@latest
sudo cloud-provider-kind &

cloud-provider-kind gives the LoadBalancer Service an IP on the host loopback so you can curl ingress-nginx locally. ExternalDNS won’t make sense locally (no real DNS) — for the lab we either skip ExternalDNS on kind or use a 127.0.0.1 host with /etc/hosts.

Lesson 11 · Slide 12

Promoting from staging to prod issuer

Once staging works end-to-end, copy the ClusterIssuer to letsencrypt-prod (swap the server URL) and switch the Ingress annotation to letsencrypt-prod. Delete the old staging cert Secret; cert-manager re-issues from prod within ~60 seconds.

Lesson 11 · Slide 13

Recap & what’s next

Coming up: Module 5 — observability, autoscaling, GitOps.
1 / ?