Occasional blog posts from a random systems engineer

Using labels in traefik rules using consulcatalog

· Read in about 2 min · (322 Words)

Traefik’s ConsulCatalog plugin provides a defaultRule parameter, which is applied by default to exposed services.

The example from the docs (https://doc.traefik.io/traefik/providers/consul-catalog/#defaultrule), suggests:

For a given service, if no routing rule was defined by a tag, it is defined by this defaultRule instead. The defaultRule must be set to a valid Go template, and can include sprig template functions. The service name can be accessed with the Name identifier, and the template has access to all the labels (i.e. tags beginning with the prefix) defined on this service.

For simple configurations that use the service name in the rule, e.g. Host(`{{ .Name }}.example.com`), this is obvious how it works.

However, to use the labels, the description and the example Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`) does not make it obvious how this works.

To get this working, there’s three things that I’ve found that are important (some more obvious than others :) )

Tag prefix

Ensure all tags for services are prefixed with the ‘prefix’ (https://doc.traefik.io/traefik/providers/consul-catalog/#prefix)

E.g. if prefix is blah, the tags must be along the lines of blah-my-label.

Keep in mind, there’s nothing fancy going on with the dashes, so blahtest will match. If you care about this, prepend a dash to the prefix config.

The tag is also not manipulated in any way with regards to the prefix. This means that a tag myprefix-my-label will result in a label myprefix-my-label.

Built-in prefixing

When using the example rule, Host(`{{ index .Labels \"myLabel" }}`), from testing, this will never work. Consul prepends all labels with an additional: traefik..

This means, if you have:

  • prefix config: myprefix
  • tag: myprefix-mylabel=test the resulting “label” will actually be: traefik.myprefix-mylabel, so your rule would look something like: Host(`{{ index .Labels \"traefik.myprefix-mylabel\" }}`)

Debugging

Whilst attempting to figure this out, I found that I could dump the whole map into the rule, by using a defaultRule: Host(`{{ .Labels }}`), which produced a rule:

Host(`map[traefik.traefik-mytestlabel:mytestvalue]`)

and answered everything :D

Comments