github.com/afbjorklund/moby@v20.10.5+incompatible/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/testutil/daemon" 15 "gotest.tools/v3/assert" 16 "gotest.tools/v3/icmd" 17 "gotest.tools/v3/poll" 18 "gotest.tools/v3/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 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 33 d := daemon.New(t) 34 defer d.Stop(t) 35 d.Start(t) 36 37 c := d.NewClientT(t) 38 defer c.Close() 39 40 // Verify bridge network's subnet 41 out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{}) 42 assert.NilError(t, err) 43 subnet := out.IPAM.Config[0].Subnet 44 45 d.Restart(t, 46 "--live-restore=true", 47 "--default-address-pool", "base=175.30.0.0/16,size=16", 48 "--default-address-pool", "base=175.33.0.0/16,size=24", 49 ) 50 51 out1, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{}) 52 assert.NilError(t, err) 53 // Make sure docker0 doesn't get override with new IP in live restore case 54 assert.Equal(t, out1.IPAM.Config[0].Subnet, subnet) 55 } 56 57 func TestDaemonDefaultNetworkPools(t *testing.T) { 58 skip.If(t, testEnv.OSType == "windows") 59 // Remove docker0 bridge and the start daemon defining the predefined address pools 60 skip.If(t, testEnv.IsRemoteDaemon) 61 skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature") 62 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 63 defaultNetworkBridge := "docker0" 64 delInterface(t, defaultNetworkBridge) 65 d := daemon.New(t) 66 defer d.Stop(t) 67 d.Start(t, 68 "--default-address-pool", "base=175.30.0.0/16,size=16", 69 "--default-address-pool", "base=175.33.0.0/16,size=24", 70 ) 71 72 c := d.NewClientT(t) 73 defer c.Close() 74 75 // Verify bridge network's subnet 76 out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{}) 77 assert.NilError(t, err) 78 assert.Equal(t, out.IPAM.Config[0].Subnet, "175.30.0.0/16") 79 80 // Create a bridge network and verify its subnet is the second default pool 81 name := "elango" + t.Name() 82 network.CreateNoError(context.Background(), t, c, name, 83 network.WithDriver("bridge"), 84 ) 85 out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 86 assert.NilError(t, err) 87 assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.0.0/24") 88 89 // Create a bridge network and verify its subnet is the third default pool 90 name = "saanvi" + t.Name() 91 network.CreateNoError(context.Background(), t, c, name, 92 network.WithDriver("bridge"), 93 ) 94 out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 95 assert.NilError(t, err) 96 assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.1.0/24") 97 delInterface(t, defaultNetworkBridge) 98 99 } 100 101 func TestDaemonRestartWithExistingNetwork(t *testing.T) { 102 skip.If(t, testEnv.OSType == "windows") 103 skip.If(t, testEnv.IsRemoteDaemon) 104 skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature") 105 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 106 defaultNetworkBridge := "docker0" 107 d := daemon.New(t) 108 d.Start(t) 109 defer d.Stop(t) 110 c := d.NewClientT(t) 111 defer c.Close() 112 113 // Create a bridge network 114 name := "elango" + t.Name() 115 network.CreateNoError(context.Background(), t, c, name, 116 network.WithDriver("bridge"), 117 ) 118 119 // Verify bridge network's subnet 120 out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 121 assert.NilError(t, err) 122 networkip := out.IPAM.Config[0].Subnet 123 124 // Restart daemon with default address pool option 125 d.Restart(t, 126 "--default-address-pool", "base=175.30.0.0/16,size=16", 127 "--default-address-pool", "base=175.33.0.0/16,size=24") 128 129 out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 130 assert.NilError(t, err) 131 assert.Equal(t, out1.IPAM.Config[0].Subnet, networkip) 132 delInterface(t, defaultNetworkBridge) 133 } 134 135 func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) { 136 skip.If(t, testEnv.OSType == "windows") 137 skip.If(t, testEnv.IsRemoteDaemon) 138 skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature") 139 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 140 defaultNetworkBridge := "docker0" 141 d := daemon.New(t) 142 d.Start(t) 143 defer d.Stop(t) 144 c := d.NewClientT(t) 145 defer c.Close() 146 147 // Create a bridge network 148 name := "elango" + t.Name() 149 network.CreateNoError(context.Background(), t, c, name, 150 network.WithDriver("bridge"), 151 ) 152 153 // Verify bridge network's subnet 154 out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 155 assert.NilError(t, err) 156 networkip := out.IPAM.Config[0].Subnet 157 158 // Create a bridge network 159 name = "sthira" + t.Name() 160 network.CreateNoError(context.Background(), t, c, name, 161 network.WithDriver("bridge"), 162 ) 163 out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 164 assert.NilError(t, err) 165 networkip2 := out.IPAM.Config[0].Subnet 166 167 // Restart daemon with default address pool option 168 d.Restart(t, 169 "--default-address-pool", "base=175.18.0.0/16,size=16", 170 "--default-address-pool", "base=175.19.0.0/16,size=24", 171 ) 172 173 // Create a bridge network 174 name = "saanvi" + t.Name() 175 network.CreateNoError(context.Background(), t, c, name, 176 network.WithDriver("bridge"), 177 ) 178 out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{}) 179 assert.NilError(t, err) 180 181 assert.Check(t, out1.IPAM.Config[0].Subnet != networkip) 182 assert.Check(t, out1.IPAM.Config[0].Subnet != networkip2) 183 delInterface(t, defaultNetworkBridge) 184 } 185 186 func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) { 187 skip.If(t, testEnv.OSType == "windows") 188 skip.If(t, testEnv.IsRemoteDaemon) 189 skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature") 190 skip.If(t, testEnv.IsRootless, "rootless mode has different view of network") 191 defaultNetworkBridge := "docker0" 192 d := daemon.New(t) 193 defer d.Stop(t) 194 d.Start(t, 195 "--bip=172.60.0.1/16", 196 "--default-address-pool", "base=175.30.0.0/16,size=16", 197 "--default-address-pool", "base=175.33.0.0/16,size=24", 198 ) 199 200 c := d.NewClientT(t) 201 defer c.Close() 202 203 // Verify bridge network's subnet 204 out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{}) 205 assert.NilError(t, err) 206 // Make sure BIP IP doesn't get override with new default address pool . 207 assert.Equal(t, out.IPAM.Config[0].Subnet, "172.60.0.0/16") 208 delInterface(t, defaultNetworkBridge) 209 } 210 211 func TestServiceWithPredefinedNetwork(t *testing.T) { 212 skip.If(t, testEnv.OSType == "windows") 213 skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode") 214 defer setupTest(t)() 215 d := swarm.NewSwarm(t, testEnv) 216 defer d.Stop(t) 217 c := d.NewClientT(t) 218 defer c.Close() 219 220 hostName := "host" 221 var instances uint64 = 1 222 serviceName := "TestService" + t.Name() 223 224 serviceID := swarm.CreateService(t, d, 225 swarm.ServiceWithReplicas(instances), 226 swarm.ServiceWithName(serviceName), 227 swarm.ServiceWithNetwork(hostName), 228 ) 229 230 poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll) 231 232 _, _, err := c.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) 233 assert.NilError(t, err) 234 235 err = c.ServiceRemove(context.Background(), serviceID) 236 assert.NilError(t, err) 237 } 238 239 const ingressNet = "ingress" 240 241 func TestServiceRemoveKeepsIngressNetwork(t *testing.T) { 242 t.Skip("FLAKY_TEST") 243 skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode") 244 245 skip.If(t, testEnv.OSType == "windows") 246 defer setupTest(t)() 247 d := swarm.NewSwarm(t, testEnv) 248 defer d.Stop(t) 249 c := d.NewClientT(t) 250 defer c.Close() 251 252 poll.WaitOn(t, swarmIngressReady(c), swarm.NetworkPoll) 253 254 var instances uint64 = 1 255 256 serviceID := swarm.CreateService(t, d, 257 swarm.ServiceWithReplicas(instances), 258 swarm.ServiceWithName(t.Name()+"-service"), 259 swarm.ServiceWithEndpoint(&swarmtypes.EndpointSpec{ 260 Ports: []swarmtypes.PortConfig{ 261 { 262 Protocol: swarmtypes.PortConfigProtocolTCP, 263 TargetPort: 80, 264 PublishMode: swarmtypes.PortConfigPublishModeIngress, 265 }, 266 }, 267 }), 268 ) 269 270 poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll) 271 272 ctx := context.Background() 273 _, _, err := c.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) 274 assert.NilError(t, err) 275 276 err = c.ServiceRemove(ctx, serviceID) 277 assert.NilError(t, err) 278 279 poll.WaitOn(t, noServices(ctx, c), swarm.ServicePoll) 280 poll.WaitOn(t, swarm.NoTasks(ctx, c), swarm.ServicePoll) 281 282 // Ensure that "ingress" is not removed or corrupted 283 time.Sleep(10 * time.Second) 284 netInfo, err := c.NetworkInspect(ctx, ingressNet, types.NetworkInspectOptions{ 285 Verbose: true, 286 Scope: "swarm", 287 }) 288 assert.NilError(t, err, "Ingress network was removed after removing service!") 289 assert.Assert(t, len(netInfo.Containers) != 0, "No load balancing endpoints in ingress network") 290 assert.Assert(t, len(netInfo.Peers) != 0, "No peers (including self) in ingress network") 291 _, ok := netInfo.Containers["ingress-sbox"] 292 assert.Assert(t, ok, "ingress-sbox not present in ingress network") 293 } 294 295 func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll.Result { 296 return func(log poll.LogT) poll.Result { 297 netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{ 298 Verbose: true, 299 Scope: "swarm", 300 }) 301 if err != nil { 302 return poll.Error(err) 303 } 304 np := len(netInfo.Peers) 305 nc := len(netInfo.Containers) 306 if np == 0 || nc == 0 { 307 return poll.Continue("ingress not ready: %d peers and %d containers", nc, np) 308 } 309 _, ok := netInfo.Containers["ingress-sbox"] 310 if !ok { 311 return poll.Continue("ingress not ready: does not contain the ingress-sbox") 312 } 313 return poll.Success() 314 } 315 } 316 317 func noServices(ctx context.Context, client client.ServiceAPIClient) func(log poll.LogT) poll.Result { 318 return func(log poll.LogT) poll.Result { 319 services, err := client.ServiceList(ctx, types.ServiceListOptions{}) 320 switch { 321 case err != nil: 322 return poll.Error(err) 323 case len(services) == 0: 324 return poll.Success() 325 default: 326 return poll.Continue("waiting for all services to be removed: service count at %d", len(services)) 327 } 328 } 329 } 330 331 func TestServiceWithDataPathPortInit(t *testing.T) { 332 skip.If(t, testEnv.OSType == "windows") 333 skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "DataPathPort was added in API v1.40") 334 skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode") 335 defer setupTest(t)() 336 var datapathPort uint32 = 7777 337 d := swarm.NewSwarm(t, testEnv, daemon.WithSwarmDataPathPort(datapathPort)) 338 c := d.NewClientT(t) 339 ctx := context.Background() 340 // Create a overlay network 341 name := "saanvisthira" + t.Name() 342 overlayID := network.CreateNoError(context.Background(), t, c, name, 343 network.WithDriver("overlay")) 344 345 var instances uint64 = 1 346 serviceID := swarm.CreateService(t, d, 347 swarm.ServiceWithReplicas(instances), 348 swarm.ServiceWithName(name), 349 swarm.ServiceWithNetwork(name), 350 ) 351 352 poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll) 353 354 info := d.Info(t) 355 assert.Equal(t, info.Swarm.Cluster.DataPathPort, datapathPort) 356 err := c.ServiceRemove(ctx, serviceID) 357 assert.NilError(t, err) 358 poll.WaitOn(t, noServices(ctx, c), swarm.ServicePoll) 359 poll.WaitOn(t, swarm.NoTasks(ctx, c), swarm.ServicePoll) 360 err = c.NetworkRemove(ctx, overlayID) 361 assert.NilError(t, err) 362 c.Close() 363 err = d.SwarmLeave(t, true) 364 assert.NilError(t, err) 365 d.Stop(t) 366 367 // Clean up , set it back to original one to make sure other tests don't fail 368 // call without datapath port option. 369 d = swarm.NewSwarm(t, testEnv) 370 defer d.Stop(t) 371 nc := d.NewClientT(t) 372 defer nc.Close() 373 // Create a overlay network 374 name = "not-saanvisthira" + t.Name() 375 overlayID = network.CreateNoError(ctx, t, nc, name, 376 network.WithDriver("overlay")) 377 378 serviceID = swarm.CreateService(t, d, 379 swarm.ServiceWithReplicas(instances), 380 swarm.ServiceWithName(name), 381 swarm.ServiceWithNetwork(name), 382 ) 383 384 poll.WaitOn(t, swarm.RunningTasksCount(nc, serviceID, instances), swarm.ServicePoll) 385 386 info = d.Info(t) 387 var defaultDataPathPort uint32 = 4789 388 assert.Equal(t, info.Swarm.Cluster.DataPathPort, defaultDataPathPort) 389 err = nc.ServiceRemove(ctx, serviceID) 390 assert.NilError(t, err) 391 poll.WaitOn(t, noServices(ctx, nc), swarm.ServicePoll) 392 poll.WaitOn(t, swarm.NoTasks(ctx, nc), swarm.ServicePoll) 393 err = nc.NetworkRemove(ctx, overlayID) 394 assert.NilError(t, err) 395 err = d.SwarmLeave(t, true) 396 assert.NilError(t, err) 397 } 398 399 func TestServiceWithDefaultAddressPoolInit(t *testing.T) { 400 skip.If(t, testEnv.OSType == "windows") 401 skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode") 402 defer setupTest(t)() 403 d := swarm.NewSwarm(t, testEnv, 404 daemon.WithSwarmDefaultAddrPool([]string{"20.20.0.0/16"}), 405 daemon.WithSwarmDefaultAddrPoolSubnetSize(24)) 406 defer d.Stop(t) 407 cli := d.NewClientT(t) 408 defer cli.Close() 409 ctx := context.Background() 410 411 // Create a overlay network 412 name := "sthira" + t.Name() 413 overlayID := network.CreateNoError(ctx, t, cli, name, 414 network.WithDriver("overlay"), 415 network.WithCheckDuplicate(), 416 ) 417 418 var instances uint64 = 1 419 serviceName := "TestService" + t.Name() 420 serviceID := swarm.CreateService(t, d, 421 swarm.ServiceWithReplicas(instances), 422 swarm.ServiceWithName(serviceName), 423 swarm.ServiceWithNetwork(name), 424 ) 425 426 poll.WaitOn(t, swarm.RunningTasksCount(cli, serviceID, instances), swarm.ServicePoll) 427 428 _, _, err := cli.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) 429 assert.NilError(t, err) 430 431 out, err := cli.NetworkInspect(ctx, overlayID, types.NetworkInspectOptions{Verbose: true}) 432 assert.NilError(t, err) 433 t.Logf("%s: NetworkInspect: %+v", t.Name(), out) 434 assert.Assert(t, len(out.IPAM.Config) > 0) 435 // As of docker/swarmkit#2890, the ingress network uses the default address 436 // pool (whereas before, the subnet for the ingress network was hard-coded. 437 // This means that the ingress network gets the subnet 20.20.0.0/24, and 438 // the network we just created gets subnet 20.20.1.0/24. 439 assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.1.0/24") 440 441 // Also inspect ingress network and make sure its in the same subnet 442 out, err = cli.NetworkInspect(ctx, "ingress", types.NetworkInspectOptions{Verbose: true}) 443 assert.NilError(t, err) 444 assert.Assert(t, len(out.IPAM.Config) > 0) 445 assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.0.0/24") 446 447 err = cli.ServiceRemove(ctx, serviceID) 448 poll.WaitOn(t, noServices(ctx, cli), swarm.ServicePoll) 449 poll.WaitOn(t, swarm.NoTasks(ctx, cli), swarm.ServicePoll) 450 assert.NilError(t, err) 451 err = cli.NetworkRemove(ctx, overlayID) 452 assert.NilError(t, err) 453 err = d.SwarmLeave(t, true) 454 assert.NilError(t, err) 455 456 }