Getting External Services Working with Traefik in K3s

The Challenge

When I first set up Traefik as my ingress controller in my K3s cluster, everything worked fine for internal services running within Kubernetes. However, I ran into issues when trying to expose external services β€” like my Proxmox server β€” through Traefik while ensuring proper routing, TLS, and domain handling.

The Goal

My goal was to access My Proxmox web gui via Traefik using the domain juliette.home.m23homelab.org, while ensuring:

  • Proper TLS handling with Let’s Encrypt (via cert-manager).
  • Secure HTTPS passthrough without Traefik interfering.
  • Correct routing through an ExternalName service in Kubernetes.

I got help from @dasop on Discord, who pointed me in the right direction!

The Working Solution

After a lot of troubleshooting, I managed to get it working with the following Kubernetes manifests:

1. The ExternalName Service

This service maps the internal Proxmox instance to a Kubernetes service so that Traefik can route traffic to it.

apiVersion: v1
kind: Service
metadata:
  name: proxmox-juliette
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    # 2 Lines Below required if app/endpoint uses https! if http dont uncomment.
    traefik.ingress.kubernetes.io/service.serverstransport: default-insecure-transport@kubernetescrd
    traefik.ingress.kubernetes.io/service.serversscheme: https
spec:
  type: ExternalName
  externalName: 192.168.178.170  # Proxmox server internal IP
  ports:
    - port: 8006
      targetPort: 8006
      protocol: TCP

Explanation:

  • ExternalName Service: This service acts as a proxy to an external IP (192.168.178.170).
  • Traefik Annotations:
    • service.serverstransport: default-insecure-transport@kubernetescrd: This tells Traefik to use the insecure transport, allowing it to communicate with self-signed HTTPS services.
    • service.serversscheme: https: This ensures that Traefik properly routes traffic using HTTPS instead of defaulting to HTTP.

2. The Ingress

This Ingress definition tells Traefik how to route external requests to the Proxmox service.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: proxmox-juliette-ingress
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
    external-dns.alpha.kubernetes.io/hostname: juliette.home.m23homelab.org
    cert-manager.io/cluster-issuer: cloudflare-clusterissuer
spec:
  tls:
    - hosts:
      - juliette.home.m23homelab.org
      secretName: proxmox-juliette-certificate-secret
  rules:
    - host: juliette.home.m23homelab.org
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: proxmox-juliette
                port:
                  number: 8006
  • TLS Setup: This uses cert-manager to issue a TLS certificate via Cloudflare DNS.
  • Ingress Rules: Any request to juliette.home.m23homelab.org is forwarded to the Proxmox service.

3. ServerTransport Manifest (For Insecure HTTPS Backends)

Since Proxmox uses a self-signed certificate, we need to allow Traefik to skip certificate verification for this backend.

apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
  name: default-insecure-transport
  namespace: default
spec:
  insecureSkipVerify: true

Explanation:

  • insecureSkipVerify: true allows Traefik to communicate with self-signed HTTPS services without failing due to certificate validation errors.
  • This is referenced in the Service manifest via traefik.ingress.kubernetes.io/service.serverstransport: default-insecure-transport@kubernetescrd.

Lessons Learned

  • External services require an ExternalName service in Kubernetes, rather than directly exposing them via Ingress.
  • If an external service uses HTTPS, Traefik must be told to use serversscheme: https, or it defaults to HTTP.
  • For self-signed certificates, a ServersTransport resource is required to allow insecure connections.
  • DNS management is handled by external-dns and cert-manager, making domain and TLS automation seamless.

Final Thoughts

With this setup, I can now securely access my Proxmox Web UI through Traefik using my domain, with full TLS support. This method also applies to other external services, like router UIs, other servers, or web applications outside the cluster. Huge thanks to @dasop on Discord for pointing me in the right direction!