Merge pull request #49850 from m1093782566/service-session-timeout
Automatic merge from submit-queue (batch tested with PRs 49850, 47782, 50595, 50730, 51341) Paramaterize `stickyMaxAgeMinutes` for service in API **What this PR does / why we need it**: Currently I find `stickyMaxAgeMinutes` for a session affinity type service is hard code to 180min. There is a TODO comment, see https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/iptables/proxier.go#L205 I think the seesion sticky max time varies from service to service and users may not aware of it since it's hard coded in all proxier.go - iptables, userspace and winuserspace. Once we parameterize it in API, users can set/get the values for their different services. Perhaps, we can introduce a new field `api.ClientIPAffinityConfig` in `api.ServiceSpec`. There is an initial discussion about it in sig-network group. See, https://groups.google.com/forum/#!topic/kubernetes-sig-network/i-LkeHrjs80 **Which issue this PR fixes**: fixes #49831 **Special notes for your reviewer**: **Release note**: ```release-note Paramaterize session affinity timeout seconds in service API for Client IP based session affinity. ```
This commit is contained in:
@@ -19,6 +19,7 @@ package validation
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -28,8 +29,6 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"math"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@@ -1873,6 +1872,33 @@ func validateProbe(probe *api.Probe, fldPath *field.Path) field.ErrorList {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateClientIPAffinityConfig(config *api.SessionAffinityConfig, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if config == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath, fmt.Sprintf("when session affinity type is %s", api.ServiceAffinityClientIP)))
|
||||
return allErrs
|
||||
}
|
||||
if config.ClientIP == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("clientIP"), fmt.Sprintf("when session affinity type is %s", api.ServiceAffinityClientIP)))
|
||||
return allErrs
|
||||
}
|
||||
if config.ClientIP.TimeoutSeconds == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("clientIP").Child("timeoutSeconds"), fmt.Sprintf("when session affinity type is %s", api.ServiceAffinityClientIP)))
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateAffinityTimeout(config.ClientIP.TimeoutSeconds, fldPath.Child("clientIP").Child("timeoutSeconds"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateAffinityTimeout(timeout *int32, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if *timeout <= 0 || *timeout > api.MaxClientIPServiceAffinitySeconds {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, timeout, fmt.Sprintf("must be greater than 0 and less than %d", api.MaxClientIPServiceAffinitySeconds)))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// AccumulateUniqueHostPorts extracts each HostPort of each Container,
|
||||
// accumulating the results and returning an error if any ports conflict.
|
||||
func AccumulateUniqueHostPorts(containers []api.Container, accumulator *sets.String, fldPath *field.Path) field.ErrorList {
|
||||
@@ -2914,6 +2940,14 @@ func ValidateService(service *api.Service) field.ErrorList {
|
||||
allErrs = append(allErrs, field.NotSupported(specPath.Child("sessionAffinity"), service.Spec.SessionAffinity, supportedSessionAffinityType.List()))
|
||||
}
|
||||
|
||||
if service.Spec.SessionAffinity == api.ServiceAffinityClientIP {
|
||||
allErrs = append(allErrs, validateClientIPAffinityConfig(service.Spec.SessionAffinityConfig, specPath.Child("sessionAffinityConfig"))...)
|
||||
} else if service.Spec.SessionAffinity == api.ServiceAffinityNone {
|
||||
if service.Spec.SessionAffinityConfig != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(specPath.Child("sessionAffinityConfig"), fmt.Sprintf("must not be set when session affinity is %s", string(api.ServiceAffinityNone))))
|
||||
}
|
||||
}
|
||||
|
||||
if helper.IsServiceIPSet(service) {
|
||||
if ip := net.ParseIP(service.Spec.ClusterIP); ip == nil {
|
||||
allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty, 'None', or a valid IP address"))
|
||||
|
Reference in New Issue
Block a user