Have you ever wanted to have proper SSL traffic with an ingress controller? Did you want your ingress controller also managing certificates? Do you wish you could also hand the SSL cert that’s being auto-regenerated to the app in the container? Are you running Traefik in Kubernetes (unlike literally everyone else)?

Great! It’s quite easy. For this episode, we’re gonna assume that you’ve got cert-manager installed, and configured, as well as a ClusterIssuer configured. Additionally, we’ll assume you’re using Traefik 2.x+, and your k8s cluster is healthy, and that you own the domain you’re using the cert for.

Since you’re on this site, I’ll probably end up mostly talking about how this site, and it’s subdomains are set up. As long as I don’t leak anything secret, it’ll be good to have more eyes on how I’m doing this!

Cert:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: hugo-cert-local
  namespace: hugo
  annotations:
    cert-manager.io/cluster-issuer: ssl-prod
spec:
  # Secret names are always required.
  secretName: hugo-ssl-local
  renewBefore: 360h # 15d
  # At least one of a DNS Name, URI, or IP address is required.
  dnsNames:
    - dragonfruit.dev
    - www.dragonfruit.dev
  # Issuer references are always required.
  issuerRef:
    name: ssl-prod
    # We can reference ClusterIssuers by changing the kind here.
    # The default value is Issuer (i.e. a locally namespaced Issuer)
    kind: ClusterIssuer

IngressRoute (cause I use Traefik):

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: hugo-local
  namespace: hugo
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`dragonfruit.dev`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: hugo
      port: 3001
  tls:
    secretName: hugo-ssl-local

Service:

apiVersion: v1
kind: Service
metadata:
  name: hugo
  namespace: hugo
spec:
  ports:
  - name: http
    port: 3001
    targetPort: 3001
  selector:
    app: hugo

So obviously, I use Hugo. I have a deployment set up with 3 replicas, pointing to the pod that has my hugo server built into it. This is awful and bad and I’m actively working on a way to solve it, but here we are in the here and now. The hugo container exposes 3001, and listens on 0.0.0.0. Additionally, it’s been configured to not add the port number on to the end of the ingress. The Traefik controller handles the SSL configuration, as well as the middleware to enforce https instead of http. The certificate is set up and configured to use ZeroSSL, and writes in the TLS crt/key into the TLS secret mentioned.

So now here’s what we’ve got:

  • 3 pod deployment of a built hugo server
  • Service with a selector pointing at the pods
  • IngressRoute pointing at the service
  • Certificate for IngressRoute to serve TLS

Last but not least is DNS. For that, I’m doing a bad thing. My dns is set to point *.dragonfruit.dev at dragonfruit.dev, and dragonfruit.dev to point at the IP of my hosting server. So as I add subdomains, they automatically point at where the compute is going to be hosted anyway.

Next time I’ll probably go over some of my compute, and what everything here is running on, but for now, that’s how this site is running while in the cluster!

See ya next time!