Hi,
Trying to get a configuration setup and I'm not sure what I'm doing wrong. I have a stand alone docker instance running on a public subnet. Two containers are running. Portainer and Traefik. I have TLS with Protainer and the Dashboard working perfectly. On my private subnet I have a docker swarm configuration running and it is connected to the Traefik proxy running on the controller machine. I spun up a basic service of a redis instance and added all the proper labels and it seems to be configured properly. The problem is that the IP that keeps being used is part of the swarm's overlay network and any traffic pointed at the endpoint just times out. Is this configuration viable? I've seen some indications that Traefik won't work unless it is running on the swarm itself.
Thanks for your time.
Do you use TLS? Do you use a TCP router?
Hi bluepuma77,
Thanks for the question. I have turned TLS on and off in different combinations. Yes...using the TCP router.
Static config
swarm:
endpoint: "tcp://10.0.2.99:2375"
The response from the swarm
"tcp":{"routers":{"redis":{"entryPoints":["redis"],"rule":"HostSNI(`*`)","service":"redis"}},"services":{"redis":{"loadBalancer":{"servers":[{"address":"10.11.0.1:6379"}]}}}}
Tags on the stack in Deploy. Tried a few combinations
- traefik.tcp.routers.redis.rule=HostSNI(`*`)
#- traefik.tcp.routers.redis.tls=true
#- traefik.docker.network=host
- traefik.docker.lbswarm=true
- traefik.tcp.services.redis.loadbalancer.server.port=6379
- traefik.tcp.routers.redis.entrypoints=redis
- traefik.enable=true
- traefik.tcp.routers.redis.service=redis
redis-cli -h <domain> -p 6379
<domain>:6379> ping
Error: Server closed the connection
2023-11-20T16:35:50Z DBG github.com/traefik/traefik/v3/pkg/tcp/proxy.go:41 > Handling TCP connection address=10.11.0.1:6379 remoteAddr=<myip>:47750
2023-11-20T16:36:20Z ERR github.com/traefik/traefik/v3/pkg/tcp/proxy.go:48 > Error while dialing backend error="dial tcp 10.11.0.1:6379: i/o timeout"
If I hit any of the nodes from the controller machine...works perfectly
Share your full Traefik static and dynamic configuration, and docker-compose.yml
if used. Also from the target service.
################################################################
#
# Configuration sample for Traefik v2.
# https://github.com/traefik/traefik/blob/v2.10/traefik.sample.yml
#
# For Traefik v1: https://github.com/traefik/traefik/blob/v2.10/traefik.sample.toml
#
################################################################
################################################################
# Global configuration
################################################################
global:
checkNewVersion: true
sendAnonymousUsage: true
################################################################
# EntryPoints configuration
################################################################
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
redis:
address: :6379
################################################################
# Traefik logs configuration
################################################################
log:
level: DEBUG
# filePath: log/traefik.log
# format: json
################################################################
# Access logs configuration
################################################################
accessLog:
filePath: /etc/traefik/logs/access.log
format: json
fields:
defaultMode: keep
names:
ClientAddr: keep
ClientUsername: keep
DownstreamStatus: keep
OriginStatus: keep
RequestAddr: keep
RequestHost: keep
RequestMethod: keep
RequestPath: keep
RequestPort: keep
RequestProtocol: keep
RouterName: keep
ServiceAddr: keep
ServiceName: keep
StartLocal: keep
entryPointName: keep
headers:
defaultMode: keep
################################################################
# API and dashboard configuration
################################################################
api:
insecure: false
dashboard: true
#debug: true
################################################################
# Ping configuration
################################################################
ping:
entryPoint: traefik
################################################################
# Provider configuration backend
################################################################
providers:
# Enable Docker configuration backend
docker:
exposedByDefault: true
file:
filename: /etc/traefik/dynamic.yml
watch: true
swarm:
endpoint: "tcp://10.0.2.99:2375"
# docker swarm mode (1.12+)
# Let's Encrypt Config
# certificatesResolvers:
# letsEncrypt:
# acme:
# email: <REDACTED>
# storage: /etc/traefik/acme.json
# tlsChallenge: {}
# staging:
# acme:
# email: <REDACTED>
# storage: /etc/traefik/staging.json
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
# tlsChallenge: {}
http:
middlewares:
dashboard-auth:
basicAuth:
users:
- "admin:...."
routers:
api:
rule: Host(`dashboard.app.domain`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
middlewares:
- dashboard-auth
service: api@internal
tls: {}
tls:
stores:
default:
defaultCertificate:
certFile: /etc/traefik/certs/fullchain.pem
keyFile: /etc/traefik/certs/privkey.pem
version: '3.7'
services:
redis:
image: redis:latest
hostname: "redis.unc"
command: redis-server --appendonly yes
volumes:
- redis_data:/data
networks:
- redisnet
ports:
- "6379:6379"
deploy:
endpoint_mode: vip
labels:
- traefik.tcp.routers.redis.rule=HostSNI(`*`)
#- traefik.tcp.routers.redis.tls=true
#- traefik.docker.network=host
- traefik.docker.lbswarm=true
- traefik.tcp.services.redis.loadbalancer.server.port=6379
- traefik.tcp.routers.redis.entrypoints=redis
- traefik.enable=true
- traefik.tcp.routers.redis.service=redis
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
environment:
REDIS_REPLICATION_MODE: master
networks:
redisnet:
driver: overlay
volumes:
redis_data:
driver: local
Traefik compose is missing.
Note that you attach Redis to a Docker network that by default is not shared, so Traefik should not be able to connect to it.
I ran Traefik without compose.
Docker Swarm uses a mesh network for routing with overlays. If the request hits any node on the appropriate port it will route to the correct node using the IPVS service. That si my main issue, is that Traefik should be using a node IP address and the ingress overlay will take care of the rest, but instead it is behaving as if it was part of the swarm. Which goes to my initial question. Can Traefik work with providers that it is not apart of?
By default, Traefik gets the IPs of all instances of a Docker service and uses round-robin to forward requests to those Docker network IPs.
If you want Traefik to use the Docker service VIP instead, just set the option traefik.docker.lbswarm=true
(doc).
If you want to use external Docker IPs, then use providers.docker.useBindPortIP=true
(doc).