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:
Laszlo Janosi
2018-08-25 20:26:25 +00:00
parent a6da2b1472
commit e466bdc67e
25 changed files with 104 additions and 114 deletions

View File

@@ -1572,7 +1572,7 @@ type ContainerPort struct {
HostPort int32
// Required: This must be a valid port number, 0 < x < 65536.
ContainerPort int32
// Required: Supports "TCP" and "UDP". "SCTP" is supported only if no HostPort is specified.
// Required: Supports "TCP", "UDP" and "SCTP"
// +optional
Protocol Protocol
// Optional: What host IP to bind the external port to.
@@ -3177,7 +3177,7 @@ type ServicePort struct {
// the 'Name' field in EndpointPort objects.
Name string
// The IP protocol for this port. Supports "TCP", "UDP", and SCTP.
// The IP protocol for this port. Supports "TCP", "UDP", and "SCTP".
Protocol Protocol
// The port that will be exposed on the service.

View File

@@ -1918,10 +1918,7 @@ func ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc *core.PersistentVo
return allErrs
}
var supportedServicePortProtocols = sets.NewString(string(core.ProtocolTCP), string(core.ProtocolUDP), string(core.ProtocolSCTP))
var supportedLoadBalancerProtocols = sets.NewString(string(core.ProtocolTCP), string(core.ProtocolUDP))
var supportedContainerPortProtocols = sets.NewString(string(core.ProtocolTCP), string(core.ProtocolUDP), string(core.ProtocolSCTP))
var supportedHostPortProtocols = sets.NewString(string(core.ProtocolTCP), string(core.ProtocolUDP))
var supportedPortProtocols = sets.NewString(string(core.ProtocolTCP), string(core.ProtocolUDP), string(core.ProtocolSCTP))
func validateContainerPorts(ports []core.ContainerPort, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
@@ -1954,12 +1951,10 @@ func validateContainerPorts(ports []core.ContainerPort, fldPath *field.Path) fie
}
if len(port.Protocol) == 0 {
allErrs = append(allErrs, field.Required(idxPath.Child("protocol"), ""))
} else if port.HostPort != 0 {
if !supportedHostPortProtocols.Has(string(port.Protocol)) {
allErrs = append(allErrs, field.NotSupported(idxPath.Child("protocol"), port.Protocol, supportedHostPortProtocols.List()))
}
} else if !supportedContainerPortProtocols.Has(string(port.Protocol)) {
allErrs = append(allErrs, field.NotSupported(idxPath.Child("protocol"), port.Protocol, supportedContainerPortProtocols.List()))
} else if !utilfeature.DefaultFeatureGate.Enabled(features.SCTPSupport) && port.Protocol == core.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(idxPath.Child("protocol"), port.Protocol, []string{string(core.ProtocolTCP), string(core.ProtocolUDP)}))
} else if !supportedPortProtocols.Has(string(port.Protocol)) {
allErrs = append(allErrs, field.NotSupported(idxPath.Child("protocol"), port.Protocol, supportedPortProtocols.List()))
}
}
return allErrs
@@ -3733,8 +3728,10 @@ func ValidateService(service *core.Service) field.ErrorList {
includeProtocols := sets.NewString()
for i := range service.Spec.Ports {
portPath := portsPath.Index(i)
if !supportedLoadBalancerProtocols.Has(string(service.Spec.Ports[i].Protocol)) {
allErrs = append(allErrs, field.Invalid(portPath.Child("protocol"), service.Spec.Ports[i].Protocol, "cannot create an external load balancer with non-TCP/UDP ports"))
if !utilfeature.DefaultFeatureGate.Enabled(features.SCTPSupport) && service.Spec.Ports[i].Protocol == core.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(portPath.Child("protocol"), service.Spec.Ports[i].Protocol, []string{string(core.ProtocolTCP), string(core.ProtocolUDP)}))
} else if !supportedPortProtocols.Has(string(service.Spec.Ports[i].Protocol)) {
allErrs = append(allErrs, field.Invalid(portPath.Child("protocol"), service.Spec.Ports[i].Protocol, "cannot create an external load balancer with non-TCP/UDP/SCTP ports"))
} else {
includeProtocols.Insert(string(service.Spec.Ports[i].Protocol))
}
@@ -3829,11 +3826,13 @@ func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService bo
for _, msg := range validation.IsValidPortNum(int(sp.Port)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("port"), sp.Port, msg))
}
if len(sp.Protocol) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("protocol"), ""))
} else if !supportedServicePortProtocols.Has(string(sp.Protocol)) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), sp.Protocol, supportedServicePortProtocols.List()))
} else if !utilfeature.DefaultFeatureGate.Enabled(features.SCTPSupport) && sp.Protocol == core.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), sp.Protocol, []string{string(core.ProtocolTCP), string(core.ProtocolUDP)}))
} else if !supportedPortProtocols.Has(string(sp.Protocol)) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), sp.Protocol, supportedPortProtocols.List()))
}
allErrs = append(allErrs, ValidatePortNumOrName(sp.TargetPort, fldPath.Child("targetPort"))...)
@@ -5201,8 +5200,10 @@ func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *fi
}
if len(port.Protocol) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("protocol"), ""))
} else if !supportedServicePortProtocols.Has(string(port.Protocol)) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), port.Protocol, supportedServicePortProtocols.List()))
} else if !utilfeature.DefaultFeatureGate.Enabled(features.SCTPSupport) && port.Protocol == core.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), port.Protocol, []string{string(core.ProtocolTCP), string(core.ProtocolUDP)}))
} else if !supportedPortProtocols.Has(string(port.Protocol)) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("protocol"), port.Protocol, supportedPortProtocols.List()))
}
return allErrs
}

View File

@@ -4060,6 +4060,7 @@ func TestValidateResourceQuotaWithAlphaLocalStorageCapacityIsolation(t *testing.
}
func TestValidatePorts(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SCTPSupport, true)()
successCase := []core.ContainerPort{
{Name: "abc", ContainerPort: 80, HostPort: 80, Protocol: "TCP"},
{Name: "easy", ContainerPort: 82, Protocol: "TCP"},
@@ -8590,6 +8591,8 @@ func makeValidService() core.Service {
}
func TestValidateService(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SCTPSupport, true)()
testCases := []struct {
name string
tweakSvc func(svc *core.Service) // given a basic valid service, each test case can customize it

View File

@@ -26,6 +26,8 @@ import (
api "k8s.io/kubernetes/pkg/apis/core"
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/apis/networking"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/features"
)
// ValidateNetworkPolicyName can be used to check whether the given networkpolicy
@@ -37,9 +39,12 @@ func ValidateNetworkPolicyName(name string, prefix bool) []string {
// ValidateNetworkPolicyPort validates a NetworkPolicyPort
func ValidateNetworkPolicyPort(port *networking.NetworkPolicyPort, portPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if port.Protocol != nil && *port.Protocol != api.ProtocolTCP && *port.Protocol != api.ProtocolUDP && *port.Protocol != api.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(portPath.Child("protocol"), *port.Protocol, []string{string(api.ProtocolTCP), string(api.ProtocolUDP), string(api.ProtocolSCTP)}))
if utilfeature.DefaultFeatureGate.Enabled(features.SCTPSupport) {
if port.Protocol != nil && *port.Protocol != api.ProtocolTCP && *port.Protocol != api.ProtocolUDP && *port.Protocol != api.ProtocolSCTP {
allErrs = append(allErrs, field.NotSupported(portPath.Child("protocol"), *port.Protocol, []string{string(api.ProtocolTCP), string(api.ProtocolUDP), string(api.ProtocolSCTP)}))
}
} else if port.Protocol != nil && *port.Protocol != api.ProtocolTCP && *port.Protocol != api.ProtocolUDP {
allErrs = append(allErrs, field.NotSupported(portPath.Child("protocol"), *port.Protocol, []string{string(api.ProtocolTCP), string(api.ProtocolUDP)}))
}
if port.Port != nil {
if port.Port.Type == intstr.Int {

View File

@@ -23,6 +23,9 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/networking"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/kubernetes/pkg/features"
)
func TestValidateNetworkPolicy(t *testing.T) {
@@ -30,6 +33,8 @@ func TestValidateNetworkPolicy(t *testing.T) {
protocolUDP := api.ProtocolUDP
protocolICMP := api.Protocol("ICMP")
protocolSCTP := api.ProtocolSCTP
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SCTPSupport, true)()
successCases := []networking.NetworkPolicy{
{
@@ -279,6 +284,7 @@ func TestValidateNetworkPolicy(t *testing.T) {
}
// Success cases are expected to pass validation.
for k, v := range successCases {
if errs := ValidateNetworkPolicy(&v); len(errs) != 0 {
t.Errorf("Expected success for %d, got %v", k, errs)