I recently posted about my experience with k3s and how I’m now using it to run my blog. I also mentioned my blog’s new domain and how I’m keeping the old name working. That involved changing the Ingress resource for my blog, so I’ll show how I updated it to accept the old domains and automatically redirect to my preferred domain without needing to make WordPress itself do any redirecting.
The Ingress Controller installed by default by k3s (at least for now) is Traefik. It supports a couple of interesting features, including the ability to automatically redirect based on URL regular expressions via just two annotations. These annotations aren’t documented particularly well but I was able to figure them out through some trial and error. First, let me lay out my goals:
- Redirect requests for these domains to my preferred domain (therubyist.org):
- www.therubyist.org
- blog.gnagy.info
- gnagy.info
- Make the above redirection happen before WordPress is involved
- Ensure that HTTPS still works and is forced
- Also before WordPress itself is involved
- This redirect should be permanent (meaning an HTTP 301)
Given the above goals, the end result really was modifying the Ingress resource in my previous post from this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: blog
namespace: blog
labels:
app.kubernetes.io/name: blog
app.kubernetes.io/part-of: blog
app.kubernetes.io/component: blog-ingress
annotations:
# Forces HTTPS
ingress.kubernetes.io/ssl-redirect: "true"
# Uses the right ingress class
kubernetes.io/ingress.class: "traefik"
# Tells this Ingress to issue a cert via our ClusterIssuer
cert-manager.io/cluster-issuer: letsencrypt
# Uses "http01" for ACME provisioning via Let's Encrypt
cert-manager.io/acme-challenge-type: http01
spec:
rules:
- host: blog.gnagy.info
http:
paths:
- backend:
serviceName: blog
servicePort: www
tls:
- hosts:
- blog.gnagy.info
secretName: blog-tls
To this, which includes the required changes:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: blog
namespace: blog
labels:
app.kubernetes.io/name: blog
app.kubernetes.io/part-of: blog
app.kubernetes.io/component: blog-ingress
annotations:
# Forces HTTPS
ingress.kubernetes.io/ssl-redirect: "true"
# Forces a Permanent (301) redirect
ingress.kubernetes.io/redirect-permanent: "true"
# Specifies a regex for which URLs to redirect
ingress.kubernetes.io/redirect-regex: "^https://(www.therubyist.org|(blog.)?gnagy.info)/?(.*)"
# Here is where redirected URLs will end up
# Notice the $3, which is the third capture
# group from the above regex
ingress.kubernetes.io/redirect-replacement: "https://therubyist.org/$3"
# Uses the right ingress class
kubernetes.io/ingress.class: "traefik"
# Tells this Ingress to issue a cert via our ClusterIssuer
cert-manager.io/cluster-issuer: letsencrypt
# Uses "http01" for ACME provisioning via Let's Encrypt
cert-manager.io/acme-challenge-type: http01
spec:
# All four rules point to the same service
rules:
- host: blog.gnagy.info
http:
paths:
- backend:
serviceName: blog
servicePort: www
- host: gnagy.info
http:
paths:
- backend:
serviceName: blog
servicePort: www
- host: www.therubyist.org
http:
paths:
- backend:
serviceName: blog
servicePort: www
- host: therubyist.org
http:
paths:
- backend:
serviceName: blog
servicePort: www
# Notice how TLS now includes the additional domains
tls:
- hosts:
- blog.gnagy.info
- gnagy.info
- therubyist.org
- www.therubyist.org
secretName: blog-tls
The above changes amount to three additional annotations, one to specify a permanent redirect and the other two decide what to redirect and where it is redirected. Beyond that, I needed to inform the ingress itself that it is responsible for the additional domains (the rules portion of the spec) as well as updating tls.hosts to include the additional names (so Let’s Encrypt via cert-manager can do its thing).
Of course, this required that I did the prework of pointing those domains at my server ahead of time, but this wasn’t a problem.
If the above is still called blog-ingress.yaml, save it and run:
kubectl apply -f blog-ingress.yaml
Once things are done applying, the redirects should be all set.
