github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/integration/network/service_test.go (about)

     1  package network // import "github.com/docker/docker/integration/network"
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	swarmtypes "github.com/docker/docker/api/types/swarm"
    10  	"github.com/docker/docker/api/types/versions"
    11  	"github.com/docker/docker/client"
    12  	"github.com/docker/docker/integration/internal/network"
    13  	"github.com/docker/docker/integration/internal/swarm"
    14  	"github.com/docker/docker/internal/test/daemon"
    15  	"gotest.tools/assert"
    16  	"gotest.tools/icmd"
    17  	"gotest.tools/poll"
    18  	"gotest.tools/skip"
    19  )
    20  
    21  // delInterface removes given network interface
    22  func delInterface(t *testing.T, ifName string) {
    23  	icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success)
    24  	icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success)
    25  	icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success)
    26  }
    27  
    28  func TestDaemonRestartWithLiveRestore(t *testing.T) {
    29  	skip.If(t, testEnv.OSType == "windows")
    30  	skip.If(t, testEnv.IsRemoteDaemon)
    31  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    32  	d := daemon.New(t)
    33  	defer d.Stop(t)
    34  	d.Start(t)
    35  	d.Restart(t,
    36  		"--live-restore=true",
    37  		"--default-address-pool", "base=175.30.0.0/16,size=16",
    38  		"--default-address-pool", "base=175.33.0.0/16,size=24",
    39  	)
    40  
    41  	// Verify bridge network's subnet
    42  	c := d.NewClientT(t)
    43  	defer c.Close()
    44  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
    45  	assert.NilError(t, err)
    46  	// Make sure docker0 doesn't get override with new IP in live restore case
    47  	assert.Equal(t, out.IPAM.Config[0].Subnet, "172.18.0.0/16")
    48  }
    49  
    50  func TestDaemonDefaultNetworkPools(t *testing.T) {
    51  	skip.If(t, testEnv.OSType == "windows")
    52  	// Remove docker0 bridge and the start daemon defining the predefined address pools
    53  	skip.If(t, testEnv.IsRemoteDaemon)
    54  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    55  	defaultNetworkBridge := "docker0"
    56  	delInterface(t, defaultNetworkBridge)
    57  	d := daemon.New(t)
    58  	defer d.Stop(t)
    59  	d.Start(t,
    60  		"--default-address-pool", "base=175.30.0.0/16,size=16",
    61  		"--default-address-pool", "base=175.33.0.0/16,size=24",
    62  	)
    63  
    64  	c := d.NewClientT(t)
    65  	defer c.Close()
    66  
    67  	// Verify bridge network's subnet
    68  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
    69  	assert.NilError(t, err)
    70  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.30.0.0/16")
    71  
    72  	// Create a bridge network and verify its subnet is the second default pool
    73  	name := "elango" + t.Name()
    74  	network.CreateNoError(t, context.Background(), c, name,
    75  		network.WithDriver("bridge"),
    76  	)
    77  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
    78  	assert.NilError(t, err)
    79  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.0.0/24")
    80  
    81  	// Create a bridge network and verify its subnet is the third default pool
    82  	name = "saanvi" + t.Name()
    83  	network.CreateNoError(t, context.Background(), c, name,
    84  		network.WithDriver("bridge"),
    85  	)
    86  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
    87  	assert.NilError(t, err)
    88  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.1.0/24")
    89  	delInterface(t, defaultNetworkBridge)
    90  
    91  }
    92  
    93  func TestDaemonRestartWithExistingNetwork(t *testing.T) {
    94  	skip.If(t, testEnv.OSType == "windows")
    95  	skip.If(t, testEnv.IsRemoteDaemon)
    96  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    97  	defaultNetworkBridge := "docker0"
    98  	d := daemon.New(t)
    99  	d.Start(t)
   100  	defer d.Stop(t)
   101  	c := d.NewClientT(t)
   102  	defer c.Close()
   103  
   104  	// Create a bridge network
   105  	name := "elango" + t.Name()
   106  	network.CreateNoError(t, context.Background(), c, name,
   107  		network.WithDriver("bridge"),
   108  	)
   109  
   110  	// Verify bridge network's subnet
   111  	out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   112  	assert.NilError(t, err)
   113  	networkip := out.IPAM.Config[0].Subnet
   114  
   115  	// Restart daemon with default address pool option
   116  	d.Restart(t,
   117  		"--default-address-pool", "base=175.30.0.0/16,size=16",
   118  		"--default-address-pool", "base=175.33.0.0/16,size=24")
   119  
   120  	out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   121  	assert.NilError(t, err)
   122  	assert.Equal(t, out1.IPAM.Config[0].Subnet, networkip)
   123  	delInterface(t, defaultNetworkBridge)
   124  }
   125  
   126  func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
   127  	skip.If(t, testEnv.OSType == "windows")
   128  	skip.If(t, testEnv.IsRemoteDaemon)
   129  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
   130  	defaultNetworkBridge := "docker0"
   131  	d := daemon.New(t)
   132  	d.Start(t)
   133  	defer d.Stop(t)
   134  	c := d.NewClientT(t)
   135  	defer c.Close()
   136  
   137  	// Create a bridge network
   138  	name := "elango" + t.Name()
   139  	network.CreateNoError(t, context.Background(), c, name,
   140  		network.WithDriver("bridge"),
   141  	)
   142  
   143  	// Verify bridge network's subnet
   144  	out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   145  	assert.NilError(t, err)
   146  	networkip := out.IPAM.Config[0].Subnet
   147  
   148  	// Create a bridge network
   149  	name = "sthira" + t.Name()
   150  	network.CreateNoError(t, context.Background(), c, name,
   151  		network.WithDriver("bridge"),
   152  	)
   153  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   154  	assert.NilError(t, err)
   155  	networkip2 := out.IPAM.Config[0].Subnet
   156  
   157  	// Restart daemon with default address pool option
   158  	d.Restart(t,
   159  		"--default-address-pool", "base=175.18.0.0/16,size=16",
   160  		"--default-address-pool", "base=175.19.0.0/16,size=24",
   161  	)
   162  
   163  	// Create a bridge network
   164  	name = "saanvi" + t.Name()
   165  	network.CreateNoError(t, context.Background(), c, name,
   166  		network.WithDriver("bridge"),
   167  	)
   168  	out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   169  	assert.NilError(t, err)
   170  
   171  	assert.Check(t, out1.IPAM.Config[0].Subnet != networkip)
   172  	assert.Check(t, out1.IPAM.Config[0].Subnet != networkip2)
   173  	delInterface(t, defaultNetworkBridge)
   174  }
   175  
   176  func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
   177  	skip.If(t, testEnv.OSType == "windows")
   178  	skip.If(t, testEnv.IsRemoteDaemon)
   179  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
   180  	defaultNetworkBridge := "docker0"
   181  	d := daemon.New(t)
   182  	defer d.Stop(t)
   183  	d.Start(t,
   184  		"--bip=172.60.0.1/16",
   185  		"--default-address-pool", "base=175.30.0.0/16,size=16",
   186  		"--default-address-pool", "base=175.33.0.0/16,size=24",
   187  	)
   188  
   189  	c := d.NewClientT(t)
   190  	defer c.Close()
   191  
   192  	// Verify bridge network's subnet
   193  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
   194  	assert.NilError(t, err)
   195  	// Make sure BIP IP doesn't get override with new default address pool .
   196  	assert.Equal(t, out.IPAM.Config[0].Subnet, "172.60.0.1/16")
   197  	delInterface(t, defaultNetworkBridge)
   198  }
   199  
   200  func TestServiceWithPredefinedNetwork(t *testing.T) {
   201  	skip.If(t, testEnv.OSType == "windows")
   202  	defer setupTest(t)()
   203  	d := swarm.NewSwarm(t, testEnv)
   204  	defer d.Stop(t)
   205  	c := d.NewClientT(t)
   206  	defer c.Close()
   207  
   208  	hostName := "host"
   209  	var instances uint64 = 1
   210  	serviceName := "TestService" + t.Name()
   211  
   212  	serviceID := swarm.CreateService(t, d,
   213  		swarm.ServiceWithReplicas(instances),
   214  		swarm.ServiceWithName(serviceName),
   215  		swarm.ServiceWithNetwork(hostName),
   216  	)
   217  
   218  	poll.WaitOn(t, serviceRunningCount(c, serviceID, instances), swarm.ServicePoll)
   219  
   220  	_, _, err := c.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
   221  	assert.NilError(t, err)
   222  
   223  	err = c.ServiceRemove(context.Background(), serviceID)
   224  	assert.NilError(t, err)
   225  }
   226  
   227  const ingressNet = "ingress"
   228  
   229  func TestServiceRemoveKeepsIngressNetwork(t *testing.T) {
   230  	skip.If(t, testEnv.OSType == "windows")
   231  	defer setupTest(t)()
   232  	d := swarm.NewSwarm(t, testEnv)
   233  	defer d.Stop(t)
   234  	c := d.NewClientT(t)
   235  	defer c.Close()
   236  
   237  	poll.WaitOn(t, swarmIngressReady(c), swarm.NetworkPoll)
   238  
   239  	var instances uint64 = 1
   240  
   241  	serviceID := swarm.CreateService(t, d,
   242  		swarm.ServiceWithReplicas(instances),
   243  		swarm.ServiceWithName(t.Name()+"-service"),
   244  		swarm.ServiceWithEndpoint(&swarmtypes.EndpointSpec{
   245  			Ports: []swarmtypes.PortConfig{
   246  				{
   247  					Protocol:    swarmtypes.PortConfigProtocolTCP,
   248  					TargetPort:  80,
   249  					PublishMode: swarmtypes.PortConfigPublishModeIngress,
   250  				},
   251  			},
   252  		}),
   253  	)
   254  
   255  	poll.WaitOn(t, serviceRunningCount(c, serviceID, instances), swarm.ServicePoll)
   256  
   257  	ctx := context.Background()
   258  	_, _, err := c.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
   259  	assert.NilError(t, err)
   260  
   261  	err = c.ServiceRemove(ctx, serviceID)
   262  	assert.NilError(t, err)
   263  
   264  	poll.WaitOn(t, noServices(ctx, c), swarm.ServicePoll)
   265  	poll.WaitOn(t, swarm.NoTasks(ctx, c), swarm.ServicePoll)
   266  
   267  	// Ensure that "ingress" is not removed or corrupted
   268  	time.Sleep(10 * time.Second)
   269  	netInfo, err := c.NetworkInspect(ctx, ingressNet, types.NetworkInspectOptions{
   270  		Verbose: true,
   271  		Scope:   "swarm",
   272  	})
   273  	assert.NilError(t, err, "Ingress network was removed after removing service!")
   274  	assert.Assert(t, len(netInfo.Containers) != 0, "No load balancing endpoints in ingress network")
   275  	assert.Assert(t, len(netInfo.Peers) != 0, "No peers (including self) in ingress network")
   276  	_, ok := netInfo.Containers["ingress-sbox"]
   277  	assert.Assert(t, ok, "ingress-sbox not present in ingress network")
   278  }
   279  
   280  func serviceRunningCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result {
   281  	return func(log poll.LogT) poll.Result {
   282  		services, err := client.ServiceList(context.Background(), types.ServiceListOptions{})
   283  		if err != nil {
   284  			return poll.Error(err)
   285  		}
   286  
   287  		if len(services) != int(instances) {
   288  			return poll.Continue("Service count at %d waiting for %d", len(services), instances)
   289  		}
   290  		return poll.Success()
   291  	}
   292  }
   293  
   294  func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll.Result {
   295  	return func(log poll.LogT) poll.Result {
   296  		netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{
   297  			Verbose: true,
   298  			Scope:   "swarm",
   299  		})
   300  		if err != nil {
   301  			return poll.Error(err)
   302  		}
   303  		np := len(netInfo.Peers)
   304  		nc := len(netInfo.Containers)
   305  		if np == 0 || nc == 0 {
   306  			return poll.Continue("ingress not ready: %d peers and %d containers", nc, np)
   307  		}
   308  		_, ok := netInfo.Containers["ingress-sbox"]
   309  		if !ok {
   310  			return poll.Continue("ingress not ready: does not contain the ingress-sbox")
   311  		}
   312  		return poll.Success()
   313  	}
   314  }
   315  
   316  func noServices(ctx context.Context, client client.ServiceAPIClient) func(log poll.LogT) poll.Result {
   317  	return func(log poll.LogT) poll.Result {
   318  		services, err := client.ServiceList(ctx, types.ServiceListOptions{})
   319  		switch {
   320  		case err != nil:
   321  			return poll.Error(err)
   322  		case len(services) == 0:
   323  			return poll.Success()
   324  		default:
   325  			return poll.Continue("waiting for all services to be removed: service count at %d", len(services))
   326  		}
   327  	}
   328  }
   329  
   330  func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
   331  	skip.If(t, testEnv.OSType == "windows")
   332  	defer setupTest(t)()
   333  	var ops = []func(*daemon.Daemon){}
   334  	ipAddr := []string{"20.20.0.0/16"}
   335  	ops = append(ops, daemon.WithSwarmDefaultAddrPool(ipAddr))
   336  	ops = append(ops, daemon.WithSwarmDefaultAddrPoolSubnetSize(24))
   337  	d := swarm.NewSwarm(t, testEnv, ops...)
   338  
   339  	cli := d.NewClientT(t)
   340  	defer cli.Close()
   341  
   342  	// Create a overlay network
   343  	name := "saanvisthira" + t.Name()
   344  	network.CreateNoError(t, context.Background(), cli, name,
   345  		network.WithDriver("overlay"))
   346  
   347  	var instances uint64 = 1
   348  	serviceName := "TestService" + t.Name()
   349  	serviceID := swarm.CreateService(t, d,
   350  		swarm.ServiceWithReplicas(instances),
   351  		swarm.ServiceWithName(serviceName),
   352  		swarm.ServiceWithNetwork(name),
   353  	)
   354  
   355  	poll.WaitOn(t, serviceRunningCount(cli, serviceID, instances), swarm.ServicePoll)
   356  
   357  	_, _, err := cli.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
   358  	assert.NilError(t, err)
   359  
   360  	out, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   361  	assert.NilError(t, err)
   362  	t.Logf("%s: NetworkInspect: %+v", t.Name(), out)
   363  	assert.Assert(t, len(out.IPAM.Config) > 0)
   364  	assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.0.0/24")
   365  
   366  	err = cli.ServiceRemove(context.Background(), serviceID)
   367  	assert.NilError(t, err)
   368  	d.SwarmLeave(t, true)
   369  	d.Stop(t)
   370  
   371  	// Clean up , set it back to original one to make sure other tests don't fail
   372  	ipAddr = []string{"10.0.0.0/8"}
   373  	ops = append(ops, daemon.WithSwarmDefaultAddrPool(ipAddr))
   374  	ops = append(ops, daemon.WithSwarmDefaultAddrPoolSubnetSize(24))
   375  	d = swarm.NewSwarm(t, testEnv, ops...)
   376  	d.SwarmLeave(t, true)
   377  	defer d.Stop(t)
   378  }