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.enablewith the valuetruetraefik.http.routers.<router_name>.tlswith the valuefalsetraefik.http.routers.<router_name>.entrypointswith the valuewebtraefik.http.routers.<router_name>.rule with matching rules, e.g.
Host(`example.localhost`)traefik.http.services.<service_name>.loadbalancer.server.portwith 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.enablewith the valuetruetraefik.http.routers.<router_name>.tlswith the valuetruetraefik.http.routers.<router_name>.entrypointswith the valuewebsecuretraefik.http.routers.<router_name>.rule with matching rules, e.g.
Host(`example.localhost`)traefik.http.services.<service_name>.loadbalancer.server.portwith the port used by the container, e.g.80.
Example
Given the following Kubernetes manifest file
# 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
traefikwith a container namedtraefikrunning the imagedocker.io/library/traefik:v3.6.6and the ports 80 and 8080 in the host are mapped to the port 80 and 8080, respectively, in the container.a pod named
nginx-traefikwith a container namednginx-traefikrunning the imagedocker.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