Kubernetes Ingress Controller

Kubernetes support for Argo-Tunnel is in Beta.

Ideas or feedback on the Cloudflare Ingress Controller? We’re eager to hear your thoughts in the forum.

Want to contribute? The Cloudflare Ingress Controller is open source.

Playing around with the Argo Tunnel Ingress Controller is easy, and can be done on any Kubernetes cluster (Google GKE, Amazon EKS, Microsoft AKS). If you don’t have one, you can create a local Kubernetes cluster with Minikube.

For use-cases that require more than a single controller replica, you will need to purchase Cloudflare Load Balancing to use Argo Tunnel Ingress Controller. In the future, Cloudflare Load Balancing will be a configuration option, and the Ingress Controller will be usable without Load Balancing.

In this example, we’re going to expose a private version of the echoserver through Argo Tunnel. This example assumes you have a Kubernetes cluster running on one of the platforms mentioned above.

Step One: Download Cloudflared & Generate a Certificate

Download and install cloudflared here.

Then, run cloudflared login and select a domain to generate and download a certificate. Make sure the certificate is placed into ~/.cloudflared/cert.pem

Step Two: Install the Ingress Controller with Helm

Helm is a package manager for kubernetes which defines an application as a set of templates. This makes it easy to install and update applications in a kubernetes cluster.

Add the repository that holds the Helm chart:

 helm repo add cloudflare https://cloudflare.github.io/helm-charts
 helm repo update

The Helm chart that describes all the components is found here.

Install the Controller with Helm:

$ helm install --name anydomain --namespace default \
    --set rbac.create=true \
    --set controller.ingressClass=argo-tunnel \
    --set controller.logLevel=6 \
    cloudflare/argo-tunnel

Note: the controller watches all namespaces.

Step Three: Deploy a Service into a Kubernetes Cluster

The echoserver image starts a http listener that simply mimics the request as its response.

Create a manifest called echo.yaml:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: echo
  name: echo
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: echo
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: echo
  name: echo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: k8s.gcr.io/echoserver:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
      terminationGracePeriodSeconds: 60

Deploy echoserver into your Kubernetes cluster:

kubectl apply -f echo.yaml`

Tip: -n sets the namespace for deployment.

Step Four: Create a Tunnel Secret

Convert the domain certificate into a tunnel secret:

$ kubectl create secret generic mydomain.com --from-file="$HOME/.cloudflared/cert.pem"

Tip: -n sets the namespace for deployment.

Step Five: Create an Ingress Definition

The Kubernetes Ingress is a spec for external connectivity to a Kubernetes service. Typically, an ingress will contain an annotation, kubernetes.io/ingress.class, to identify the controller that should handle the ingress.

The ingress manifest contains:

  • an annotation kubernetes.io/ingress.class: argo-tunnel, matching the controller.
  • mappings between host and service name, port, path that should be exposed.
  • mappings between host and tunnel secret

Create an ingress definition called echo-tunnel.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: argo-tunnel
  labels:
    ingress: argo-tunnel
  name: echo
spec:
  tls:
  - hosts:
    - echo.mydomain.com
    secretName: mydomain.com
  rules:
  - host: echo.mydomain.com
    http:
      paths:
      - backend:
          serviceName: echo
          servicePort: http

Note:

  • the Ingress must be deployed in the same namespace as the Service
  • the Ingress must be deployed in the same namespace as the Secret
  • the host must belong the domain certificate (tunnel secret)

Deploy the Ingress:

$ kubectl apply -f echo-tunnel.yaml

Tip: -n sets the namespace for deployment.

The ingress controller opens a tunnel between the Cloudflare edge and the Kubernetes virtual service IP.

Step Six: Use the Tunnel

The ingress controller opens a tunnel between the Cloudflare edge and the Kubernetes virtual service IP.

Curl the tunnel:

$ curl http://echo.mydomain.com

Questions? Feedback? We’re listening here.