Traefik 2 does not match 2 Entrypoints - kubernetes

i have simple question. I want to receive a response from the backend on two different ports. According to the documentation, this should be a simple task. I did so, but for some reason one part does not work. What am I missing?
http://my-service.com -> Works.
http://my-service.com:6666 -> Does not work.
I configured traefik:
Static-conf:
entryPoints:
web:
address: :80
websecure:
address: :443
traefik:
address: :9000
web2:
address: :6666
Dynamic-conf:
http:
routers:
StartPage:
entryPoints:
- web
- web2
service: MyService
rule: "Host(`my-service.com`)"
services:
MyService:
loadBalancer:
servers:
- url: "http://ca-service-svc.app/"
Traefik dashboard does not show any errors. I see my configuration.
Thanks for the help.

Related

Port forwarding problem using Traefik and docker-compose

I want the next port forwarding:
http://traefik.service.localhost/ -> Traefik UI
http://api.service.localhost/ -> 'Hello-Word' page from api-service
Here is my attempt to create appropriate docker-compose.yml file:
version: '3.8'
services:
reverse-proxy:
image: traefik:v2.4
container_name: reverse-proxy
command:
- "--api.insecure=true"
- "--providers.docker"
ports:
- "80:80"
- "8080:8080"
labels:
- traefik.enable=true
- traefik.docker.network=pred-network
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- pred-network
api-service:
image: x86_64/prediction-service:0.8.1
container_name: api-service
environment:
SERVING_SERVICE: model-service
expose:
- 80
labels:
- traefik.enable=true
- traefik.http.routers.api-service.rule=Host(`api.service.localhost`)
networks:
- pred-network
networks:
pred-network:
I am getting the following:
http://traefik.service.localhost/ -> HTTP Error 404. The requested resource is not found.
http://api.service.localhost/ -> HTTP Error 404. The requested resource is not found.
The only link that actually works:
http://api.service.localhost:8080/ -> Traefik UI
If I would include:
ports:
- "8070:80"
into api-service part of docker-compose.yml I could access my 'Hello-Word':
http://localhost:8070/ -> "Hello-Word"
In this case it not get routed through Traefik but directly through api-service. Is it possible to do it over Traefik?
To have a service routed by traefik with docker, you should have labels. Traefik will fetch those labels in order to know how to do routing.
Thus, to have request of api.service.localhost routed to your api service, you should have the label that define the corresponding rule:
traefik.http.routers.service.rule=Host(`api.service.localhost`)
As for the label of Traefik, you should have two labels:
traefik.http.routers.traefik.rule=Host(`traefik.service.localhost`)
traefik.http.routers.traefik.service=api#internal
Beside those traefik labels, you should tell traefik to expose the dashboard using a specific service by adding this configuration: --api.dashboard (More help to expose the dashboard here).
Note, if your api service uses another port than the one by default, you could add this label:
traefik.http.services.service.loadbalancer.server.port=80
Ps, do not expose twice the port 80, you only need to expose it for the traefik container.

Bad Gateway with Traefik and Docker Compose

I'm trying to deploy a React + FastApi + Postgres application on docker compose with Traefik as the reverse proxy. I'm running into issues with Bad Gateway errors. Running my FastAPI locally runs it on port 8888 and exposes the path /docs to view the api documentation. I'd like to eventually have the application running on example.local with the docs available on example.local/api/docs. My docker-compose.yaml is as follows (loosely based on this one):
version: '3.8'
services:
proxy:
image: traefik:v2.4
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- '80:80'
- '8080:8080'
- '443:443'
command:
- --providers.docker
- --api.insecure=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=web
- --entrypoints.web.address=:80
labels:
- traefik.enable=true
- traefik.http.routers.example-proxy-http.rule=Host(`example.local`)
- traefik.http.routers.example-proxy-http.entrypoints=web
- traefik.http.services.example-proxy.loadbalancer.server.port=80
backend:
build:
context: ./backend
dockerfile: Dockerfile
command: python app/main.py
volumes:
- ./backend/app:/app
env_file:
- .env
networks:
- web
- backend
labels:
- traefik.enable=true
- traefik.http.routers.example-backend-http.rule=PathPrefix(`api/docs`)
- traefik.http.routers.example-backend-http.entrypoints=web
- traefik.http.services.example-backend.loadbalancer.server.port=8888
networks:
web:
external: true
backend:
external: false
I've added 127.0.0.1 example.local to my /etc/hosts file.
From reading around it seems like Bad Gateway errors tend to occur from traefik and related services not being on the same network, or traefik routing traffic to the wrong port on the service container. However if I set ports: - '8888:8888' in my backend service I can access the docs from localhost:8888/docs so I'm pretty sure 8888 is the correct port for the backend loadbalancer. From what I can see traefik and the backend service are on the same network too and I've set it as the default traefik network with --providers.docker.network=web. Interestingly if I visit localhost/api/docs in my browser I'm served up a page from FastAPI. So it could be an issue with my traefik http router labels? I'm quite new to traefik and proxies so would appreciate any help or guidance, thanks!
UPDATE
If I specify the host for the backend by adding
- traefik.http.routers.infilmation-backend-http.rule=Host(`example.local`) && PathPrefix(`/docs`)
to the backend service labels, then visiting example.local/docs does serve up page from FastApi. So I guess my question would be what is the best way of setting up a host for this application? Is there a way I can specify a default host for all services then any PathPrefix rules would be in relation to that host?

Port forwarding with traefik and docker-compose

I would like to serve a docker-compose service through traefik with port-forwarding. I had many tries and the best I could achieve from now is described below:
First I create two networks:
docker network create frontend # To expose traefik
docker network create backend # To bind backend services
The traefik configuration is about (development, dashboard enabled at :8080):
version: "3.6"
services:
proxy:
image: traefik:latest
restart: unless-stopped
command:
- "--log.level=DEBUG"
- "--api"
- "--api.dashboard"
- "--api.insecure"
- "--providers.docker"
- "--providers.docker.exposedbydefault=false"
# Service entrypoint:
- "--entrypoints.lora-server.address=:8090"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
labels:
- "traefik.enable=true"
- "traefik.docker.network=frontend"
- "traefik.http.routers.traefik.entrypoints=traefik"
- "traefik.http.routers.traefik.service=api#internal"
networks:
- backend
- frontend
ports:
- "8080:8080"
- "8090:8090"
networks:
frontend:
external: true
backend:
external: true
The backend service is described here (a fork from ChripStack but it could be anything else):
version: "3"
services:
# [...]
chirpstack-application-server:
image: chirpstack/chirpstack-application-server:3
networks:
- backend
volumes:
- ./configuration/chirpstack-application-server:/etc/chirpstack-application-server
labels:
- "traefik.enable=true"
- "traefik.docker.network=backend"
- "traefik.http.routers.chirpstack.entrypoints=lora-server"
- "traefik.http.routers.chirpstack.rule=Host(`{host:}`)"
- "traefik.http.routers.chirpstack.service=chirpstack-application-server#docker"
- "traefik.http.services.chirpstack-application-server.loadbalancer.server.port=8080"
# [...]
networks:
backend:
external: true
The service also natively run on :8080 and I would like to access it on :8090 through traefik.
When I run both applications, traefik registers the new service and does not complain (no errors, no warning, the flow seems complete at least from the dashboard interface).
time="2020-07-30T11:47:47Z" level=debug msg="Creating middleware" middlewareType=Pipelining serviceName=chirpstack-application-server#docker entryPointName=lora-server routerName=chirpstack#docker middlewareName=pipelining
time="2020-07-30T11:47:47Z" level=debug msg="Creating load-balancer" entryPointName=lora-server routerName=chirpstack#docker serviceName=chirpstack-application-server#docker
time="2020-07-30T11:47:47Z" level=debug msg="Creating server 0 http://192.168.112.9:8080" entryPointName=lora-server routerName=chirpstack#docker serviceName=chirpstack-application-server#docker serverName=0
time="2020-07-30T11:47:47Z" level=debug msg="Added outgoing tracing middleware chirpstack-application-server#docker" middlewareName=tracing entryPointName=lora-server routerName=chirpstack#docker middlewareType=TracingForwarder
But I could not access the service, I am geting 404 errors when I try to connect http://host:8090.
To my understanding, it seems traefik does not know how it should complete the flow between the two networks: http://frontend:8090 -> http://backend:8080 (because I haven't referenced it anywhere).
What should I change in my configuration to make it work? How can I specify to traefik that it must route the HTTP traffic from frontend:8090 to backend:8080? Your help is much appreciated.
Traefik listens on some port, that's the only thing defined with entrypoints. You don't specify network for this incoming requests, because it's unrelated. traefik.docker.network is only used for routing after Traefik handles the incoming requests.
So the correct flow is not http://frontend:8090 -> http://backend:8080, but http://host:8090 -> http://backend:8080.
I think your configuration is correct. The only thing which seems to be odd is usage of Host rule. Maybe try to change it to something like this:
"traefik.http.routers.chirpstack.rule=hostregexp(`{host:.+}`)"

Debugging Traefik when the Site Cannot Be Reached from outside Company's Intranet

Using docker-compose I have deployed a web application that uses Traefik as the reverse proxy, listening on port 80. This works without problem when I'm inside my company's intranet. Outside of the intranet, however, I get a 'site cannot be reached' response. Pinging the address from outside shows that the address is reachable and port 80 is open.
I've also tried to use segments in my Traefik configuration to route both the internal and external hostname I have been provided but this has no effect:
version: "3.5"
services:
test:
image: emilevauge/whoami
deploy:
labels:
traefik.enable: "true"
traefik.foo.frontend.rule: "Host:${HOSTNAME};PathPrefixStrip:/test"
traefik.bar.frontend.rule: "Host:${EXTERNAL_HOSTNAME};PathPrefixStrip:/test"
traefik.port: 80
networks:
- frontend
...
I have configured the access logs to see if my requests are reaching Traefik, can anyone advise me what I should be looking for and how to filter the huge amount of text produced to find it? This is my Traefik setup configuration:
version: '3.5'
services:
traefik:
image: traefik:alpine
command: |-
--entryPoints="Name:http Address::80"
--entryPoints="Name:https Address::443 TLS"
--defaultentrypoints="http,https"
--acme
--acme.acmelogging="true"
--acme.domains="${HOSTNAME}"
--acme.domains="${EXTERNAL_HOSTNAME}"
--acme.email="${ACME_EMAIL}"
--acme.entrypoint="https"
--acme.httpchallenge
--acme.httpchallenge.entrypoint="http"
--acme.storage="/opt/traefik/acme.json"
--acme.onhostrule="true"
--docker
--docker.swarmmode
--docker.domain="${HOSTNAME}"
--docker.network="frontend"
--docker.watch
--api
--api.statistics
--logLevel="DEBUG"
networks:
- frontend

Keycloak behind Kong and strange redirect

Setup:
minikube version: v0.27.0
Kong (helm install stable/kong) / version 1.0.2
Keycloak (helm install stable/keycloak) / version 4.8.3.Final
I have a self signed SSL certificate for my "hello.local".
What I need to achieve: Keycloak behind Kong at "https://hello.local/".
My steps:
1) fresh minikube
2) Install Keycloak with helm, following values.yaml:
keycloak:
basepath: ""
replicas: 1
...
extraEnv: |
- name: PROXY_ADDRESS_FORWARDING
value: "true"
(that would create service auth-keycloak-http)
3) Install Kong with helm, following values.yaml:
replicaCount: 1
admin:
ingress:
enabled: true
hosts: ['hello.local']
proxy:
type: LoadBalancer
ingress:
enabled: true
hosts: ['hello.local']
tls:
- hosts:
- hello.local
secretName: tls-certificate
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
tls:
enabled: true
postgresql:
...
4) I setup service and route for Kong
Service:
Protocol: http
Host: auth-keycloak-http
Port: 80
Route:
Hosts: hello.local
After that I can open "https://hello.local" and can see welcome page from Keycloak where I can click Administration Console and after that I have redirect to "https://hello.local:8443/admin/master/console/" in my browser. So we should not have redirect with another port at this point.
Setup with 2 docker images (Keycloak + Kong) is working if PROXY_ADDRESS_FORWARDING is true.
How can I make Keycloak (helm chart) to work behind Kong (helm chart) in kubernetes cluster as expected, without redirect?
This is being discussed in github issue 1, github issue 2 and github issue 3. Also, Similar questions on stackoverflow
Original answer:
Seems, it is necessary to setup following environment variables in values.yaml of keycloak helm chart:
...
extraEnv: |
- name: KEYCLOAK_HTTP_PORT
value: "80"
- name: KEYCLOAK_HTTPS_PORT
value: "443"
- name: KEYCLOAK_HOSTNAME
value: example.com
...
All of them are required, after that, redirect would work correctly.
Added 2021 Sep:
Issue with weird behavior with redirect to port 8443 for some action (like go to Account management with the link on the top right of admin console).
In fact we do not need to set any KEYCLOAK_HTTP_PORT or KEYCLOAK_HTTPS_PORT.
Some changes are required on proxy side. On proxy we need to set x-forwarded-port to 443 for this route.
In my case we use Kong:
On the route, where Keycloak is exposed, we need to add (this one worked for me):
serverless > post function with following content:
ngx.var.upstream_x_forwarded_port=443
More info on KONG and x_forwarded_*