In another installment of stupid Kubernetes routing tricks I bring you the following problem:
- I’m have a website running on webflow. Which for some reason still doesn’t support hosting .well-known routes. It turns out, we really need those.
- I have most the rest of my subdomains in Kubernetes.
So I figured the thing to do is to just use Kubernetes as a reverse proxy to send traffic to Webflow. So that’s what I did. I broke this up into two different sections. First, let’s tackle the webflow issue. This will reverse proxy into our site:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_ssl_name www.example.com;
proxy_ssl_server_name on;
name: proxy-example-com
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: proxy-example-com
port:
number: 443
path: /
pathType: Prefix
tls:
- hosts:
- example.com
secretName: proxy-example-com
---
apiVersion: v1
kind: Service
metadata:
name: proxy-example-com
spec:
type: ExternalName
externalName: proxy-ssl-geo.webflow.com
A few things:
- We have to forward HTTPS and port 433.
- The webflow recommendation is that you use the www subdomain as primary.
Checking this out and modifying our routing to point to our ingress controller load balancer it redirects to our website. During my trial and error of this I’m sad to report I took down our corporate website for 5 minutes.
Now we can create some other manifests for our .well-known site. We just create another ingress rule that is specific to the path
apiVersion: v1
kind: ConfigMap
metadata:
name: example-com-config
data:
com.tesla.3p.public-key.pem: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAED43wf2LN+adRW5Tv4KpwotH1g8S5
Jj02Tzb+u/lgktlEFWreI1gNCn3Ivi97ziVnYNfg5sEPfO1MNqv5BWrvvg==
-----END PUBLIC KEY-----
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-com
spec:
replicas: 1
selector:
matchLabels:
app: example-com
template:
metadata:
labels:
app: example-com
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: example-com-volume
mountPath: /usr/share/nginx/html/.well-known/appspecific/
volumes:
- name: example-com-volume
configMap:
name: example-com-config
---
apiVersion: v1
kind: Service
metadata:
name: example-com
spec:
selector:
app: example-com
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-com-well-known
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: "/.well-known/appspecific/"
pathType: ImplementationSpecific
backend:
service:
name: example-com
port:
number: 80
tls:
- hosts:
- example.com
secretName: example-com-tls
Cool. Now this later part lets us host a .well-known/appspecific/com.tesla.3p.public-key.pem. This can be used for any other .well-known file that is needed to be hosted.