Exposing our application to the internet
The linkding app is now running on our cluster, but in order to make it useful it would be good to expose it to the internet.
It would be better, from a security point of view, not to have to open any ports to the internet.
Cloudflare offers a nice free solution (if you host a domain with them) called Cloudflare tunnels.
They work by opening a connection from the client (application end) to Cloudflare, that stays open and allows traffic to route from Cloudflare to your network - after you setup a CNAME record.
First we need to install and configure the cloudflared app.
pacman -S cloudflared
cloudflared tunnel login
We then need to create a tunnel named ldpi.
# will createe a json file /home/matt/.cloudflared
cloudflared tunnel create ldpi
We then use the generated file to create a secret in K3S.
kubectl create secret generic tunnel-credentials \
--from-file=credentials.json=58c97568-9eda-4dbf-9857-b6cf9cf91259.json
Using the application id in the json file we need to add a CNAME record to Cloudflare (with proxying)
# The CNAME needs to point to this record (our cname is links)
58c97568-9eda-4dbf-0857-b6cf9cf91259.cfargotunnel.com
We now need to add a kubernetes service that will be configured to point to our deployment.
# in service.yaml (base layer of linkding)
# and edit kustomization file!
apiVersion: v1
kind: Service
metadata:
name: linkding
spec:
ports:
- port: 9090
selector:
app: linkding
type: ClusterIP
We then create a new deployment that will run the cloudflared image and make the initial call to Cloudflare to setup the tunnel.
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloudflared
spec:
selector:
matchLabels:
app: cloudflared
replicas: 2
template:
metadata:
labels:
app: cloudflared
spec:
containers:
- name: cloudflared
image: cloudflare/cloudflared:latest
args:
- tunnel
- --config
- /etc/cloudflared/config/config.yaml
- run
livenessProbe:
httpGet:
path: /ready
port: 2000
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /etc/cloudflared/config
readOnly: true
- name: creds
mountPath: /etc/cloudflared/creds
readOnly: true
volumes:
- name: creds
secret:
secretName: tunnel-credentials
- name: config
configMap:
name: cloudflared
items:
- key: config.yaml
path: config.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cloudflared
data:
config.yaml: |
tunnel: ldpi
credentials-file: /etc/cloudflared/creds/credentials.json
ingress:
- hostname: links.mattbritt.com
service: http://linkding:9090
When we push these changes to our repo, Flux will provision and setup the tunnel, we are live!