TLDR; This project simplifies exposing Kubernetes services to the internet easily and securely using Cloudflare Tunnel.
To use the Cloudflare Tunnel Ingress Controller, you need to have a Cloudflare account and a domain configured on Cloudflare. You also need to create a Cloudflare API token with the following permissions: Zone:Zone:Read
, Zone:DNS:Edit
, and Account:Cloudflare Tunnel:Edit
.
Additionally, you need to fetch the Account ID from the Cloudflare dashboard.
Finally, you need to have a Kubernetes cluster with public Internet access.
Take a look on this video to see how smoothly and easily it works:
Want to DIY? The following instructions would help your bootstrap a minikube Kubernetes Cluster, then expose the Kubernetes Dashboard to the internet via Cloudflare Tunnel Ingress Controller.
- You should have a Cloudflare account and a domain configured on Cloudflare.
- Create a Cloudflare API token with the following:
Zone:Zone:Read
Zone:DNS:Edit
Account:Cloudflare Tunnel:Edit
- Fetch the Account ID from the Cloudflare dashboard, follow the instructions here.
- Bootstrap a minikube cluster
minikube start
- Add Helm Repository;
helm repo add strrl.dev https://helm.strrl.dev
helm repo update
- Install with Helm:
helm upgrade --install --wait \
-n cloudflare-tunnel-ingress-controller --create-namespace \
cloudflare-tunnel-ingress-controller \
strrl.dev/cloudflare-tunnel-ingress-controller \
--set=cloudflare.apiToken="<cloudflare-api-token>",cloudflare.accountId="<cloudflare-account-id>",cloudflare.tunnelName="<your-favorite-tunnel-name>"
if the tunnel does not exist, controller will create it for you.
- Then enable some awesome features in minikube, like kubernetes-dashboard:
minikube addons enable dashboard
minikube addons enable metrics-server
- Then expose the dashboard to the internet by creating an
Ingress
:
kubectl -n kubernetes-dashboard \
create ingress dashboard-via-cf-tunnel \
--rule="<your-favorite-domain>/*=kubernetes-dashboard:80"\
--class cloudflare-tunnel
for example, I would use
dash.strrl.cloud
as my favorite domain here.
- At last, access the dashboard via the domain you just created:
- Done! Enjoy! π
There is also an awesome project which could integrate with Cloudflare Tunnel as CRD, check it out adyanth/cloudflare-operator!
Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request. To speed up local development and testing, you can use Act to run GitHub Actions workflows locally. For example, to run unit tests using the same workflow as CI:
act -W .github/workflows/unit-test.yaml
You can view all available workflows here.
To run the project locally, Skaffold is integrated into the Makefile. First, install Skaffold by following the instructions at skaffold.dev.
Then, start the development environment with:
skaffold dev
Important: The controller pod expects a Kubernetes
Secret
namedcloudflare-api
with credentials to authenticate with Cloudflare. If this secret is not present, the pod will fail with:CreateContainerConfigError: secret "cloudflare-api" not found
.
There are two ways to provide the required secret:
-
Manually create it with kubectl:
kubectl create secret generic cloudflare-api \ -n cloudflare-tunnel-ingress-controller-dev \ --from-literal=api-token='your_api_token' \ --from-literal=cloudflare-account-id='your_account_id' \ --from-literal=cloudflare-tunnel-name='your_tunnel_name'
-
(Recommended for local development) Copy the example file
hack/dev/cloudflare-api.example.yaml
tohack/dev/cloudflare-api.yaml
and fill in your own credentials:
cp hack/dev/cloudflare-api.example.yaml hack/dev/cloudflare-api.yaml
This file is included in .gitignore
, so your secrets will not be committed to version control.
When you run skaffold dev
, the secret defined in cloudflare-api.yaml
will be automatically applied to your cluster.
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api
namespace: cloudflare-tunnel-ingress-controller-dev
stringData:
api-token: "<your_api_token>"
cloudflare-account-id: "<your_account_id>"
cloudflare-tunnel-name: "<your_tunnel_name>"
This project is licensed under the MIT License. See the LICENSE file for details.