How to Successfully Publish Traefik on a Single VM with k3s?

December 11, 2025 5 answers
Asked by CuriousCod3r
Hey everyone! I'm diving into my first Kubernetes cluster using k3s because I find it user-friendly. I have MediaWiki running smoothly inside the cluster, but now I want to publish it through Traefik, which comes integrated with k3s. Since I'm only working with a single VM and don't have access to any cloud load balancers, I plan to configure Traefik to utilize hostPorts to publish this service. I'm currently using this Helm configuration: ```yaml # HelmChartConfig for Traefik apiVersion: helm.cattle.io/v1 kind: HelmChartConfig metadata: name: traefik namespace: kube-system spec: valuesContent: |- service: type: ClusterIP ports: web: port: 80 expose: true exposedPort: 80 protocol: TCP hostPort: 80 websecure: port: 443 expose: true exposedPort: 443 protocol: TCP hostPort: 443 additionalArguments: - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - "--certificatesresolvers.lecertresolver.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.lecertresolver.acme.email=redacted@gmail.com" - "--certificatesresolvers.lecertresolver.acme.storage=/data/acme.json" ``` Yet, when I deploy it with `kubectl apply -f .`, the Traefik service remains configured as a LoadBalancer instead of using hostPorts. I also tried implementing MetalLB, but it didn't workโ€”possibly due to some ARP issues in my provider's network. Checking the logs of the Traefik pod indicates that the ACME challenge from Let's Encrypt fails due to timeouts, and I can't access services on port 443 either. I even ran `ss -lntp`, and I couldn't see ports 80 or 443 being bound to anything. What am I missing? Any tips would be appreciated because I'm quite new to Kubernetes!

Answers

DevNewbie34
Remember, a ClusterIP service is only accessible within the cluster but not from outside. If you're aiming for outside accessibility, consider using a NodePort service or go for a LoadBalancer serviceโ€”which k3s provides as well! Just check out this [link](https://docs.k3s.io/networking/networking-services#service-load-balancer) for guidance about setting it up properly.
Reply to this answer
SimplicitySeeker
The line `type: ClusterIP` means it's only reachable inside your cluster and doesnโ€™t expose ports on your node. To provide a proper answer, Iโ€™d need to know where your VM is hostedโ€”like on a local network or in the cloudโ€”since different providers have different networking rules.
Reply to this answer
CloudExplorer
If you want to hit your service from outside, you'll need to set up MetalLB properly to assign a load balancer IP to your service. Make sure that external IP is configured correctly!
Reply to this answer
KubeNinja99
Take a moment to simplify your approachโ€”right now youโ€™re juggling multiple issues. Start off simply on a VM or Docker. Make sure your provider supports virtual IPs and try to expose a basic 'hello world' pod using MetalLB first. Then move on to getting HTTP working, before setting up HTTPS with a self-signed certificate.
Reply to this answer
TechieGuru83
You might not need to stress about those configurations! Generally, the Traefik included with k3s should automatically expose ports 80 and 443 via ServiceLB, as outlined in their documentation. With just a single node, you can simply expose those ports on your node to access it over the internet, and it should work just fine. Also, don't worry about processes showing up as listening on those ports; Kubernetes handles a lot of networking under the hood with iptables, so port 80 and 443 traffic on the node can still route to the right places inside your pod without anything showing as 'listening' on those ports outside the pod.
Reply to this answer

Add your answer

Answers are reviewed before publication.

Related Discussions