service_common.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // +build linux windows
  2. package libnetwork
  3. import (
  4. "net"
  5. "github.com/Sirupsen/logrus"
  6. )
  7. func newService(name string, id string, ingressPorts []*PortConfig, aliases []string) *service {
  8. return &service{
  9. name: name,
  10. id: id,
  11. ingressPorts: ingressPorts,
  12. loadBalancers: make(map[string]*loadBalancer),
  13. aliases: aliases,
  14. }
  15. }
  16. func (c *controller) cleanupServiceBindings(cleanupNID string) {
  17. var cleanupFuncs []func()
  18. c.Lock()
  19. services := make([]*service, 0, len(c.serviceBindings))
  20. for _, s := range c.serviceBindings {
  21. services = append(services, s)
  22. }
  23. c.Unlock()
  24. for _, s := range services {
  25. s.Lock()
  26. for nid, lb := range s.loadBalancers {
  27. if cleanupNID != "" && nid != cleanupNID {
  28. continue
  29. }
  30. for eid, ip := range lb.backEnds {
  31. service := s
  32. loadBalancer := lb
  33. networkID := nid
  34. epID := eid
  35. epIP := ip
  36. cleanupFuncs = append(cleanupFuncs, func() {
  37. if err := c.rmServiceBinding(service.name, service.id, networkID, epID, loadBalancer.vip,
  38. service.ingressPorts, service.aliases, epIP); err != nil {
  39. logrus.Errorf("Failed to remove service bindings for service %s network %s endpoint %s while cleanup: %v",
  40. service.id, networkID, epID, err)
  41. }
  42. })
  43. }
  44. }
  45. s.Unlock()
  46. }
  47. for _, f := range cleanupFuncs {
  48. f()
  49. }
  50. }
  51. func (c *controller) addServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
  52. n, err := c.NetworkByID(nid)
  53. if err != nil {
  54. return err
  55. }
  56. skey := serviceKey{
  57. id: sid,
  58. ports: portConfigs(ingressPorts).String(),
  59. }
  60. c.Lock()
  61. s, ok := c.serviceBindings[skey]
  62. if !ok {
  63. // Create a new service if we are seeing this service
  64. // for the first time.
  65. s = newService(name, sid, ingressPorts, aliases)
  66. c.serviceBindings[skey] = s
  67. }
  68. c.Unlock()
  69. // Add endpoint IP to special "tasks.svc_name" so that the
  70. // applications have access to DNS RR.
  71. n.(*network).addSvcRecords("tasks."+name, ip, nil, false)
  72. for _, alias := range aliases {
  73. n.(*network).addSvcRecords("tasks."+alias, ip, nil, false)
  74. }
  75. // Add service name to vip in DNS, if vip is valid. Otherwise resort to DNS RR
  76. svcIP := vip
  77. if len(svcIP) == 0 {
  78. svcIP = ip
  79. }
  80. n.(*network).addSvcRecords(name, svcIP, nil, false)
  81. for _, alias := range aliases {
  82. n.(*network).addSvcRecords(alias, svcIP, nil, false)
  83. }
  84. s.Lock()
  85. defer s.Unlock()
  86. lb, ok := s.loadBalancers[nid]
  87. if !ok {
  88. // Create a new load balancer if we are seeing this
  89. // network attachment on the service for the first
  90. // time.
  91. lb = &loadBalancer{
  92. vip: vip,
  93. fwMark: fwMarkCtr,
  94. backEnds: make(map[string]net.IP),
  95. service: s,
  96. }
  97. fwMarkCtrMu.Lock()
  98. fwMarkCtr++
  99. fwMarkCtrMu.Unlock()
  100. s.loadBalancers[nid] = lb
  101. }
  102. lb.backEnds[eid] = ip
  103. // Add loadbalancer service and backend in all sandboxes in
  104. // the network only if vip is valid.
  105. if len(vip) != 0 {
  106. n.(*network).addLBBackend(ip, vip, lb.fwMark, ingressPorts)
  107. }
  108. return nil
  109. }
  110. func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, ingressPorts []*PortConfig, aliases []string, ip net.IP) error {
  111. var rmService bool
  112. n, err := c.NetworkByID(nid)
  113. if err != nil {
  114. return err
  115. }
  116. skey := serviceKey{
  117. id: sid,
  118. ports: portConfigs(ingressPorts).String(),
  119. }
  120. c.Lock()
  121. s, ok := c.serviceBindings[skey]
  122. c.Unlock()
  123. if !ok {
  124. return nil
  125. }
  126. s.Lock()
  127. lb, ok := s.loadBalancers[nid]
  128. if !ok {
  129. s.Unlock()
  130. return nil
  131. }
  132. _, ok = lb.backEnds[eid]
  133. if !ok {
  134. s.Unlock()
  135. return nil
  136. }
  137. delete(lb.backEnds, eid)
  138. if len(lb.backEnds) == 0 {
  139. // All the backends for this service have been
  140. // removed. Time to remove the load balancer and also
  141. // remove the service entry in IPVS.
  142. rmService = true
  143. delete(s.loadBalancers, nid)
  144. }
  145. if len(s.loadBalancers) == 0 {
  146. // All loadbalancers for the service removed. Time to
  147. // remove the service itself.
  148. c.Lock()
  149. delete(c.serviceBindings, skey)
  150. c.Unlock()
  151. }
  152. // Remove loadbalancer service(if needed) and backend in all
  153. // sandboxes in the network only if the vip is valid.
  154. if len(vip) != 0 {
  155. n.(*network).rmLBBackend(ip, vip, lb.fwMark, ingressPorts, rmService)
  156. }
  157. s.Unlock()
  158. // Delete the special "tasks.svc_name" backend record.
  159. n.(*network).deleteSvcRecords("tasks."+name, ip, nil, false)
  160. for _, alias := range aliases {
  161. n.(*network).deleteSvcRecords("tasks."+alias, ip, nil, false)
  162. }
  163. // If we are doing DNS RR add the endpoint IP to DNS record
  164. // right away.
  165. if len(vip) == 0 {
  166. n.(*network).deleteSvcRecords(name, ip, nil, false)
  167. for _, alias := range aliases {
  168. n.(*network).deleteSvcRecords(alias, ip, nil, false)
  169. }
  170. }
  171. // Remove the DNS record for VIP only if we are removing the service
  172. if rmService && len(vip) != 0 {
  173. n.(*network).deleteSvcRecords(name, vip, nil, false)
  174. for _, alias := range aliases {
  175. n.(*network).deleteSvcRecords(alias, vip, nil, false)
  176. }
  177. }
  178. return nil
  179. }