clarify automatic service creation/assignment with labels

This commit is contained in:
mpl 2019-09-26 12:48:05 +02:00 committed by Traefiker Bot
parent c8fa059064
commit c6e783e7c3
6 changed files with 156 additions and 5 deletions

View file

@ -87,7 +87,7 @@ Attach labels to your containers and let Traefik do the rest!
!!! info "Labels" !!! info "Labels"
- Labels are case insensitive. - Labels are case insensitive.
- The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/docker.md) - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/docker.md).
### General ### General
@ -96,6 +96,32 @@ Traefik creates, for each container, a corresponding [service](../services/index
The Service automatically gets a server per instance of the container, The Service automatically gets a server per instance of the container,
and the router automatically gets a rule defined by `defaultRule` (if no rule for it was defined in labels). and the router automatically gets a rule defined by `defaultRule` (if no rule for it was defined in labels).
#### Service definition
--8<-- "content/routing/providers/service-by-label.md"
??? example "Automatic service assignment with labels"
With labels in a compose file
```yaml
labels:
- "traefik.http.routers.myproxy.rule=Host(`foo.com`)"
# service myservice gets automatically assigned to router myproxy
- "traefik.http.services.myservice.loadbalancer.server.port=80"
```
??? example "Automatic service creation and assignment with labels"
With labels in a compose file
```yaml
labels:
# no service specified or defined and yet one gets automatically created
# and assigned to router myproxy.
- "traefik.http.routers.myproxy.rule=Host(`foo.com`)"
```
### Routers ### Routers
To update the configuration of the Router automatically attached to the container, To update the configuration of the Router automatically attached to the container,

View file

@ -10,7 +10,7 @@ See also [Marathon user guide](../../user-guides/marathon.md).
!!! info "Labels" !!! info "Labels"
- Labels are case insensitive. - Labels are case insensitive.
- The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/marathon.md) - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/marathon.md).
### General ### General
@ -19,6 +19,32 @@ Traefik creates, for each Marathon application, a corresponding [service](../ser
The Service automatically gets a server per instance of the application, The Service automatically gets a server per instance of the application,
and the router automatically gets a rule defined by defaultRule (if no rule for it was defined in labels). and the router automatically gets a rule defined by defaultRule (if no rule for it was defined in labels).
#### Service definition
--8<-- "content/routing/providers/service-by-label.md"
??? example "Automatic service assignment with labels"
Service myservice gets automatically assigned to router myproxy.
```json
labels: {
"traefik.http.routers.myproxy.rule": "Host(`foo.com`)",
"traefik.http.services.myservice.loadbalancer.server.port": "80"
}
```
??? example "Automatic service creation and assignment with labels"
No service specified or defined, and yet one gets automatically created.
and assigned to router myproxy.
```json
labels: {
"traefik.http.routers.myproxy.rule": "Host(`foo.com`)"
}
```
### Routers ### Routers
To update the configuration of the Router automatically attached to the application, To update the configuration of the Router automatically attached to the application,

View file

@ -17,7 +17,7 @@ Attach labels to your services and let Traefik do the rest!
!!! info "Labels" !!! info "Labels"
- Labels are case insensitive. - Labels are case insensitive.
- The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/rancher.md) - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/rancher.md).
### General ### General
@ -25,6 +25,32 @@ Traefik creates, for each rancher service, a corresponding [service](../services
The Service automatically gets a server per container in this rancher service, and the router gets a default rule attached to it, based on the service name. The Service automatically gets a server per container in this rancher service, and the router gets a default rule attached to it, based on the service name.
#### Service definition
--8<-- "content/routing/providers/service-by-label.md"
??? example "Automatic service assignment with labels"
With labels in a compose file
```yaml
labels:
- "traefik.http.routers.myproxy.rule=Host(`foo.com`)"
# service myservice gets automatically assigned to router myproxy
- "traefik.http.services.myservice.loadbalancer.server.port=80"
```
??? example "Automatic service creation and assignment with labels"
With labels in a compose file
```yaml
labels:
# no service specified or defined and yet one gets automatically created
# and assigned to router myproxy.
- "traefik.http.routers.myproxy.rule=Host(`foo.com`)"
```
### Routers ### Routers
To update the configuration of the Router automatically attached to the container, add labels starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change. To update the configuration of the Router automatically attached to the container, add labels starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change.

View file

@ -0,0 +1,16 @@
In general when configuring a Traefik provider,
a service assigned to one (or several) router(s) must be defined as well for the routing to be functional.
There are, however, exceptions when using label-based configurations:
1. If a label defines a router (e.g. through a router Rule)
and a label defines a service (e.g. implicitly through a loadbalancer server port value),
but the router does not specify any service,
then that service is automatically assigned to the router.
1. If a label defines a router (e.g. through a router Rule)
but no service is defined, then a service is automatically created
and assigned to the router.
!!! info ""
As one would expect, in either of these cases, if in addition a service is specified for the router,
then that service is the one assigned, regardless of whether it actually is defined or whatever else other services are defined.

View file

@ -288,8 +288,14 @@ The middlewares will take effect only if the rule matches, and before forwarding
### Service ### Service
You must attach a [service](../services/index.md) per router. Each request must eventually be handled by a [service](../services/index.md),
Services are the target for the router. which is why each router definition should include a service target,
which is basically where the request will be passed along to.
In general, a service assigned to a router should have been defined,
but there are exceptions for label-based providers.
See the specific [docker](../providers/docker.md#service-definition), [rancher](../providers/rancher.md#service-definition),
or [marathon](../providers/marathon.md#service-definition) documentation.
!!! important "HTTP routers can only target HTTP services (not TCP services)." !!! important "HTTP routers can only target HTTP services (not TCP services)."

View file

@ -798,6 +798,57 @@ func Test_buildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "one router, one specified but undefined service -> specified one is assigned, but automatic is created instead",
containers: []dockerData{
{
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.routers.Router1.rule": "Host(`foo.com`)",
"traefik.http.routers.Router1.service": "Service1",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
Addr: "127.0.0.1",
},
},
},
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Router1": {
Service: "Service1",
Rule: "Host(`foo.com`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://127.0.0.1:80",
},
},
PassHostHeader: true,
},
},
},
},
},
},
{ {
desc: "two containers with same service name and different passhostheader", desc: "two containers with same service name and different passhostheader",
containers: []dockerData{ containers: []dockerData{