Changes according to the approved KEP. SCTP is supported for HostPort and LoadBalancer. Alpha feature flag SCTPSupport controls the support of SCTP. Kube-proxy config parameter is removed.
This commit is contained in:
@@ -155,12 +155,6 @@ type KubeProxyConfiguration struct {
|
||||
// If set it to a non-zero IP block, kube-proxy will filter that down to just the IPs that applied to the node.
|
||||
// An empty string slice is meant to select all network interfaces.
|
||||
NodePortAddresses []string
|
||||
// sctpUserSpaceNode is to enable the deployment of applications that use a userspace SCTP protocol implementation.
|
||||
// If set to "true" the kube-proxy does not start listening on the host node on the SCTP ports of Services
|
||||
// specified with externalIP or type=NodePort.
|
||||
// If set to "false" kube-proxy listens on the SCTP ports of Services specified with externalIP or type=NodePort.
|
||||
// Default value is "false".
|
||||
SCTPUserSpaceNode bool
|
||||
}
|
||||
|
||||
// Currently, three modes of proxy are available in Linux platform: 'userspace' (older, going to be EOL), 'iptables'
|
||||
|
@@ -151,12 +151,6 @@ type KubeProxyConfiguration struct {
|
||||
// If set it to a non-zero IP block, kube-proxy will filter that down to just the IPs that applied to the node.
|
||||
// An empty string slice is meant to select all network interfaces.
|
||||
NodePortAddresses []string `json:"nodePortAddresses"`
|
||||
// sctpUserSpaceNode is to enable the deployment of applications that use a userspace SCTP protocol implementation.
|
||||
// If set to "true" the kube-proxy does not start listening on the host node on the SCTP ports of Services
|
||||
// specified with externalIP or type=NodePort.
|
||||
// If set to "false" kube-proxy listens on the SCTP ports of Services specified with externalIP or type=NodePort.
|
||||
// Default value is "false".
|
||||
SCTPUserSpaceNode bool `json:"sctpUserSpaceNode"`
|
||||
}
|
||||
|
||||
// Currently, three modes of proxy are available in Linux platform: 'userspace' (older, going to be EOL), 'iptables'
|
||||
|
@@ -144,7 +144,6 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_kubeproxyconfig_KubeProxyCon
|
||||
}
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
|
||||
out.SCTPUserSpaceNode = in.SCTPUserSpaceNode
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -180,7 +179,6 @@ func autoConvert_kubeproxyconfig_KubeProxyConfiguration_To_v1alpha1_KubeProxyCon
|
||||
}
|
||||
out.ConfigSyncPeriod = in.ConfigSyncPeriod
|
||||
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
|
||||
out.SCTPUserSpaceNode = in.SCTPUserSpaceNode
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/ishidawataru/sctp"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -260,10 +259,6 @@ type Proxier struct {
|
||||
// networkInterfacer defines an interface for several net library functions.
|
||||
// Inject for test purpose.
|
||||
networkInterfacer utilproxy.NetworkInterfacer
|
||||
|
||||
// Indicates whether a node is dedicated for applications that use userspace
|
||||
// SCTP stack.
|
||||
sctpUserSpaceNode bool
|
||||
}
|
||||
|
||||
// listenPortOpener opens ports by calling bind() and listen().
|
||||
@@ -295,7 +290,6 @@ func NewProxier(ipt utiliptables.Interface,
|
||||
recorder record.EventRecorder,
|
||||
healthzServer healthcheck.HealthzUpdater,
|
||||
nodePortAddresses []string,
|
||||
sctpUserSpaceNode bool,
|
||||
) (*Proxier, error) {
|
||||
// Set the route_localnet sysctl we need for
|
||||
if err := sysctl.SetSysctl(sysctlRouteLocalnet, 1); err != nil {
|
||||
@@ -352,7 +346,6 @@ func NewProxier(ipt utiliptables.Interface,
|
||||
natRules: bytes.NewBuffer(nil),
|
||||
nodePortAddresses: nodePortAddresses,
|
||||
networkInterfacer: utilproxy.RealNetwork{},
|
||||
sctpUserSpaceNode: sctpUserSpaceNode,
|
||||
}
|
||||
burstSyncs := 2
|
||||
glog.V(3).Infof("minSyncPeriod: %v, syncPeriod: %v, burstSyncs: %d", minSyncPeriod, syncPeriod, burstSyncs)
|
||||
@@ -852,15 +845,9 @@ func (proxier *Proxier) syncProxyRules() {
|
||||
// If the "external" IP happens to be an IP that is local to this
|
||||
// machine, hold the local port open so no other process can open it
|
||||
// (because the socket might open but it would never work).
|
||||
// Exception: if the node is dedicated for applications that use
|
||||
// userspace SCTP stack we must not start listening on the local port
|
||||
// in the kernel because that would load the SCTP kernel module, and
|
||||
// there are interworking issues between the SCTP kernel module and
|
||||
// userspace SCTP stacks.
|
||||
if local, err := utilproxy.IsLocalIP(externalIP); err != nil {
|
||||
glog.Errorf("can't determine if IP is local, assuming not: %v", err)
|
||||
} else if local && (svcInfo.GetProtocol() != api.ProtocolSCTP || !proxier.sctpUserSpaceNode) {
|
||||
|
||||
} else if local && (svcInfo.GetProtocol() != v1.ProtocolSCTP) {
|
||||
lp := utilproxy.LocalPort{
|
||||
Description: "externalIP for " + svcNameString,
|
||||
IP: externalIP,
|
||||
@@ -1029,7 +1016,7 @@ func (proxier *Proxier) syncProxyRules() {
|
||||
if proxier.portsMap[lp] != nil {
|
||||
glog.V(4).Infof("Port %s was open before and is still needed", lp.String())
|
||||
replacementPortsMap[lp] = proxier.portsMap[lp]
|
||||
} else if svcInfo.GetProtocol() != api.ProtocolSCTP || !proxier.sctpUserSpaceNode {
|
||||
} else if svcInfo.GetProtocol() != v1.ProtocolSCTP {
|
||||
socket, err := proxier.portMapper.OpenLocalPort(&lp)
|
||||
if err != nil {
|
||||
glog.Errorf("can't open %s, skipping this nodePort: %v", lp.String(), err)
|
||||
@@ -1432,18 +1419,6 @@ func openLocalPort(lp *utilproxy.LocalPort) (utilproxy.Closeable, error) {
|
||||
return nil, err
|
||||
}
|
||||
socket = conn
|
||||
case "sctp":
|
||||
// There is not any golang/net way to bind or listen on an SCTP socket.
|
||||
// We have to use a 3rd part lib - the same which is used in Docker
|
||||
addr, err := sctp.ResolveSCTPAddr("sctp", net.JoinHostPort(lp.IP, strconv.Itoa(lp.Port)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := sctp.ListenSCTP("sctp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
socket = conn
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown protocol %q", lp.Protocol)
|
||||
}
|
||||
|
@@ -161,9 +161,9 @@ func newFakeServiceInfo(service proxy.ServicePortName, ip net.IP, port int, prot
|
||||
|
||||
func TestDeleteEndpointConnections(t *testing.T) {
|
||||
const (
|
||||
UDP = api.ProtocolUDP
|
||||
TCP = api.ProtocolTCP
|
||||
SCTP = api.ProtocolSCTP
|
||||
UDP = v1.ProtocolUDP
|
||||
TCP = v1.ProtocolTCP
|
||||
SCTP = v1.ProtocolSCTP
|
||||
)
|
||||
testCases := []struct {
|
||||
description string
|
||||
@@ -394,7 +394,6 @@ func NewFakeProxier(ipt utiliptables.Interface) *Proxier {
|
||||
natRules: bytes.NewBuffer(nil),
|
||||
nodePortAddresses: make([]string, 0),
|
||||
networkInterfacer: utilproxytest.NewFakeNetwork(),
|
||||
sctpUserSpaceNode: false,
|
||||
}
|
||||
p.syncRunner = async.NewBoundedFrequencyRunner("test-sync-runner", p.syncProxyRules, 0, time.Minute, 1)
|
||||
return p
|
||||
|
@@ -29,7 +29,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/ishidawataru/sctp"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -234,7 +233,6 @@ type Proxier struct {
|
||||
// networkInterfacer defines an interface for several net library functions.
|
||||
// Inject for test purpose.
|
||||
networkInterfacer utilproxy.NetworkInterfacer
|
||||
sctpUserSpaceNode bool
|
||||
}
|
||||
|
||||
// IPGetter helps get node network interface IP
|
||||
@@ -300,7 +298,6 @@ func NewProxier(ipt utiliptables.Interface,
|
||||
healthzServer healthcheck.HealthzUpdater,
|
||||
scheduler string,
|
||||
nodePortAddresses []string,
|
||||
sctpUserSpaceNode bool,
|
||||
) (*Proxier, error) {
|
||||
// Set the route_localnet sysctl we need for
|
||||
if err := sysctl.SetSysctl(sysctlRouteLocalnet, 1); err != nil {
|
||||
@@ -382,7 +379,6 @@ func NewProxier(ipt utiliptables.Interface,
|
||||
ipset: ipset,
|
||||
nodePortAddresses: nodePortAddresses,
|
||||
networkInterfacer: utilproxy.RealNetwork{},
|
||||
sctpUserSpaceNode: sctpUserSpaceNode,
|
||||
}
|
||||
// initialize ipsetList with all sets we needed
|
||||
proxier.ipsetList = make(map[string]*IPSet)
|
||||
@@ -815,7 +811,9 @@ func (proxier *Proxier) syncProxyRules() {
|
||||
for _, externalIP := range svcInfo.ExternalIPs {
|
||||
if local, err := utilproxy.IsLocalIP(externalIP); err != nil {
|
||||
glog.Errorf("can't determine if IP is local, assuming not: %v", err)
|
||||
} else if local && (svcInfo.GetProtocol() != api.ProtocolSCTP || !proxier.sctpUserSpaceNode) {
|
||||
// We do not start listening on SCTP ports, according to our agreement in the
|
||||
// SCTP support KEP
|
||||
} else if local && (svcInfo.GetProtocol() != v1.ProtocolSCTP) {
|
||||
lp := utilproxy.LocalPort{
|
||||
Description: "externalIP for " + svcNameString,
|
||||
IP: externalIP,
|
||||
@@ -1014,7 +1012,9 @@ func (proxier *Proxier) syncProxyRules() {
|
||||
if proxier.portsMap[lp] != nil {
|
||||
glog.V(4).Infof("Port %s was open before and is still needed", lp.String())
|
||||
replacementPortsMap[lp] = proxier.portsMap[lp]
|
||||
} else if svcInfo.GetProtocol() != api.ProtocolSCTP || !proxier.sctpUserSpaceNode {
|
||||
// We do not start listening on SCTP ports, according to our agreement in the
|
||||
// SCTP support KEP
|
||||
} else if svcInfo.GetProtocol() != v1.ProtocolSCTP {
|
||||
socket, err := proxier.portMapper.OpenLocalPort(&lp)
|
||||
if err != nil {
|
||||
glog.Errorf("can't open %s, skipping this nodePort: %v", lp.String(), err)
|
||||
@@ -1650,18 +1650,6 @@ func openLocalPort(lp *utilproxy.LocalPort) (utilproxy.Closeable, error) {
|
||||
return nil, err
|
||||
}
|
||||
socket = conn
|
||||
case "sctp":
|
||||
// SCTP is not supported by golang/net, or any other built-in lib,
|
||||
// so we have to manage SCTP via a 3rd party lib.
|
||||
sctpAddr, err := sctp.ResolveSCTPAddr("sctp", net.JoinHostPort(lp.IP, strconv.Itoa(lp.Port)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := sctp.ListenSCTP("sctp", sctpAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
socket = conn
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown protocol %q", lp.Protocol)
|
||||
}
|
||||
|
@@ -171,7 +171,6 @@ func NewFakeProxier(ipt utiliptables.Interface, ipvs utilipvs.Interface, ipset u
|
||||
ipsetList: ipsetList,
|
||||
nodePortAddresses: make([]string, 0),
|
||||
networkInterfacer: proxyutiltest.NewFakeNetwork(),
|
||||
sctpUserSpaceNode: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1362,8 +1361,8 @@ func TestBuildServiceMapAddRemove(t *testing.T) {
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "foobar", "UDP", 8675, 30061, 7000)
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "baz", "UDP", 8676, 30062, 7001)
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "sctpfoo", "SCTP", 8677, 30063, 7002)
|
||||
svc.Status.LoadBalancer = api.LoadBalancerStatus{
|
||||
Ingress: []api.LoadBalancerIngress{
|
||||
svc.Status.LoadBalancer = v1.LoadBalancerStatus{
|
||||
Ingress: []v1.LoadBalancerIngress{
|
||||
{IP: "10.1.2.4"},
|
||||
},
|
||||
}
|
||||
@@ -1375,8 +1374,8 @@ func TestBuildServiceMapAddRemove(t *testing.T) {
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "foobar2", "UDP", 8677, 30063, 7002)
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "baz", "UDP", 8678, 30064, 7003)
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "sctpbaz", "SCTP", 8679, 30065, 7004)
|
||||
svc.Status.LoadBalancer = api.LoadBalancerStatus{
|
||||
Ingress: []api.LoadBalancerIngress{
|
||||
svc.Status.LoadBalancer = v1.LoadBalancerStatus{
|
||||
Ingress: []v1.LoadBalancerIngress{
|
||||
{IP: "10.1.2.3"},
|
||||
},
|
||||
}
|
||||
@@ -1460,9 +1459,9 @@ func TestBuildServiceMapServiceHeadless(t *testing.T) {
|
||||
svc.Spec.Type = v1.ServiceTypeClusterIP
|
||||
svc.Spec.ClusterIP = v1.ClusterIPNone
|
||||
}),
|
||||
makeTestService("somewhere-else", "headless-sctp", func(svc *api.Service) {
|
||||
svc.Spec.Type = api.ServiceTypeClusterIP
|
||||
svc.Spec.ClusterIP = api.ClusterIPNone
|
||||
makeTestService("somewhere-else", "headless-sctp", func(svc *v1.Service) {
|
||||
svc.Spec.Type = v1.ServiceTypeClusterIP
|
||||
svc.Spec.ClusterIP = v1.ClusterIPNone
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "sip", "SCTP", 1235, 0, 0)
|
||||
}),
|
||||
)
|
||||
@@ -2634,7 +2633,7 @@ func Test_syncService(t *testing.T) {
|
||||
// case 4, SCTP, old virtual server is same as new virtual server
|
||||
oldVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 80,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2642,7 +2641,7 @@ func Test_syncService(t *testing.T) {
|
||||
svcName: "foo",
|
||||
newVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 80,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2653,7 +2652,7 @@ func Test_syncService(t *testing.T) {
|
||||
// case 5, old virtual server is different from new virtual server
|
||||
oldVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 8080,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2661,7 +2660,7 @@ func Test_syncService(t *testing.T) {
|
||||
svcName: "bar",
|
||||
newVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 8080,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagPersistent,
|
||||
@@ -2672,7 +2671,7 @@ func Test_syncService(t *testing.T) {
|
||||
// case 6, old virtual server is different from new virtual server
|
||||
oldVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 8080,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2680,7 +2679,7 @@ func Test_syncService(t *testing.T) {
|
||||
svcName: "bar",
|
||||
newVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 8080,
|
||||
Scheduler: "wlc",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2693,7 +2692,7 @@ func Test_syncService(t *testing.T) {
|
||||
svcName: "baz",
|
||||
newVirtualServer: &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Protocol: string(api.ProtocolSCTP),
|
||||
Protocol: string(v1.ProtocolSCTP),
|
||||
Port: 53,
|
||||
Scheduler: "rr",
|
||||
Flags: utilipvs.FlagHashed,
|
||||
@@ -2828,7 +2827,6 @@ func TestCleanLegacyService(t *testing.T) {
|
||||
nil,
|
||||
DefaultScheduler,
|
||||
make([]string, 0),
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
|
@@ -116,9 +116,9 @@ func TestServiceToServiceMap(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "headless sctp service",
|
||||
service: makeTestService("ns2", "headless", func(svc *api.Service) {
|
||||
svc.Spec.Type = api.ServiceTypeClusterIP
|
||||
svc.Spec.ClusterIP = api.ClusterIPNone
|
||||
service: makeTestService("ns2", "headless", func(svc *v1.Service) {
|
||||
svc.Spec.Type = v1.ServiceTypeClusterIP
|
||||
svc.Spec.ClusterIP = v1.ClusterIPNone
|
||||
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "sip", "SCTP", 7777, 0, 0)
|
||||
}),
|
||||
expected: map[ServicePortName]*BaseServiceInfo{},
|
||||
|
Reference in New Issue
Block a user