Service Routing with Traefik - External Services and URLs (Day 9)
Using Traefik to route traffic to services outside Kubernetes, e.g. Proxmox and OPNsense UIs, including SSL certificates.
Having moved to a k3s deployed traefik, this covers setting up routes for services running outside the cluster.
Initial Traefik Configuration
First, we need to enable external name services in Traefik (add this to your traefik ingress deployment):
set:
- name: providers.kubernetesCRD.allowExternalNameServices
value: true
Route Organization
I'm keeping all routes separate from other deployments using a dedicated routes.yaml
for helmfile:
releases:
- name: routes
namespace: routes
chart: ./charts/routes
Certificate Setup
Assuming you have a ClusterIssuer
already configured next we request a wildcard certificate for the services defined in the namespace.
I typically request wildcard certificates per namespace if there are multiple services needing ingress routes
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: routes-ns-ssl-cert
namespace: routes
spec:
commonName: "*.<your domain>"
dnsNames:
- "*.<your domain>"
issuerRef:
kind: ClusterIssuer
name: letsencrypt-dns01-issuer
secretName: ssl-cert-prod
Traffic Management
HTTP to HTTPS Redirect
First, an HTTPS redirect middleware - this forces all incoming traffic to use HTTPS
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: https-redirect
namespace: routes
spec:
redirectScheme:
scheme: https
permanent: true
Handling Self-Signed Certs
For services like Proxmox and OPNsense that use self-signed certificates, we need to tell Traefik to skip verification:
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: insecure-skip-verify
namespace: routes
spec:
insecureSkipVerify: true
Setting Up Routes
1. Define the Service
First, create a service for your endpoint:
apiVersion: v1
kind: Service
metadata:
name: opnsense
namespace: routes
spec:
ports:
- port: 443
targetPort: 443
type: ExternalName
externalName: 192.168.2.1 <this is the IP of the service you want to route to or its domain name>
2. Create Ingress Routes
You'll need two routes - one for HTTPS and one for HTTP redirect:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: opnsense
namespace: routes
spec:
entryPoints:
- websecure
routes:
- match: Host(`<the URL you want to the service to be reached on>`)
kind: Rule
services:
- name: opnsense
port: 443
scheme: https
serversTransport: insecure-skip-verify
tls:
secretName: ssl-cert-prod
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: opnsense-redirect
namespace: routes
spec:
entryPoints:
- web
routes:
- match: Host(`<the URL you want to the service to be reached on>`)
kind: Rule
middlewares:
- name: https-redirect
services:
- name: noop@internal
kind: TraefikService
3. Configure DNS Entries
Add your routes to your DNS provider:
<your defined url> -> traefik loadbalancer ip
Or if your DNS provider supports wildcards:
*.<your defined url> -> traefik loadbalancer ip
I'm using AdGuard Home, so it's just a matter of going to Filters > DNS rewrites and adding either a wildcard or specific URL.
4. Deploy the Routes
Review the changes first:
helmfile diff --file routes.yaml
Then deploy:
helmfile apply --file routes.yaml
You should now be able to access the service via the URL name used.