service_windows.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package libnetwork
  2. import (
  3. "context"
  4. "net"
  5. "github.com/Microsoft/hcsshim"
  6. "github.com/containerd/log"
  7. )
  8. type policyLists struct {
  9. ilb *hcsshim.PolicyList
  10. elb *hcsshim.PolicyList
  11. }
  12. var lbPolicylistMap = make(map[*loadBalancer]*policyLists)
  13. func (n *Network) addLBBackend(ip net.IP, lb *loadBalancer) {
  14. if len(lb.vip) == 0 {
  15. return
  16. }
  17. vip := lb.vip
  18. ingressPorts := lb.service.ingressPorts
  19. lb.Lock()
  20. defer lb.Unlock()
  21. // find the load balancer IP for the network.
  22. var sourceVIP string
  23. for _, e := range n.Endpoints() {
  24. epInfo := e.Info()
  25. if epInfo == nil {
  26. continue
  27. }
  28. if epInfo.LoadBalancer() {
  29. sourceVIP = epInfo.Iface().Address().IP.String()
  30. break
  31. }
  32. }
  33. if sourceVIP == "" {
  34. log.G(context.TODO()).Errorf("Failed to find load balancer IP for network %s", n.Name())
  35. return
  36. }
  37. var endpoints []hcsshim.HNSEndpoint
  38. for eid, be := range lb.backEnds {
  39. if be.disabled {
  40. continue
  41. }
  42. // Call HNS to get back ID (GUID) corresponding to the endpoint.
  43. hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid)
  44. if err != nil {
  45. log.G(context.TODO()).Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err)
  46. return
  47. }
  48. endpoints = append(endpoints, *hnsEndpoint)
  49. }
  50. if policies, ok := lbPolicylistMap[lb]; ok {
  51. if policies.ilb != nil {
  52. policies.ilb.Delete()
  53. policies.ilb = nil
  54. }
  55. if policies.elb != nil {
  56. policies.elb.Delete()
  57. policies.elb = nil
  58. }
  59. delete(lbPolicylistMap, lb)
  60. }
  61. ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0)
  62. if err != nil {
  63. log.G(context.TODO()).Errorf("Failed to add ILB policy for service %s (%s) with endpoints %v using load balancer IP %s on network %s: %v",
  64. lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err)
  65. return
  66. }
  67. lbPolicylistMap[lb] = &policyLists{
  68. ilb: ilbPolicy,
  69. }
  70. publishedPorts := make(map[uint32]uint32)
  71. for i, port := range ingressPorts {
  72. protocol := uint16(6)
  73. // Skip already published port
  74. if publishedPorts[port.PublishedPort] == port.TargetPort {
  75. continue
  76. }
  77. if port.Protocol == ProtocolUDP {
  78. protocol = 17
  79. }
  80. // check if already has udp matching to add wild card publishing
  81. for j := i + 1; j < len(ingressPorts); j++ {
  82. if ingressPorts[j].TargetPort == port.TargetPort &&
  83. ingressPorts[j].PublishedPort == port.PublishedPort {
  84. protocol = 0
  85. }
  86. }
  87. publishedPorts[port.PublishedPort] = port.TargetPort
  88. lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort))
  89. if err != nil {
  90. log.G(context.TODO()).Errorf("Failed to add ELB policy for service %s (ip:%s target port:%v published port:%v) with endpoints %v using load balancer IP %s on network %s: %v",
  91. lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err)
  92. return
  93. }
  94. }
  95. }
  96. func (n *Network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullRemove bool) {
  97. if len(lb.vip) == 0 {
  98. return
  99. }
  100. if numEnabledBackends(lb) > 0 {
  101. // Reprogram HNS (actually VFP) with the existing backends.
  102. n.addLBBackend(ip, lb)
  103. } else {
  104. lb.Lock()
  105. defer lb.Unlock()
  106. log.G(context.TODO()).Debugf("No more backends for service %s (ip:%s). Removing all policies", lb.service.name, lb.vip.String())
  107. if policyLists, ok := lbPolicylistMap[lb]; ok {
  108. if policyLists.ilb != nil {
  109. if _, err := policyLists.ilb.Delete(); err != nil {
  110. log.G(context.TODO()).Errorf("Failed to remove HNS ILB policylist %s: %s", policyLists.ilb.ID, err)
  111. }
  112. policyLists.ilb = nil
  113. }
  114. if policyLists.elb != nil {
  115. if _, err := policyLists.elb.Delete(); err != nil {
  116. log.G(context.TODO()).Errorf("Failed to remove HNS ELB policylist %s: %s", policyLists.elb.ID, err)
  117. }
  118. policyLists.elb = nil
  119. }
  120. delete(lbPolicylistMap, lb)
  121. } else {
  122. log.G(context.TODO()).Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String())
  123. }
  124. }
  125. }
  126. func numEnabledBackends(lb *loadBalancer) int {
  127. nEnabled := 0
  128. for _, be := range lb.backEnds {
  129. if !be.disabled {
  130. nEnabled++
  131. }
  132. }
  133. return nEnabled
  134. }
  135. func (sb *Sandbox) populateLoadBalancers(ep *Endpoint) {
  136. }
  137. func arrangeIngressFilterRule() {
  138. }