mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-29 21:29:24 +00:00
Made IPVS and iptables modes of kube-proxy fully randomize masquerading if possible
Work around Linux kernel bug that sometimes causes multiple flows to get mapped to the same IP:PORT and consequently some suffer packet drops. Also made the same update in kubelet. Also added cross-pointers between the two bodies of code, in comments. Some day we should eliminate the duplicate code. But today is not that day.
This commit is contained in:
@@ -1654,12 +1654,20 @@ func (proxier *Proxier) createAndLinkeKubeChain() {
|
||||
// Install the kubernetes-specific postrouting rules. We use a whole chain for
|
||||
// this so that it is easier to flush and change, for example if the mark
|
||||
// value should ever change.
|
||||
writeLine(proxier.natRules, []string{
|
||||
// NB: THIS MUST MATCH the corresponding code in the kubelet
|
||||
masqRule := []string{
|
||||
"-A", string(kubePostroutingChain),
|
||||
"-m", "comment", "--comment", `"kubernetes service traffic requiring SNAT"`,
|
||||
"-m", "mark", "--mark", proxier.masqueradeMark,
|
||||
"-j", "MASQUERADE",
|
||||
}...)
|
||||
}
|
||||
if proxier.iptables.HasRandomFully() {
|
||||
masqRule = append(masqRule, "--random-fully")
|
||||
klog.V(3).Info("Using `--random-fully` in the MASQUERADE rule for iptables")
|
||||
} else {
|
||||
klog.V(2).Info("Not using `--random-fully` in the MASQUERADE rule for iptables because the local version of iptables does not support it")
|
||||
}
|
||||
writeLine(proxier.natRules, masqRule...)
|
||||
|
||||
// Install the kubernetes-specific masquerade mark rule. We use a whole chain for
|
||||
// this so that it is easier to flush and change, for example if the mark
|
||||
|
||||
@@ -1120,6 +1120,27 @@ func TestClusterIP(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMasqueradeRule(t *testing.T) {
|
||||
for _, testcase := range []bool{false, true} {
|
||||
ipt := iptablestest.NewFake().SetHasRandomFully(testcase)
|
||||
ipvs := ipvstest.NewFake()
|
||||
ipset := ipsettest.NewFake(testIPSetVersion)
|
||||
fp := NewFakeProxier(ipt, ipvs, ipset, nil, nil, false)
|
||||
makeServiceMap(fp)
|
||||
makeEndpointsMap(fp)
|
||||
fp.syncProxyRules()
|
||||
|
||||
postRoutingRules := ipt.GetRules(string(kubePostroutingChain))
|
||||
if !hasJump(postRoutingRules, "MASQUERADE", "") {
|
||||
t.Errorf("Failed to find -j MASQUERADE in %s chain", kubePostroutingChain)
|
||||
}
|
||||
if hasMasqRandomFully(postRoutingRules) != testcase {
|
||||
probs := map[bool]string{false: "found", true: "did not find"}
|
||||
t.Errorf("%s --random-fully in -j MASQUERADE rule in %s chain for HasRandomFully()=%v", probs[testcase], kubePostroutingChain, testcase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExternalIPsNoEndpoint(t *testing.T) {
|
||||
ipt := iptablestest.NewFake()
|
||||
ipvs := ipvstest.NewFake()
|
||||
@@ -3112,6 +3133,15 @@ func hasJump(rules []iptablestest.Rule, destChain, ipSet string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func hasMasqRandomFully(rules []iptablestest.Rule) bool {
|
||||
for _, r := range rules {
|
||||
if r[iptablestest.Masquerade] == "--random-fully" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkIptabless to check expected iptables chain and rules
|
||||
func checkIptables(t *testing.T, ipt *iptablestest.FakeIPTables, epIpt netlinktest.ExpectedIptablesChain) {
|
||||
for epChain, epRules := range epIpt {
|
||||
|
||||
Reference in New Issue
Block a user