mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-24 11:29:09 +00:00
Kube-proxy: perf-enhancement: Reduce NAT table KUBE-SERVICES/NODEPORTS chain rules
The nat KUBE-SERVICES chain is called from OUTPUT and PREROUTING stages. In clusters with large number of services, the nat-KUBE-SERVICES chain is the largest chain with for eg: 33k rules. This patch aims to move the KubeMarkMasq rules from the kubeServicesChain into the respective KUBE-SVC-* chains. This way during each packet-rule matching we won't have to traverse the MASQ rules of all services which get accumulated in the KUBE-SERVICES and/or KUBE-NODEPORTS chains. Since the jump to KUBE-MARK-MASQ ultimately sets the 0x400 mark for nodeIP SNAT, it should not matter whether the jump is made from KUBE-SERVICES or KUBE-SVC-* chains. Specifically we change: 1) For ClusterIP svc, we move the KUBE-MARK-MASQ jump rule from KUBE-SERVICES chain into KUBE-SVC-* chain. 2) For ExternalIP svc, we move the KUBE-MARK-MASQ jump rule in the case of non-ServiceExternalTrafficPolicyTypeLocal from KUBE-SERVICES chain into KUBE-SVC-* chain. 3) For NodePorts svc, we move the KUBE-MARK-MASQ jump rule in case of non-ServiceExternalTrafficPolicyTypeLocal from KUBE-NODEPORTS chain to KUBE-SVC-* chain. 4) For load-balancer svc, we don't change anything since it is already svc specific due to creation of KUBE-FW-* chains per svc. This would cut the rules per svc in KUBE-SERVICES and KUBE-NODEPORTS in half.
This commit is contained in:
@@ -477,6 +477,18 @@ func WriteLine(buf *bytes.Buffer, words ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
// WriteRuleLine prepends the strings "-A" and chainName to the buffer and calls
|
||||
// WriteLine to join all the words into the buffer and terminate with newline.
|
||||
func WriteRuleLine(buf *bytes.Buffer, chainName string, words ...string) {
|
||||
if len(words) == 0 {
|
||||
return
|
||||
}
|
||||
buf.WriteString("-A ")
|
||||
buf.WriteString(chainName)
|
||||
buf.WriteByte(' ')
|
||||
WriteLine(buf, words...)
|
||||
}
|
||||
|
||||
// WriteBytesLine write bytes to buffer, terminate with newline
|
||||
func WriteBytesLine(buf *bytes.Buffer, bytes []byte) {
|
||||
buf.Write(bytes)
|
||||
|
@@ -1183,6 +1183,44 @@ func TestWriteLine(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteRuleLine(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
chainName string
|
||||
words []string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "write no line due to no words",
|
||||
chainName: "KUBE-SVC-FOO",
|
||||
words: []string{},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "write one line",
|
||||
chainName: "KUBE-XLB-FOO",
|
||||
words: []string{"test1"},
|
||||
expected: "-A KUBE-XLB-FOO test1\n",
|
||||
},
|
||||
{
|
||||
name: "write multi word line",
|
||||
chainName: "lolChain",
|
||||
words: []string{"test1", "test2", "test3"},
|
||||
expected: "-A lolChain test1 test2 test3\n",
|
||||
},
|
||||
}
|
||||
testBuffer := bytes.NewBuffer(nil)
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
testBuffer.Reset()
|
||||
WriteRuleLine(testBuffer, testCase.chainName, testCase.words...)
|
||||
if !strings.EqualFold(testBuffer.String(), testCase.expected) {
|
||||
t.Fatalf("write word is %v\n expected: %s, got: %s", testCase.words, testCase.expected, testBuffer.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteBytesLine(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
Reference in New Issue
Block a user