Traefik Proxy

One limitation of using ports to access the container is that only a single container can be bind to a given port. Another limitation of using ports to access the container is that ports are not mnemonics. One solution to both problems is the use of a proxy.

         flowchart
     subgraph pod0[Pod]
     proxy
     end

     subgraph pod1[Pod]
     nginx1
     end

     subgraph pod2[Pod]
     nginx2
     end

     subgraph network[Network]
     pod0
     pod1
     pod2
     end

     subgraph host[Host]
     browser
     network
     pod0
     pod1
     pod2
     end

     browser[Web browser] -->|*.localhost| proxy[Proxy];
     proxy -->|foo.localhost| nginx1[Django];
     proxy -->|bar.localhost| nginx2[Flask];

     classDef classPod fill:lightblue,stroke:blue
     class pod0 classPod;
     class pod1 classPod;
     class pod2 classPod;

     classDef classNetwork stroke:black,stroke-dasharray: 5 5
     class network classNetwork;
    

Diagram of proxy to access container.

A popular proxy is Traefik and it will be cover in this section.

Note

The content of this section is inspired by “Running the Traefik, my favorite Edge Router with Podman” from William Sena.

Requirements

Traefik requires access to Podman’s systemd socket to work. To start the socket, run

systemctl --user start podman.socket

If you prefer, to start immediately on boot, run

systemctl --user enable podman.socket

Usage

Traefik uses labels in the pod to declare the rules for when and how traffic should be directed to the specific pod.

HTTP

Labels used for HTTP are

  • traefik.enable with the value true

  • traefik.http.routers.<router_name>.tls with the value false

  • traefik.http.routers.<router_name>.entrypoints with the value web

  • traefik.http.routers.<router_name>.rule with matching rules, e.g. Host(`example.localhost`)

  • traefik.http.services.<service_name>.loadbalancer.server.port with the port used by the container, e.g. 80.

HTTPS

Traefik has built-in support for Let’s Encrypt and the reader must read the section “TLS Certificate Management (Let’s Encrypt)” from the Traekik documentation.

Labels used for HTTP are

  • traefik.enable with the value true

  • traefik.http.routers.<router_name>.tls with the value true

  • traefik.http.routers.<router_name>.entrypoints with the value websecure

  • traefik.http.routers.<router_name>.rule with matching rules, e.g. Host(`example.localhost`)

  • traefik.http.services.<service_name>.loadbalancer.server.port with the port used by the container, e.g. 80.

Example

Given the following Kubernetes manifest file

play.yml
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.3.1
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  containers:
  - args:
    - nginx
    - -g
    - daemon off;
    image: docker.io/library/nginx:alpine
    name: nginx
    ports:
    - containerPort: 80
      hostIP: 0.0.0.0
      hostPort: 8080

running

podman kube play play.yml

creates

  • a pod named traefik with a container named traefik running the image docker.io/library/traefik:v3.6.6 and the ports 80 and 8080 in the host are mapped to the port 80 and 8080, respectively, in the container.

  • a pod named nginx-traefik with a container named nginx-traefik running the image docker.io/library/nginx:alpine.

The Traefik dashboard can be tested with

curl http://traefik.localhost

and the NGINX server can be tested with

curl http://example.localhost