Setting up reverse proxies on nginx ingress controller on Kubernetes

In another installment of stupid Kubernetes routing tricks I bring you the following problem:

  1. 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.
  2. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *