service_test.go 14 KB

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