Expose Service In Your Baremetal without Public IP in Kubernetes with Cloudflare Tunnel

March 04, 2024

Expose Service In Your Baremetal without Public IP in Kubernetes with Cloudflare Tunnel

Thumbnail: "Indonesian Students in Prague, Czech Republic During the Graduation of One of Their Friends in 1968. Photo from Soegeng Soejono's Archive." - Gestapu Menghapus Satu Generasi Intelektual Indonesia


So if we are hosting our own Kubernetes, one of problem is expose your service, how to do that? NodePort? Loadbalancer, or what?. This problem is make metallb.universe.tf born.

But even white these tools, we still need to have deal with IPs pools, route, etc. It's good if when you need it, but what if your goals is just get ingress-nginx, and point your DNS to IP from cloudflare, and enable Cloudflare Proxy? then this is the right blog post for you. You can just utilize Cloudflare Tunnel.

Lets get into the details.

What is Cloudflare Tunnel

Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address. With Tunnel, you do not send traffic to an external IP — instead, a lightweight daemon in your infrastructure (‘cloudflared’) creates outbound-only connections to Cloudflare’s global network.

This way, your origins can serve traffic through Cloudflare without being vulnerable to attacks that bypass Cloudflare.

How it works

Let's just set it up!

1. Get your cloudflare tunnel token

Login to your cloudflare accout, navigate to one.dash.cloudflare.com, follow these guide get-started - cloudflare tunnel

2. Create a daemonset in your Kubernetes

Put your token value inside TUNNEL_TOKEN key, and then you ready to deploy it.

---
apiVersion: v1
stringData:
  TUNNEL_TOKEN: eyJhXXXXxXXxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXTM3OWJXXXXXXxxxxXXXXXxxxxxxxXXXXXXXXXXXXXXXXFNCJ9
kind: Secret
metadata:
  name: cf-tunel-production
  namespace: cloudflared
type: Opaque
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: cloudflared
  name: cloudflared-daemonset
  namespace: cloudflared
spec:
  selector:
    matchLabels:
      pod: cloudflared
  template:
    metadata:
      labels:
        pod: cloudflared
    spec:
      containers:
        - command:
            - cloudflared
            - tunnel
            - --metrics
            - 0.0.0.0:2000
            - run
          image: cloudflare/cloudflared:latest
          env:
            - name: NO_AUTOUPDATE
              value: "true"
          envFrom:
            - secretRef:
                name: cf-tunel-production
          imagePullPolicy: Always
          livenessProbe:
            failureThreshold: 1
            httpGet:
              path: /ready
              port: 2000
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          name: cloudflared
kubectl create ns cloudflared
kubectl create -f deployment-cloudflare-tunnel.yaml # above yaml files.

3. Point your service

Let's say you wanna expose the Ingress-Nginx, so you can just point everything at the same tunnel.

Leave subdomain blank

Point tunnel to ingress nginx

Also if your goals is just make HTTPS from user to your site, then just ignore the verify so you dont have to deal with Failed termination or ininitfy loops.

To edit, just click on "Additional application settings"

Ignore verify cert

4. Lets try expose an app

This is example of my apps running in kubernetes withs service name nginx-test-expose

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
spec:
  ingressClassName: nginx
  rules:
  - host: "not-actual-my-domain.io"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-test-expose
            port:
              number: 8080
  tls:
  - hosts:
    - not-actual-my-domain.io

Final, results Example App in Main TLD Domain, with Cloudflare Tunnel

Pros and Cons

If you want to implement this architecture, you have to consider did your egress traffic is free? if yes, the you are lucky. If not you should consire just using Public IP just like usual. Cause traffic cost is very scary!

The pros is you have your simple apps easy quck behind cloudflare, anti DDOS, etc. But the cons is you are depens on cloudflare Proxy (But is actualy the same like you are using cloudflare with Proxied).

The choice is yours!


Profile picture

Written by Nicolas Julian Seseorang yang mencoba berkarya. Chit Chat with me in Twitter