OpenShift -> Cloudflare Tunnels

Good afternoon,

I’ve inherited a setup that looks as follows:

  1. Gitlab images uploaded to a 3rd party hosted instance of OpenShift.
  2. OpenShift hosts application image and visibilityspots/cloudflared image which acts as legacy tunnel.
  3. DNS entry in CF resolves tunnel.

At the end of the month it looks like the legacy tunnels will no longer function.

Looking at the new named tunnels, it looks like you need to log on to the host machine in order to create a tunnel. In this case where OpenShift is the host platform, I’m struggling to understand how I can perform the necessary steps.

Any thoughts greatly appreciated.

Kind regards,

Rob.

Definitely not the case. Could you share with us how you got that idea?

You can follow https://blog.cloudflare.com/ridiculously-easy-to-use-tunnels/ to use the Zero Trust dashboard to create a tunnel, and then you’ll have a command (which includes a token/secret) that you can run in your automation, without ever needing to do manual steps there.
See the docs in: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/remote/

I’ve been through a world of pain the last week trying to get this to work with OpenShift.
I’m finally there but I can’t say the documentation has been too handy when approaching it using the CF Docker image.
The cert.pem has a ttl for 10 years therefore storing it as a secret makes sense, rather than performing a cloudflared login each time to write it locally.
What doesn’t make sense is if you mount a secret volume to the docker image to pull the *.pem it tries to write the <tunnel_id>.json to the same location. As it seems where ever the cert.pem is located determines the write location. By nature OpenShift doesn’t allow you to write to a secret volume, so I’ve had to bodge it and create a symlink in a writable location.
Furthermore the nature of pods mean they will be spun up and down, thus any created <tunnel_id>.json will be destroyed on the pod being destroyed. There’s an --overwrite-dns flag, but ideally I’d require an --overwrite-tunnel flag. As it stands when a pod is destroyed, I have to manually either delete from the ZT GUI or via cloudlflared delete <tunnel_name>. Then spin up a new pod.

For future reference for any OpenShifters:
My BuildConfig:

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: cloudflared-tunnel
  namespace: application
spec:
  nodeSelector: null
  output:
    to:
      kind: ImageStreamTag
      name: 'cloudflared-tunnel:latest'
  resources: {}
  successfulBuildsHistoryLimit: 5
  failedBuildsHistoryLimit: 5
  strategy:
    type: Docker
    dockerStrategy:
      from:
        kind: DockerImage
        name: 'visibilityspots/cloudflared:latest'
      buildArgs:
        - name: SERVICE_IP
          value: '?.?.?.?:8081'
        - name: HOSTNAME_CLOUDFLARE
          value: application-tunnel.domain.uk
  postCommit: {}
  source:
    type: Dockerfile
    dockerfile: >-
      FROM visibilityspots/cloudflared
      ARG SERVICE_IP
      ARG HOSTNAME_CLOUDFLARE
      RUN echo name: $HOSTNAME_CLOUDFLARE >> /tmp/config.txt
      RUN echo hostname: $HOSTNAME_CLOUDFLARE >> /tmp/config.txt
      RUN echo url: $SERVICE_IP >> /tmp/config.txt
      USER 1001
      RUN mkdir /tmp/cloudflare
      RUN chmod 777 /tmp/cloudflare
      RUN export TUNNEL_ORIGIN_CERT=/tmp/cloudflare/cert.pem
      RUN ln -s /tmp/certificates/cert.pem /tmp/cloudflare/cert.pem
      ENTRYPOINT ["cloudflared", "tunnel", "--overwrite-dns", "--config",
      "/tmp/config.txt"]
  triggers:
    - type: ConfigChange
  runPolicy: Serial

My Deployment Config:

kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: cloudflared-tunnel
  namespace: application
spec:
  strategy:
    type: Rolling
    rollingParams:
      updatePeriodSeconds: 1
      intervalSeconds: 1
      timeoutSeconds: 600
      maxUnavailable: 25%
      maxSurge: 25%
    resources: {}
    activeDeadlineSeconds: 21600
  triggers:
    - type: ConfigChange
  replicas: 1
  revisionHistoryLimit: 10
  test: false
  selector:
    app: cloudflared-tunnel
    deploymentConfig: cloudflared-tunnel
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: cloudflared-tunnel
        deploymentConfig: cloudflared-tunnel
    spec:
      volumes:
        - name: domain-cert
          secret:
            secretName: domaincert
            defaultMode: 420
      containers:
        - resources: {}
          terminationMessagePath: /dev/termination-log
          name: cloudflared-tunnel
          env:
            - name: TUNNEL_ORIGIN_CERT
              value: /tmp/cloudflare/cert.pem
          ports:
            - containerPort: 8080
              protocol: TCP
          imagePullPolicy: Always
          volumeMounts:
            - name: domain-cert
              mountPath: /tmp/certificates
          terminationMessagePolicy: File
          image: >-
            image-registry.openshift-image-registry.svc:5000/application/cloudflared-tunnel:latest
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler