Browse Source

Add a narrower SNAT rule for LB egress

The SNAT rules added for LB egress is broader and breaks load balancing
if the service is connected to multiple networks. Make it conditional
based on the subnet to which the network belongs so that the right SNAT
rule gets matched when egressing the corresponding network.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 9 years ago
parent
commit
6d877647e1
1 changed files with 8 additions and 2 deletions
  1. 8 2
      libnetwork/service_linux.go

+ 8 - 2
libnetwork/service_linux.go

@@ -647,7 +647,7 @@ func invokeFWMarker(path string, vip net.IP, fwMark uint32, ingressPorts []*Port
 
 
 	cmd := &exec.Cmd{
 	cmd := &exec.Cmd{
 		Path:   reexec.Self(),
 		Path:   reexec.Self(),
-		Args:   append([]string{"fwmarker"}, path, vip.String(), fmt.Sprintf("%d", fwMark), addDelOpt, ingressPortsFile, eIP.IP.String()),
+		Args:   append([]string{"fwmarker"}, path, vip.String(), fmt.Sprintf("%d", fwMark), addDelOpt, ingressPortsFile, eIP.String()),
 		Stdout: os.Stdout,
 		Stdout: os.Stdout,
 		Stderr: os.Stderr,
 		Stderr: os.Stderr,
 	}
 	}
@@ -719,7 +719,13 @@ func fwMarker() {
 	}
 	}
 
 
 	if addDelOpt == "-A" {
 	if addDelOpt == "-A" {
-		ruleParams := strings.Fields(fmt.Sprintf("-m ipvs --ipvs -j SNAT --to-source %s", os.Args[6]))
+		eIP, subnet, err := net.ParseCIDR(os.Args[6])
+		if err != nil {
+			logrus.Errorf("Failed to parse endpoint IP %s: %v", os.Args[6], err)
+			os.Exit(9)
+		}
+
+		ruleParams := strings.Fields(fmt.Sprintf("-m ipvs --ipvs -d %s -j SNAT --to-source %s", subnet, eIP))
 		if !iptables.Exists("nat", "POSTROUTING", ruleParams...) {
 		if !iptables.Exists("nat", "POSTROUTING", ruleParams...) {
 			rule := append(strings.Fields("-t nat -A POSTROUTING"), ruleParams...)
 			rule := append(strings.Fields("-t nat -A POSTROUTING"), ruleParams...)
 			rules = append(rules, rule)
 			rules = append(rules, rule)