Traefik 2.0 and Docker set middleware without naming the router - docker

I'm using traefik 2.0 with docker provider (swarm mode) and I wish to provide a default way for services publishing themselves on traefik avoiding conflicts.
I managed to create a default rule matching my needs, but I'm now struggling because I don't see a way to provide a default middleware to strip away prefixes.
Is there a way to add a docker service label without having to provide a specific router name, but still adding a middleware to whatever router was implicitly created by traefik?
Or is there a way to define a default middleware as there is for the default rule?
The solution I'm trying to approach is to remove all the variable substitutions in the following labels, thus reducing the verbosity of the whole definition but without exposing myself to naming conflicts:
- traefik.enable=true
- traefik.http.services.${ENV:-dev}_${STACK}_whoami.loadbalancer.server.port=80
- traefik.http.middlewares.${ENV:-dev}_${STACK}_whoami.stripprefix.prefixes=/${STACK}
- traefik.http.routers.${ENV:-dev}_${STACK}_whoami.entrypoints=http
- traefik.http.routers.${ENV:-dev}_${STACK}_whoami.rule=PathPrefix(`/${STACK}/whoami`)
- traefik.http.routers.${ENV:-dev}_${STACK}_whoami.middlewares=${ENV:-dev}_${STACK}_whoami#docker
Hoping it could become something like the following, where default is the magic word for using the implicit service name assigned by Docker when deploying the stack:
- traefik.enable=true
- traefik.http.services.default.loadbalancer.server.port=80
- traefik.http.middlewares.default.stripprefix.prefixes=/${STACK}
- traefik.http.routers.default.entrypoints=http
- traefik.http.routers.default.rule=PathPrefix(`/${STACK}/whoami`)
- traefik.http.routers.default.middlewares=default#docker
I tried the following, but apparently the go template doesn't get replaced:
- traefik.enable=true
- traefik.http.services.{{ .Name }}.loadbalancer.server.port=80
- traefik.http.middlewares.{{ .Name }}.stripprefix.prefixes=/${STACK}
- traefik.http.routers.{{ .Name }}.entrypoints=http
- traefik.http.routers.{{ .Name }}.rule=PathPrefix(`/${STACK}/whoami`)
- traefik.http.routers.{{ .Name }}.middlewares={{ .Name }}#docker

I didn't tested it but according to this doc, Go templating is only supported in dynamic (Yaml/Toml) configuration file.
So I suggest you try to add a dynamic configuration file (see here) and write something like :
http:
routers:
{{range $i, $e := until 100 }}
router{{ $e }}:
middlewares = {{ $e }}
{{end}}
Hopes this can help

Related

How to access self variable array type?

I have defined subnetIds in serverless:
enviroment:
subnetIds:
- subnet1
- subnet2
Now, at function define enviroment, I want to get each subnet like that:
environment:
SUBNET_ID_1: ${self:enviroment.subnetIds[0]}
SUBNET_ID_2: ${self:enviroment.subnetIds[1]}
I am looking for a solution that can do it.
Thank for support. I had found a solution to resolve it. Just define like that:
environment:
SUBNET_ID_1: ${self:enviroment.subnetIds.0}
SUBNET_ID_2: ${self:enviroment.subnetIds.1}
once you have the env variables set in the provider "environment" you do not need to assign it to each function.
provider:
enviroment:
subnet1
subnet2
and use it as
process.env[subnet1]
process.env[subnet2]
There is no way you can direct self refer from provider -> environment. But you can do it this way.
provider:
environment:
subnetIds:
- ${self:custom.subnet1}
- ${self:custom.subnet2}
functions:
hello:
environment:
SUBNET_ID_1: ${self:custom.subnet1}
SUBNET_ID_2: ${self:custom.subnet2}
custom:
subnet1: "subnet1 value"
subnet2: "subnet2 value"
Another thing also worth to highlight is the provider -> environment will be available in all functions by default. So you need to think again do you really need to re-declare again?

Change default freeradius auth and acct port in CoovaChilli

So I have two freeradius / radiusdesk installations on the server.
First one is old one and uses default freeradius ports: 1812/1813 for Auth/Acct.
The second one is the new once and using ports: 10001/10002 for Auth/Acct.
The issue now is that on my router, CoovaChili is always connection to the first one ( old one ) and communicating on the ports 1812/1813. I want to change it's ports. But it doesn't seems to be working. The OS is OpenWrt.
In my /etc/config/chilli i have added the following lines:
option radiusauthport 10001
option radiusacctport 10002
But is is not working. CoovaChilli still sends request to the old 1812/1813 ports. I want to know how to change that so it communicates with my defined port numbers, rather than the default ones.
Looking for the configurations to fix it.
Thanks
Looking at the OpernWRT guide at https://openwrt.org/docs/guide-user/services/captive-portal/wireless.hotspot.coova-chilli, it seems that you need to put the value parameter inside double quotes.
Specifically
option radiusauthport "10001"
option radiusacctport "10002

Traefik(+Docker) path settings for root and subfolders dispatch

With making reverse proxy on Docker and Traefik, I want to dispatch several paths on the same host into two different backend servers like these,
1. traefik.test/ -> app1/
2. traefik.test/post/blabla -> app1/post/blabla
3. traefik.test/user/blabla -> app2/user/blabla
If the rules are only #2 and #3, I could do like this in docker-compose.yml
app1:
image: akky/app1
labels:
- "traefik.backend=app1"
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/post,/comment"
app2:
image: akky/app2
labels:
- "traefik.backend=app2"
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/user,/group"
However, adding the root '/' into the first PathPrefix seems to cloak /user on app2. The following does not work, and everything goes to app1 backend.
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/,/post,/group"
The rules "Host:" and "PathPrefix" seems working as 'AND', but I wanted to use 'OR' ( exact /, OR starting with /post ). I searched and came to know that multiple rules can be directed since version 1.3.0, according to pull request #1257 by making multiple lines with adding service names.
By knowing that, what I did is like this,
app1:
image: akky/app1
labels:
- "traefik.app1_subfolder.backend=app1"
- "traefik.app1_subfolder.frontend.rule=Host:traefik.test;PathPrefix:/post,/group"
- "traefik.app1_rootfolder.backend=app1"
- "traefik.app1_rootfolder.frontend.rule=Host:traefik.test;Path:/"
app2:
image: akky/app2
labels:
- "traefik.backend=app2"
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/user"
Now it works as required, the root access is dispatched to app1/ .
My question is, is this the proper way? It does not look like so for me, as this root and subfolder dispatch should be a typical use case.
You might consider adding priority labels so the app2 rules take precedence over app1 rules. Then you should be able to simplify the app1 config.
app1:
image: akky/app1
labels:
- "traefik.backend=app1"
- "traefik.frontend.priority=10"
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/,/post,/group"
app2:
image: akky/app2
labels:
- "traefik.backend=app2"
- "traefik.frontend.priority=50"
- "traefik.frontend.rule=Host:traefik.test;PathPrefix:/user"
Update: I had the priorities in the wrong order. Larger priority values take precedence over smaller priority values. According to the docs, it's based on (priority + rule length), and the larger value wins.

Prometheus relabeling not working as expected

I would like to employ Prometheus' relabeling for adding a label hostname, which should be a more concise version of instance as provided by targets. This should allow more compact legends in Grafana dashboards.
For instance, when __address__ has been set to myhost.mydomain.com:8080, hostname should be set to myhost. I am using __address__ rather than instance as source_label, because the second is apparently not yet set when relabeling occurs.
The relevant excerpt of my prometheus.yaml looks as follows (it is meant to employ a lazy regular expression):
- job_name: 'node_exporter'
static_configs:
- targets: ['myhost1.mydomain.com:8080',
'myhost2.mydomain.com:8080']
relabel_configs:
- source_labels: ['__address__']
regex: '^([^\.:]+?)'
replacement: ${1}
target_label: 'hostname'
The expected new label hostname is not yet added. What could be wrong in my setup?
With this regex (with a non-capturing group) things have come to work: '(.+?)(?:[\\.:].+)?'.

Use Prometheus "target relabeling" to extract cAdvisor's Docker image name without tag

I use Prometheus, together with cAdvisor to monitor my environment.
Now, I tried to use Prometheus' "target relabeling", and create a label that its value is the Docker container's image name, without a tag. It is based on the originally scraped image label.
It doesn't work, for some reason, showing no errors when running on debug log level. I can see metrics scraped from cAdvisor (for example container_last_seen) but my newly created label isn't there.
My job configuration:
- job_name: "cadvisor"
scrape_interval: "5s"
dns_sd_configs:
- names: ['cadvisor.marathon.mesos']
relabel_configs:
- source_labels: ['image']
# [REGISTRYHOST/][USERNAME/]NAME[:TAG]
regex: '([^/]+/)?([^/]+/)?([^:]+)(:.+)?'
target_label: 'image_tagless'
replacement: '${1}${2}${3}'
My label - image_tagless - is missing from the scraped metrics.
Any help would be much appreciated.
The image label is not a target label, it's on the metrics themselves. Thus you should use metric_relabel_configs rather than relabel_configs
My blog on Life of a Label explains how this works.

Resources