Split Expose User Guides & Add Multi-Layer Routing Section

This commit is contained in:
Sheddy
2026-01-26 14:36:04 +01:00
committed by GitHub
parent 139b59def9
commit 91381590d3
8 changed files with 1573 additions and 924 deletions
@@ -1,252 +1,29 @@
# Exposing Services with Traefik on Docker
# Exposing Services with Traefik on Docker - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with a complex authentication based routing example
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the Traefik Docker Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service in `docker-compose.yml`:
```yaml
labels:
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@@ -255,10 +32,10 @@ labels:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply middlewares to whoami router
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@@ -288,7 +65,7 @@ curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
In the response headers, you should see security headers set by the middleware:
- `X-Frame-Options: DENY`
- `X-Frame-Options: DENY`
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security` with the appropriate settings
@@ -438,28 +215,191 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker labels do not support the `parentRefs` field. However, you can use **both Docker and File providers together** - Docker labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker
To use multi-layer routing with Docker, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./dynamic:/etc/traefik/dynamic:ro" # Mount directory for dynamic config
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Mock authentication service that adds X-User-Role header
auth-service:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Auth Service
labels:
- "traefik.enable=true"
- "traefik.http.services.auth-service.loadbalancer.server.port=80"
# Admin backend service
admin-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Admin Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=User Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.docker.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@docker` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Docker services:
- Use `service-name@docker` to reference Docker services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Apply the changes:
```bash
docker compose up -d
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Docker service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../../reference/install-configuration/providers/docker.md) for more details about the Docker integration
+250
View File
@@ -0,0 +1,250 @@
# Exposing Services with Traefik on Docker - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the [Traefik Docker Setup guide](../../setup/docker.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing
@@ -1,432 +1,25 @@
# Exposing Services with Traefik on Kubernetes
# Exposing Services with Traefik on Kubernetes - Advanced
This guide will help you expose your services securely through Traefik Proxy on Kubernetes. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding security middleware, and configuring sticky sessions. For routing, this guide gives you two options:
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Kubernetes before proceeding.
- [Gateway API](../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
Feel free to choose the one that fits your needs best.
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management (IngressRoute)
- **cert-manager** for automated certificate management (Gateway API)
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with complex authentication scenarios (IngressRoute only)
## Prerequisites
- Completed the [Basic Guide](basic.md)
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the Traefik Kubernetes Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
### Create Middlewares
@@ -469,37 +62,6 @@ kubectl apply -f middlewares.yaml
In Gateway API, you can apply middlewares using the `ExtensionRef` filter type. This is the preferred and standard way to use Traefik middlewares with Gateway API, as it integrates directly with the HTTPRoute specification.
First, make sure you have the same middlewares defined:
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
namespace: default
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ip-allowlist
namespace: default
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 10.0.0.0/8 # Typical cluster network range
- 192.168.0.0/16 # Common local network range
```
Now, update your `HTTPRoute` to reference these middlewares using the `ExtensionRef` filter:
```yaml
@@ -525,7 +87,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -543,7 +105,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -854,7 +416,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -876,7 +438,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -986,29 +548,283 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Setup Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "IngressRoute Support"
Multi-layer routing is **natively supported** by Kubernetes IngressRoute (CRD) using the `spec.parentRefs` field. This feature is not available when using standard Kubernetes Ingress or Gateway API resources.
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent IngressRoute authenticates requests, and child IngressRoutes direct traffic based on user roles.
!!! important "Parent Router Requirements"
Parent routers in multi-layer routing must not have a service defined. The child routers will handle the service selection based on their matching rules. Make sure all child IngressRoutes reference the parent correctly using `parentRefs`.
First, deploy your backend services:
```yaml
# whoami-backends.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: admin-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: admin-backend
template:
metadata:
labels:
app: admin-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "Admin Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: admin-backend
namespace: default
spec:
selector:
app: admin-backend
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: user-backend
template:
metadata:
labels:
app: user-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "User Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: user-backend
namespace: default
spec:
selector:
app: user-backend
ports:
- port: 80
```
Apply the backend services:
```bash
kubectl apply -f whoami-backends.yaml
```
Now create the middleware and IngressRoutes for multi-layer routing:
```yaml
# mlr-ingressroute.yaml
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
namespace: default
type: Opaque
stringData:
users: |
admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0
user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI.
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
basicAuth:
secret: auth-secret
headerField: X-Auth-User
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.docker.localhost`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
# Note: No services and no TLS config - this is a parent IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-admin
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `admin`)
kind: Rule
services:
- name: admin-backend
port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `user`)
kind: Rule
services:
- name: user-backend
port: 80
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
Apply the multi-layer routing configuration:
```bash
kubectl apply -f mlr-ingressroute.yaml
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent IngressRoute** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child IngressRoute** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Kubernetes service
### Cross-Namespace Parent References
You can reference parent IngressRoutes in different namespaces by specifying the `namespace` field:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: app-namespace
spec:
parentRefs:
- name: api-parent
namespace: shared-namespace # Parent in different namespace
routes:
- match: Path(`/child`)
kind: Rule
services:
- name: child-service
port: 80
```
!!! important "Cross-Namespace Requirement"
To use cross-namespace parent references, you must enable the `allowCrossNamespace` option in your Traefik Helm values:
```yaml
providers:
kubernetesCRD:
allowCrossNamespace: true
```
### Multiple Parent References
Child IngressRoutes can reference multiple parent IngressRoutes:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: default
spec:
parentRefs:
- name: parent-one
- name: parent-two
routes:
- match: Path(`/api`)
kind: Rule
services:
- name: child-service
port: 80
```
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Kubernetes using both Gateway API and IngressRoute
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Automate certificate management with Let's Encrypt (IngressRoute) and cert-manager (Gateway API)
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing (IngressRoute only)
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Kubernetes. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Kubernetes. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Kubernetes, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration.
- [Gateway API provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration.
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration
- [Gateway API provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration
+438
View File
@@ -0,0 +1,438 @@
# Exposing Services with Traefik on Kubernetes - Basic
This guide will help you get started with exposing your services through Traefik Proxy on Kubernetes. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
For routing, this guide gives you two options:
- [Gateway API](../../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
Feel free to choose the one that fits your needs best.
## Prerequisites
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the [Traefik Kubernetes Setup guide](../../setup/kubernetes.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Kubernetes, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt (IngressRoute) or cert-manager (Gateway API)
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing with IngressRoute
+3 -3
View File
@@ -17,6 +17,6 @@ Following these guides, you'll learn how to:
For detailed steps tailored to your environment, follow the guide for your platform:
- [Kubernetes](./kubernetes.md)
- [Docker](./docker.md)
- [Docker Swarm](./swarm.md)
- [Kubernetes](./kubernetes/basic.md)
- [Docker](./docker/basic.md)
- [Docker Swarm](./swarm/basic.md)
@@ -1,186 +1,23 @@
# Exposing Services with Traefik on Docker Swarm
# Exposing Services with Traefik on Docker Swarm - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker Swarm. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker Swarm before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for complex authentication scenarios
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the Traefik Docker Swarm Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service deployment section in `docker-compose.yml`:
@@ -189,7 +26,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@@ -198,10 +35,10 @@ deploy:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply the middlewares
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@@ -332,7 +169,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Sticky Sessions Configuration
- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=sticky_cookie"
@@ -374,28 +211,195 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker Swarm labels do not support the `parentRefs` field. However, you can use **both Docker Swarm and File providers together** - Swarm labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker Swarm
To use multi-layer routing with Docker Swarm, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: traefik:v3.4
command:
- "--api.dashboard=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik_proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
configs:
- source: mlr-config
target: /etc/traefik/dynamic/mlr.yml
networks:
- traefik_proxy
deploy:
placement:
constraints:
- node.role == manager
configs:
mlr-config:
file: ./dynamic/mlr.yml
networks:
traefik_proxy:
external: true
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker Swarm services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Admin backend service
admin-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=Admin Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=User Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.swarm.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@swarm` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Swarm services:
- Use `service-name@swarm` to reference Swarm services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.swarm.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.swarm.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Swarm service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker Swarm
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker Swarm. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker Swarm. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker Swarm, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../../reference/install-configuration/providers/docker.md) for more details about the Docker integration
+191
View File
@@ -0,0 +1,191 @@
# Exposing Services with Traefik on Docker Swarm - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker Swarm. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the [Traefik Docker Swarm Setup guide](../../setup/swarm.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker Swarm, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing
+19 -9
View File
@@ -136,12 +136,16 @@ plugins:
'middlewares/tcp/ipwhitelist.md': 'reference/routing-configuration/tcp/middlewares/ipallowlist.md'
'middlewares/tcp/ipallowlist.md': 'reference/routing-configuration/tcp/middlewares/ipallowlist.md'
## User Guides
'user-guides/crd-acme/index.md': 'expose/kubernetes.md'
'user-guides/cert-manager.md': 'expose/kubernetes.md'
'user-guides/docker-compose/basic-example/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-tls/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-http/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-dns/index.md': 'expose/docker.md'
'user-guides/crd-acme/index.md': 'expose/kubernetes/basic.md'
'user-guides/cert-manager.md': 'expose/kubernetes/advanced.md'
'user-guides/docker-compose/basic-example/index.md': 'expose/docker/basic.md'
'user-guides/docker-compose/acme-tls/index.md': 'expose/docker/advanced.md'
'user-guides/docker-compose/acme-http/index.md': 'expose/docker/advanced.md'
'user-guides/docker-compose/acme-dns/index.md': 'expose/docker/advanced.md'
## Expose pages (redirect old URLs to new structure)
'expose/kubernetes.md': 'expose/kubernetes/basic.md'
'expose/docker.md': 'expose/docker/basic.md'
'expose/swarm.md': 'expose/swarm/basic.md'
# References
# Static Configuration
'reference/static-configuration/overview.md': 'reference/install-configuration/configuration-options.md'
@@ -201,9 +205,15 @@ nav:
- 'Swarm': 'setup/swarm.md'
- 'Expose':
- 'Overview': 'expose/overview.md'
- 'Kubernetes': 'expose/kubernetes.md'
- 'Docker': 'expose/docker.md'
- 'Swarm': 'expose/swarm.md'
- 'Kubernetes':
- 'Basic': 'expose/kubernetes/basic.md'
- 'Advanced': 'expose/kubernetes/advanced.md'
- 'Docker':
- 'Basic': 'expose/docker/basic.md'
- 'Advanced': 'expose/docker/advanced.md'
- 'Swarm':
- 'Basic': 'expose/swarm/basic.md'
- 'Advanced': 'expose/swarm/advanced.md'
- 'Secure':
- '<span class="nav-link-with-icon">Secure Access with JWT <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>': 'secure/secure-api-access-with-jwt.md'
- '<span class="nav-link-with-icon">Secure Access with OIDC <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>': 'secure/secure-api-access-with-oidc.md'