mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 11:13:48 +00:00
Merge pull request #81477 from paulsubrata55/kube-proxy-sctp-ipset-fix
Fix in kube-proxy for sctp ipset entries
This commit is contained in:
commit
bd8a8db515
@ -1204,42 +1204,57 @@ func (proxier *Proxier) syncProxyRules() {
|
|||||||
// Nodeports need SNAT, unless they're local.
|
// Nodeports need SNAT, unless they're local.
|
||||||
// ipset call
|
// ipset call
|
||||||
|
|
||||||
var nodePortSet *IPSet
|
var (
|
||||||
|
nodePortSet *IPSet
|
||||||
|
entries []*utilipset.Entry
|
||||||
|
)
|
||||||
|
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
nodePortSet = proxier.ipsetList[kubeNodePortSetTCP]
|
nodePortSet = proxier.ipsetList[kubeNodePortSetTCP]
|
||||||
entry = &utilipset.Entry{
|
entries = []*utilipset.Entry{{
|
||||||
// No need to provide ip info
|
// No need to provide ip info
|
||||||
Port: svcInfo.NodePort(),
|
Port: svcInfo.NodePort(),
|
||||||
Protocol: protocol,
|
Protocol: protocol,
|
||||||
SetType: utilipset.BitmapPort,
|
SetType: utilipset.BitmapPort,
|
||||||
}
|
}}
|
||||||
case "udp":
|
case "udp":
|
||||||
nodePortSet = proxier.ipsetList[kubeNodePortSetUDP]
|
nodePortSet = proxier.ipsetList[kubeNodePortSetUDP]
|
||||||
entry = &utilipset.Entry{
|
entries = []*utilipset.Entry{{
|
||||||
// No need to provide ip info
|
// No need to provide ip info
|
||||||
Port: svcInfo.NodePort(),
|
Port: svcInfo.NodePort(),
|
||||||
Protocol: protocol,
|
Protocol: protocol,
|
||||||
SetType: utilipset.BitmapPort,
|
SetType: utilipset.BitmapPort,
|
||||||
}
|
}}
|
||||||
case "sctp":
|
case "sctp":
|
||||||
nodePortSet = proxier.ipsetList[kubeNodePortSetSCTP]
|
nodePortSet = proxier.ipsetList[kubeNodePortSetSCTP]
|
||||||
entry = &utilipset.Entry{
|
// Since hash ip:port is used for SCTP, all the nodeIPs to be used in the SCTP ipset entries.
|
||||||
IP: proxier.nodeIP.String(),
|
entries = []*utilipset.Entry{}
|
||||||
Port: svcInfo.NodePort(),
|
for _, nodeIP := range nodeIPs {
|
||||||
Protocol: protocol,
|
entries = append(entries, &utilipset.Entry{
|
||||||
SetType: utilipset.HashIPPort,
|
IP: nodeIP.String(),
|
||||||
|
Port: svcInfo.NodePort(),
|
||||||
|
Protocol: protocol,
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// It should never hit
|
// It should never hit
|
||||||
klog.Errorf("Unsupported protocol type: %s", protocol)
|
klog.Errorf("Unsupported protocol type: %s", protocol)
|
||||||
}
|
}
|
||||||
if nodePortSet != nil {
|
if nodePortSet != nil {
|
||||||
if valid := nodePortSet.validateEntry(entry); !valid {
|
entryInvalidErr := false
|
||||||
klog.Errorf("%s", fmt.Sprintf(EntryInvalidErr, entry, nodePortSet.Name))
|
for _, entry := range entries {
|
||||||
|
if valid := nodePortSet.validateEntry(entry); !valid {
|
||||||
|
klog.Errorf("%s", fmt.Sprintf(EntryInvalidErr, entry, nodePortSet.Name))
|
||||||
|
entryInvalidErr = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nodePortSet.activeEntries.Insert(entry.String())
|
||||||
|
}
|
||||||
|
if entryInvalidErr {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
nodePortSet.activeEntries.Insert(entry.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add externaltrafficpolicy=local type nodeport entry
|
// Add externaltrafficpolicy=local type nodeport entry
|
||||||
@ -1257,11 +1272,18 @@ func (proxier *Proxier) syncProxyRules() {
|
|||||||
klog.Errorf("Unsupported protocol type: %s", protocol)
|
klog.Errorf("Unsupported protocol type: %s", protocol)
|
||||||
}
|
}
|
||||||
if nodePortLocalSet != nil {
|
if nodePortLocalSet != nil {
|
||||||
if valid := nodePortLocalSet.validateEntry(entry); !valid {
|
entryInvalidErr := false
|
||||||
klog.Errorf("%s", fmt.Sprintf(EntryInvalidErr, entry, nodePortLocalSet.Name))
|
for _, entry := range entries {
|
||||||
|
if valid := nodePortLocalSet.validateEntry(entry); !valid {
|
||||||
|
klog.Errorf("%s", fmt.Sprintf(EntryInvalidErr, entry, nodePortLocalSet.Name))
|
||||||
|
entryInvalidErr = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nodePortLocalSet.activeEntries.Insert(entry.String())
|
||||||
|
}
|
||||||
|
if entryInvalidErr {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
nodePortLocalSet.activeEntries.Insert(entry.String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -695,6 +696,236 @@ func TestNodePort(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "node port service with protocol sctp on a node with multiple nodeIPs",
|
||||||
|
services: []*v1.Service{
|
||||||
|
makeTestService("ns1", "svc1", func(svc *v1.Service) {
|
||||||
|
svc.Spec.Type = "NodePort"
|
||||||
|
svc.Spec.ClusterIP = "10.20.30.41"
|
||||||
|
svc.Spec.Ports = []v1.ServicePort{{
|
||||||
|
Name: "p80",
|
||||||
|
Port: int32(80),
|
||||||
|
Protocol: v1.ProtocolSCTP,
|
||||||
|
NodePort: int32(3001),
|
||||||
|
}}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
endpoints: []*v1.Endpoints{
|
||||||
|
makeTestEndpoints("ns1", "svc1", func(ept *v1.Endpoints) {
|
||||||
|
ept.Subsets = []v1.EndpointSubset{{
|
||||||
|
Addresses: []v1.EndpointAddress{{
|
||||||
|
IP: "10.180.0.1",
|
||||||
|
}},
|
||||||
|
Ports: []v1.EndpointPort{{
|
||||||
|
Name: "p80",
|
||||||
|
Port: int32(80),
|
||||||
|
}},
|
||||||
|
}}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
nodeIPs: []net.IP{
|
||||||
|
net.ParseIP("100.101.102.103"),
|
||||||
|
net.ParseIP("100.101.102.104"),
|
||||||
|
net.ParseIP("100.101.102.105"),
|
||||||
|
net.ParseIP("2001:db8::1:1"),
|
||||||
|
net.ParseIP("2001:db8::1:2"),
|
||||||
|
net.ParseIP("2001:db8::1:3"),
|
||||||
|
},
|
||||||
|
nodePortAddresses: []string{},
|
||||||
|
expectedIPVS: &ipvstest.FakeIPVS{
|
||||||
|
Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
|
||||||
|
{
|
||||||
|
IP: "10.20.30.41",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("10.20.30.41"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(80),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.103",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("100.101.102.103"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.104",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("100.101.102.104"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.105",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("100.101.102.105"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:1",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("2001:db8::1:1"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:2",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("2001:db8::1:2"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:3",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
Address: net.ParseIP("2001:db8::1:3"),
|
||||||
|
Protocol: "SCTP",
|
||||||
|
Port: uint16(3001),
|
||||||
|
Scheduler: "rr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
|
||||||
|
{
|
||||||
|
IP: "10.20.30.41",
|
||||||
|
Port: 80,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.103",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.104",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.105",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:1",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:2",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:3",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: "SCTP",
|
||||||
|
}: {
|
||||||
|
{
|
||||||
|
Address: net.ParseIP("10.180.0.1"),
|
||||||
|
Port: uint16(80),
|
||||||
|
Weight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedIPSets: netlinktest.ExpectedIPSet{
|
||||||
|
kubeNodePortSetSCTP: {
|
||||||
|
{
|
||||||
|
IP: "100.101.102.103",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.104",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "100.101.102.105",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:1",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:2",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IP: "2001:db8::1:3",
|
||||||
|
Port: 3001,
|
||||||
|
Protocol: strings.ToLower(string(v1.ProtocolSCTP)),
|
||||||
|
SetType: utilipset.HashIPPort,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -2897,10 +3128,14 @@ func checkIPSet(t *testing.T, fp *Proxier, ipSet netlinktest.ExpectedIPSet) {
|
|||||||
t.Errorf("Check ipset entries failed for ipset: %q, expect %d, got %d", set, len(entries), len(ents))
|
t.Errorf("Check ipset entries failed for ipset: %q, expect %d, got %d", set, len(entries), len(ents))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(entries) == 1 {
|
expectedEntries := []string{}
|
||||||
if ents[0] != entries[0].String() {
|
for _, entry := range entries {
|
||||||
t.Errorf("Check ipset entries failed for ipset: %q", set)
|
expectedEntries = append(expectedEntries, entry.String())
|
||||||
}
|
}
|
||||||
|
sort.Strings(ents)
|
||||||
|
sort.Strings(expectedEntries)
|
||||||
|
if !reflect.DeepEqual(ents, expectedEntries) {
|
||||||
|
t.Errorf("Check ipset entries failed for ipset: %q", set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user