Exposing Pod with Traefik

Exposing Kubernetes Pod with Traefik

This guide shows you how to expose a Kubernetes pod to external traffic using Traefik as an ingress controller. Traefik is a modern reverse proxy and load balancer that makes deploying microservices easy. It automatically discovers and configures routes based on your Kubernetes resources.

Prerequisites

Before you start, you need:

  • A running Kubernetes cluster in Thalassa Cloud
  • kubectl configured to access your cluster
  • helm installed (for installing Traefik)
  • Basic understanding of Kubernetes Services and Ingress resources

Overview

Exposing a pod with Traefik involves:

  1. Installing Traefik (if not already installed)
  2. Deploying your application (Deployment and Service)
  3. Creating an IngressRoute or Ingress resource
  4. Verifying the setup

Step 1: Installing Traefik

Step 1: Check if Traefik is Already Installed

First, check if Traefik is already installed in your cluster:

kubectl get pods -n traefik-system
# or
kubectl get pods -A | grep traefik

If Traefik pods are running, you can skip to Step 2.

Step 2: Add Traefik Helm Repository

If Traefik is not installed, add the official Traefik Helm repository:

helm repo add traefik https://traefik.github.io/charts
helm repo update

Step 3: Install Traefik

Install Traefik using Helm. This example installs Traefik with a LoadBalancer service:

helm install traefik traefik/traefik \
  --namespace traefik-system \
  --create-namespace \
  --set service.type=LoadBalancer \
  --set ports.web.redirectTo=websecure \
  --set ports.websecure.tls.enabled=true

This configuration:

  • Creates a traefik-system namespace
  • Exposes Traefik via a LoadBalancer service
  • Redirects HTTP (port 80) to HTTPS (port 443)
  • Enables TLS on the websecure port

Step 4: Verify Traefik Installation

Wait for Traefik pods to be ready:

kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=traefik -n traefik-system --timeout=300s

Check the Traefik service to get the external IP:

kubectl get svc -n traefik-system

You should see a LoadBalancer service with an external IP address.

Step 2: Deploying Your Application

Step 1: Create a Sample Application

Create a simple web application deployment. Save this as app-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: default
  labels:
    app: sample-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: web
        image: nginx:alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"

Step 2: Create a Service

Create a Service to expose your pods internally. Save this as app-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: sample-app-service
  namespace: default
spec:
  selector:
    app: sample-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

Step 3: Apply the Resources

Apply both the deployment and service:

kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

Step 4: Verify the Application

Check that your pods are running:

kubectl get pods -l app=sample-app
kubectl get svc sample-app-service

Step 3: Exposing the Application with Traefik

Traefik supports two methods for exposing applications:

  • IngressRoute (Traefik’s custom resource - recommended)
  • Standard Ingress (Kubernetes native)

Method 1: Using IngressRoute (Recommended)

Step 1: Install Traefik CRDs

If you installed Traefik manually, ensure the Custom Resource Definitions (CRDs) are installed:

kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml

Step 2: Create an IngressRoute

Create an IngressRoute resource. Save this as app-ingressroute.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: sample-app-ingressroute
  namespace: default
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - match: Host(`example.com`) || Host(`www.example.com`)
      kind: Rule
      services:
        - name: sample-app-service
          port: 80
  tls:
    secretName: sample-app-tls

Note: Replace example.com with your actual domain name. For testing without a domain, you can use the Traefik IP directly (see Method 2).

Step 3: Apply the IngressRoute

kubectl apply -f app-ingressroute.yaml

Step 4: Verify the IngressRoute

kubectl get ingressroute
kubectl describe ingressroute sample-app-ingressroute

Method 2: Using Standard Ingress

Step 1: Create an Ingress Resource

Create a standard Kubernetes Ingress. Save this as app-ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sample-app-ingress
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: sample-app-service
            port:
              number: 80

Note: Replace example.com with your actual domain name or remove the host field to match any host.

Step 2: Apply the Ingress

kubectl apply -f app-ingress.yaml

Step 3: Verify the Ingress

kubectl get ingress
kubectl describe ingress sample-app-ingress

Step 4: Accessing Your Application

Step 1: Get the Traefik LoadBalancer IP

kubectl get svc -n traefik-system traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}'

Or if using a hostname:

kubectl get svc -n traefik-system traefik -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'

Step 2: Test HTTP Access

If you configured a domain, ensure it points to the Traefik IP. Then test:

curl http://example.com
# or using the IP directly
curl -H "Host: example.com" http://<TRAEFIK_IP>

Step 3: Test HTTPS Access

If TLS is configured:

curl https://example.com
# or using the IP directly
curl -k -H "Host: example.com" https://<TRAEFIK_IP>

Step 5: Configuring TLS/HTTPS (Optional)

To enable HTTPS with Traefik, you have several options:

Option 1: Using cert-manager (Recommended)

If you have cert-manager installed, you can automatically provision TLS certificates:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: sample-app-ingressroute
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`example.com`)
      kind: Rule
      services:
        - name: sample-app-service
          port: 80
  tls:
    certResolver: letsencrypt

Option 2: Using a TLS Secret

Create a TLS secret with your certificate:

kubectl create secret tls sample-app-tls \
  --cert=path/to/cert.crt \
  --key=path/to/cert.key \
  -n default

Then reference it in your IngressRoute:

tls:
  secretName: sample-app-tls

Troubleshooting

Application Not Accessible

  1. Check Traefik pods are running:

    kubectl get pods -n traefik-system
  2. Check Traefik logs:

    kubectl logs -n traefik-system -l app.kubernetes.io/name=traefik
  3. Verify your application pods are running:

    kubectl get pods -l app=sample-app
  4. Check the Service endpoints:

    kubectl get endpoints sample-app-service
  5. Verify IngressRoute/Ingress is created:

    kubectl get ingressroute
    kubectl get ingress

Traefik Not Receiving Traffic

  1. Check LoadBalancer service:

    kubectl describe svc -n traefik-system traefik
  2. Verify security groups allow traffic on ports 80 and 443

  3. Check DNS resolution (if using a domain):

    nslookup example.com

TLS Certificate Issues

  1. Check certificate status:

    kubectl describe certificate -n default
  2. Verify cert-manager is running:

    kubectl get pods -n cert-manager
  3. Check cert-manager logs:

    kubectl logs -n cert-manager -l app=cert-manager

Related Documentation