Fix empty IP for backend when dnsrr in Docker swarm mode
This commit is contained in:
parent
aaf120f263
commit
d6ad7e2e64
2 changed files with 133 additions and 14 deletions
|
@ -749,7 +749,7 @@ func listServices(ctx context.Context, dockerClient client.APIClient) ([]dockerD
|
|||
|
||||
networkMap := make(map[string]*dockertypes.NetworkResource)
|
||||
if err != nil {
|
||||
log.Debug("Failed to network inspect on client for docker, error: %s", err)
|
||||
log.Debugf("Failed to network inspect on client for docker, error: %s", err)
|
||||
return []dockerData{}, err
|
||||
}
|
||||
for _, network := range networkList {
|
||||
|
@ -762,16 +762,18 @@ func listServices(ctx context.Context, dockerClient client.APIClient) ([]dockerD
|
|||
|
||||
for _, service := range serviceList {
|
||||
dockerData := parseService(service, networkMap)
|
||||
useSwarmLB, _ := strconv.ParseBool(getIsBackendLBSwarm(dockerData))
|
||||
isGlobalSvc := service.Spec.Mode.Global != nil
|
||||
if len(dockerData.NetworkSettings.Networks) > 0 {
|
||||
useSwarmLB, _ := strconv.ParseBool(getIsBackendLBSwarm(dockerData))
|
||||
|
||||
if useSwarmLB {
|
||||
dockerDataList = append(dockerDataList, dockerData)
|
||||
} else {
|
||||
dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap, isGlobalSvc)
|
||||
if useSwarmLB {
|
||||
dockerDataList = append(dockerDataList, dockerData)
|
||||
} else {
|
||||
isGlobalSvc := service.Spec.Mode.Global != nil
|
||||
dockerDataListTasks, err = listTasks(ctx, dockerClient, service.ID, dockerData, networkMap, isGlobalSvc)
|
||||
|
||||
for _, dockerDataTask := range dockerDataListTasks {
|
||||
dockerDataList = append(dockerDataList, dockerDataTask)
|
||||
for _, dockerDataTask := range dockerDataListTasks {
|
||||
dockerDataList = append(dockerDataList, dockerDataTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -787,10 +789,9 @@ func parseService(service swarmtypes.Service, networkMap map[string]*dockertypes
|
|||
}
|
||||
|
||||
if service.Spec.EndpointSpec != nil {
|
||||
switch service.Spec.EndpointSpec.Mode {
|
||||
case swarmtypes.ResolutionModeDNSRR:
|
||||
log.Debug("Ignored endpoint-mode not supported, service name: %s", dockerData.Name)
|
||||
case swarmtypes.ResolutionModeVIP:
|
||||
if service.Spec.EndpointSpec.Mode == swarmtypes.ResolutionModeDNSRR {
|
||||
log.Warnf("Ignored endpoint-mode not supported, service name: %s", service.Spec.Annotations.Name)
|
||||
} else if service.Spec.EndpointSpec.Mode == swarmtypes.ResolutionModeVIP {
|
||||
dockerData.NetworkSettings.Networks = make(map[string]*networkData)
|
||||
for _, virtualIP := range service.Endpoint.VirtualIPs {
|
||||
networkService := networkMap[virtualIP.NetworkID]
|
||||
|
@ -803,7 +804,7 @@ func parseService(service swarmtypes.Service, networkMap map[string]*dockertypes
|
|||
}
|
||||
dockerData.NetworkSettings.Networks[network.Name] = network
|
||||
} else {
|
||||
log.Debug("Network not found, id: %s", virtualIP.NetworkID)
|
||||
log.Debugf("Network not found, id: %s", virtualIP.NetworkID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
dockertypes "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
@ -765,3 +767,119 @@ func TestListTasks(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeServicesClient struct {
|
||||
dockerclient.APIClient
|
||||
dockerVersion string
|
||||
networks []dockertypes.NetworkResource
|
||||
services []swarm.Service
|
||||
err error
|
||||
}
|
||||
|
||||
func (c *fakeServicesClient) ServiceList(ctx context.Context, options dockertypes.ServiceListOptions) ([]swarm.Service, error) {
|
||||
return c.services, c.err
|
||||
}
|
||||
|
||||
func (c *fakeServicesClient) ServerVersion(ctx context.Context) (dockertypes.Version, error) {
|
||||
return dockertypes.Version{APIVersion: c.dockerVersion}, c.err
|
||||
}
|
||||
|
||||
func (c *fakeServicesClient) NetworkList(ctx context.Context, options dockertypes.NetworkListOptions) ([]dockertypes.NetworkResource, error) {
|
||||
return c.networks, c.err
|
||||
}
|
||||
|
||||
func TestListServices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
services []swarm.Service
|
||||
dockerVersion string
|
||||
networks []dockertypes.NetworkResource
|
||||
expectedServices []string
|
||||
}{
|
||||
{
|
||||
desc: "Should return no service due to no networks defined",
|
||||
services: []swarm.Service{
|
||||
swarmService(
|
||||
serviceName("service1"),
|
||||
serviceLabels(map[string]string{
|
||||
labelDockerNetwork: "barnet",
|
||||
labelBackendLoadBalancerSwarm: "true",
|
||||
}),
|
||||
withEndpointSpec(modeVIP),
|
||||
withEndpoint(
|
||||
virtualIP("1", "10.11.12.13/24"),
|
||||
virtualIP("2", "10.11.12.99/24"),
|
||||
)),
|
||||
swarmService(
|
||||
serviceName("service2"),
|
||||
serviceLabels(map[string]string{
|
||||
labelDockerNetwork: "barnet",
|
||||
}),
|
||||
withEndpointSpec(modeDNSSR)),
|
||||
},
|
||||
dockerVersion: "1.30",
|
||||
networks: []dockertypes.NetworkResource{},
|
||||
expectedServices: []string{},
|
||||
},
|
||||
{
|
||||
desc: "Should return only service1",
|
||||
services: []swarm.Service{
|
||||
swarmService(
|
||||
serviceName("service1"),
|
||||
serviceLabels(map[string]string{
|
||||
labelDockerNetwork: "barnet",
|
||||
labelBackendLoadBalancerSwarm: "true",
|
||||
}),
|
||||
withEndpointSpec(modeVIP),
|
||||
withEndpoint(
|
||||
virtualIP("yk6l57rfwizjzxxzftn4amaot", "10.11.12.13/24"),
|
||||
virtualIP("2", "10.11.12.99/24"),
|
||||
)),
|
||||
swarmService(
|
||||
serviceName("service2"),
|
||||
serviceLabels(map[string]string{
|
||||
labelDockerNetwork: "barnet",
|
||||
}),
|
||||
withEndpointSpec(modeDNSSR)),
|
||||
},
|
||||
dockerVersion: "1.30",
|
||||
networks: []dockertypes.NetworkResource{
|
||||
{
|
||||
Name: "network_name",
|
||||
ID: "yk6l57rfwizjzxxzftn4amaot",
|
||||
Created: time.Now(),
|
||||
Scope: "swarm",
|
||||
Driver: "overlay",
|
||||
EnableIPv6: false,
|
||||
Internal: true,
|
||||
Ingress: false,
|
||||
ConfigOnly: false,
|
||||
Options: map[string]string{
|
||||
"com.docker.network.driver.overlay.vxlanid_list": "4098",
|
||||
"com.docker.network.enable_ipv6": "false",
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"com.docker.stack.namespace": "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedServices: []string{
|
||||
"service1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for caseID, test := range testCases {
|
||||
test := test
|
||||
t.Run(strconv.Itoa(caseID), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dockerClient := &fakeServicesClient{services: test.services, dockerVersion: test.dockerVersion, networks: test.networks}
|
||||
serviceDockerData, _ := listServices(context.Background(), dockerClient)
|
||||
|
||||
assert.Equal(t, len(test.expectedServices), len(serviceDockerData))
|
||||
for i, serviceName := range test.expectedServices {
|
||||
assert.Equal(t, serviceName, serviceDockerData[i].Name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue