17. September 2021 4 min read

Kubernetes and Traefik v2 forward traffic to external IP

In my internal network I have couple of devices that I would love to expose to internet. However as we all know those devices are not the most secure, so providing added layer of security via Kubernetes and Traefik v2 seemed like easiest and best idea. Traefik already obtains Letsencrypt certificates for the domains and is also able to forward traffic to addresses external to your Kubernetes cluster.

Prepare Traefik and Letsencrypt

Although I have written about this section in past posts, for completeness here is the creation of the certificate which uses letsencrypt-prod as issuer (read the official certmanager docs how to setup Issuer).

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: example-cert
  namespace: example
spec:
  commonName: example.the-mori.com
  secretName: example-the-mori-cert
  dnsNames:
    - example.the-mori.com
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer

After you applied above certificate it is time to create a service, which is going to connect your outside-cluster server to the Kubernetes and Traefik. Important change is to adjust the ExternalName IP and ports.targetPort value to match the IP and port on which your outside-cluster server is on and listening. There are quite few ways to find the IP of the server in an internal network, but in most cases, it is in 192.168.X.X ranges (depending on your subnet mask).

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: outside-server-example
  name: outside-server-example
  namespace: example
spec:
  type: ExternalName
  ports:
    - name: outside-server-example
      port: 80
      targetPort: 80
  externalName: 192.168.0.196
  selector:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/name: traefik

Connect Traefik and Service with IngressRoute

Now everything is setup so that Traefik can connect the Service and external host, while also starting to obtain the certificate. This is done with IngressRoute object where match:Host is simply hostname/domain that you want Traefik to forward messages from and services is the name of service. tls.secretName is the connection to certificate, so that connection can be secured via https. Keep in mind that Host here, has to match proper fields in the Certificate object above.

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: outside-server-ingress
  namespace: example
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`example.the-mori.com`)
      kind: Rule
      services:
        - name: outside-server-example
          kind: Service
          port: 80
  tls:
    secretName: example-the-mori-cert

It is this easy to use Traefik to forward traffic to a server external to your Kubernetes cluster. A fair warning is that this ideally should be within your local network as the main reason is to provide an additional layer of security and not expose vulnerable devices to the internet.
With Traefik 2.5.x the issue is that (via Helm Chart) you need to enable external services using this two arguments

additionalArguments:
    - "--providers.kubernetesingress.allowexternalnameservices"
    - "--providers.kubernetescrd.allowexternalnameservices"

These two arguments were not needed in previous versions of Traefik so make sure it is setup like this.

Newest from this category: