service_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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/swarm"
  11. "github.com/docker/docker/internal/test/daemon"
  12. "github.com/gotestyourself/gotestyourself/assert"
  13. "github.com/gotestyourself/gotestyourself/icmd"
  14. "github.com/gotestyourself/gotestyourself/poll"
  15. "github.com/gotestyourself/gotestyourself/skip"
  16. )
  17. // delInterface removes given network interface
  18. func delInterface(t *testing.T, ifName string) {
  19. icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success)
  20. icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success)
  21. icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success)
  22. }
  23. func TestDaemonRestartWithLiveRestore(t *testing.T) {
  24. skip.If(t, testEnv.IsRemoteDaemon())
  25. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
  26. d := daemon.New(t)
  27. defer d.Stop(t)
  28. d.Start(t)
  29. d.Restart(t, "--live-restore=true",
  30. "--default-address-pool", "base=175.30.0.0/16,size=16",
  31. "--default-address-pool", "base=175.33.0.0/16,size=24")
  32. // Verify bridge network's subnet
  33. cli, err := d.NewClient()
  34. assert.Assert(t, err)
  35. defer cli.Close()
  36. out, err := cli.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
  37. assert.NilError(t, err)
  38. // Make sure docker0 doesn't get override with new IP in live restore case
  39. assert.Equal(t, out.IPAM.Config[0].Subnet, "172.18.0.0/16")
  40. }
  41. func TestDaemonDefaultNetworkPools(t *testing.T) {
  42. // Remove docker0 bridge and the start daemon defining the predefined address pools
  43. skip.If(t, testEnv.IsRemoteDaemon())
  44. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
  45. defaultNetworkBridge := "docker0"
  46. delInterface(t, defaultNetworkBridge)
  47. d := daemon.New(t)
  48. defer d.Stop(t)
  49. d.Start(t,
  50. "--default-address-pool", "base=175.30.0.0/16,size=16",
  51. "--default-address-pool", "base=175.33.0.0/16,size=24")
  52. // Verify bridge network's subnet
  53. cli, err := d.NewClient()
  54. assert.Assert(t, err)
  55. defer cli.Close()
  56. out, err := cli.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
  57. assert.NilError(t, err)
  58. assert.Equal(t, out.IPAM.Config[0].Subnet, "175.30.0.0/16")
  59. // Create a bridge network and verify its subnet is the second default pool
  60. name := "elango"
  61. networkCreate := types.NetworkCreate{
  62. CheckDuplicate: false,
  63. }
  64. networkCreate.Driver = "bridge"
  65. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  66. assert.NilError(t, err)
  67. out, err = cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  68. assert.NilError(t, err)
  69. assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.0.0/24")
  70. // Create a bridge network and verify its subnet is the third default pool
  71. name = "saanvi"
  72. networkCreate = types.NetworkCreate{
  73. CheckDuplicate: false,
  74. }
  75. networkCreate.Driver = "bridge"
  76. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  77. assert.NilError(t, err)
  78. out, err = cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  79. assert.NilError(t, err)
  80. assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.1.0/24")
  81. delInterface(t, defaultNetworkBridge)
  82. }
  83. func TestDaemonRestartWithExistingNetwork(t *testing.T) {
  84. skip.If(t, testEnv.IsRemoteDaemon())
  85. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
  86. defaultNetworkBridge := "docker0"
  87. d := daemon.New(t)
  88. d.Start(t)
  89. defer d.Stop(t)
  90. // Verify bridge network's subnet
  91. cli, err := d.NewClient()
  92. assert.Assert(t, err)
  93. defer cli.Close()
  94. // Create a bridge network
  95. name := "elango"
  96. networkCreate := types.NetworkCreate{
  97. CheckDuplicate: false,
  98. }
  99. networkCreate.Driver = "bridge"
  100. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  101. assert.NilError(t, err)
  102. out, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  103. assert.NilError(t, err)
  104. networkip := out.IPAM.Config[0].Subnet
  105. // Restart daemon with default address pool option
  106. d.Restart(t,
  107. "--default-address-pool", "base=175.30.0.0/16,size=16",
  108. "--default-address-pool", "base=175.33.0.0/16,size=24")
  109. out1, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  110. assert.NilError(t, err)
  111. assert.Equal(t, out1.IPAM.Config[0].Subnet, networkip)
  112. delInterface(t, defaultNetworkBridge)
  113. }
  114. func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
  115. skip.If(t, testEnv.IsRemoteDaemon())
  116. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
  117. defaultNetworkBridge := "docker0"
  118. d := daemon.New(t)
  119. d.Start(t)
  120. defer d.Stop(t)
  121. // Verify bridge network's subnet
  122. cli, err := d.NewClient()
  123. assert.Assert(t, err)
  124. defer cli.Close()
  125. // Create a bridge network
  126. name := "elango"
  127. networkCreate := types.NetworkCreate{
  128. CheckDuplicate: false,
  129. }
  130. networkCreate.Driver = "bridge"
  131. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  132. assert.NilError(t, err)
  133. out, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  134. assert.NilError(t, err)
  135. networkip := out.IPAM.Config[0].Subnet
  136. // Create a bridge network
  137. name = "sthira"
  138. networkCreate = types.NetworkCreate{
  139. CheckDuplicate: false,
  140. }
  141. networkCreate.Driver = "bridge"
  142. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  143. assert.NilError(t, err)
  144. out, err = cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  145. assert.NilError(t, err)
  146. networkip2 := out.IPAM.Config[0].Subnet
  147. // Restart daemon with default address pool option
  148. d.Restart(t,
  149. "--default-address-pool", "base=175.18.0.0/16,size=16",
  150. "--default-address-pool", "base=175.19.0.0/16,size=24")
  151. // Create a bridge network
  152. name = "saanvi"
  153. networkCreate = types.NetworkCreate{
  154. CheckDuplicate: false,
  155. }
  156. networkCreate.Driver = "bridge"
  157. _, err = cli.NetworkCreate(context.Background(), name, networkCreate)
  158. assert.NilError(t, err)
  159. out1, err := cli.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
  160. assert.NilError(t, err)
  161. assert.Check(t, out1.IPAM.Config[0].Subnet != networkip)
  162. assert.Check(t, out1.IPAM.Config[0].Subnet != networkip2)
  163. delInterface(t, defaultNetworkBridge)
  164. }
  165. func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
  166. skip.If(t, testEnv.IsRemoteDaemon())
  167. skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
  168. defaultNetworkBridge := "docker0"
  169. d := daemon.New(t)
  170. defer d.Stop(t)
  171. d.Start(t, "--bip=172.60.0.1/16",
  172. "--default-address-pool", "base=175.30.0.0/16,size=16",
  173. "--default-address-pool", "base=175.33.0.0/16,size=24")
  174. // Verify bridge network's subnet
  175. cli, err := d.NewClient()
  176. assert.Assert(t, err)
  177. defer cli.Close()
  178. out, err := cli.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
  179. assert.NilError(t, err)
  180. // Make sure BIP IP doesn't get override with new default address pool .
  181. assert.Equal(t, out.IPAM.Config[0].Subnet, "172.60.0.1/16")
  182. delInterface(t, defaultNetworkBridge)
  183. }
  184. func TestServiceWithPredefinedNetwork(t *testing.T) {
  185. defer setupTest(t)()
  186. d := swarm.NewSwarm(t, testEnv)
  187. defer d.Stop(t)
  188. client := d.NewClientT(t)
  189. defer client.Close()
  190. hostName := "host"
  191. var instances uint64 = 1
  192. serviceName := "TestService" + t.Name()
  193. serviceID := swarm.CreateService(t, d,
  194. swarm.ServiceWithReplicas(instances),
  195. swarm.ServiceWithName(serviceName),
  196. swarm.ServiceWithNetwork(hostName),
  197. )
  198. poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), swarm.ServicePoll)
  199. _, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
  200. assert.NilError(t, err)
  201. err = client.ServiceRemove(context.Background(), serviceID)
  202. assert.NilError(t, err)
  203. }
  204. const ingressNet = "ingress"
  205. func TestServiceRemoveKeepsIngressNetwork(t *testing.T) {
  206. defer setupTest(t)()
  207. d := swarm.NewSwarm(t, testEnv)
  208. defer d.Stop(t)
  209. client := d.NewClientT(t)
  210. defer client.Close()
  211. poll.WaitOn(t, swarmIngressReady(client), swarm.NetworkPoll)
  212. var instances uint64 = 1
  213. serviceID := swarm.CreateService(t, d,
  214. swarm.ServiceWithReplicas(instances),
  215. swarm.ServiceWithName(t.Name()+"-service"),
  216. swarm.ServiceWithEndpoint(&swarmtypes.EndpointSpec{
  217. Ports: []swarmtypes.PortConfig{
  218. {
  219. Protocol: swarmtypes.PortConfigProtocolTCP,
  220. TargetPort: 80,
  221. PublishMode: swarmtypes.PortConfigPublishModeIngress,
  222. },
  223. },
  224. }),
  225. )
  226. poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), swarm.ServicePoll)
  227. _, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
  228. assert.NilError(t, err)
  229. err = client.ServiceRemove(context.Background(), serviceID)
  230. assert.NilError(t, err)
  231. poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll)
  232. poll.WaitOn(t, noServices(client), swarm.ServicePoll)
  233. // Ensure that "ingress" is not removed or corrupted
  234. time.Sleep(10 * time.Second)
  235. netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{
  236. Verbose: true,
  237. Scope: "swarm",
  238. })
  239. assert.NilError(t, err, "Ingress network was removed after removing service!")
  240. assert.Assert(t, len(netInfo.Containers) != 0, "No load balancing endpoints in ingress network")
  241. assert.Assert(t, len(netInfo.Peers) != 0, "No peers (including self) in ingress network")
  242. _, ok := netInfo.Containers["ingress-sbox"]
  243. assert.Assert(t, ok, "ingress-sbox not present in ingress network")
  244. }
  245. func serviceRunningCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result {
  246. return func(log poll.LogT) poll.Result {
  247. services, err := client.ServiceList(context.Background(), types.ServiceListOptions{})
  248. if err != nil {
  249. return poll.Error(err)
  250. }
  251. if len(services) != int(instances) {
  252. return poll.Continue("Service count at %d waiting for %d", len(services), instances)
  253. }
  254. return poll.Success()
  255. }
  256. }
  257. func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll.Result {
  258. return func(log poll.LogT) poll.Result {
  259. netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{
  260. Verbose: true,
  261. Scope: "swarm",
  262. })
  263. if err != nil {
  264. return poll.Error(err)
  265. }
  266. np := len(netInfo.Peers)
  267. nc := len(netInfo.Containers)
  268. if np == 0 || nc == 0 {
  269. return poll.Continue("ingress not ready: %d peers and %d containers", nc, np)
  270. }
  271. _, ok := netInfo.Containers["ingress-sbox"]
  272. if !ok {
  273. return poll.Continue("ingress not ready: does not contain the ingress-sbox")
  274. }
  275. return poll.Success()
  276. }
  277. }
  278. func noServices(client client.ServiceAPIClient) func(log poll.LogT) poll.Result {
  279. return func(log poll.LogT) poll.Result {
  280. services, err := client.ServiceList(context.Background(), types.ServiceListOptions{})
  281. switch {
  282. case err != nil:
  283. return poll.Error(err)
  284. case len(services) == 0:
  285. return poll.Success()
  286. default:
  287. return poll.Continue("Service count at %d waiting for 0", len(services))
  288. }
  289. }
  290. }