Commit cd3ab5d8 authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #24655 from njuicsgz/master

Automatic merge from submit-queue kube-proxy userspace, enable RR if connect endpoint which is session affinity fails for issue #24648
parents fa95788e c75cb94b
...@@ -27,7 +27,7 @@ import ( ...@@ -27,7 +27,7 @@ import (
type LoadBalancer interface { type LoadBalancer interface {
// NextEndpoint returns the endpoint to handle a request for the given // NextEndpoint returns the endpoint to handle a request for the given
// service-port and source address. // service-port and source address.
NextEndpoint(service proxy.ServicePortName, srcAddr net.Addr) (string, error) NextEndpoint(service proxy.ServicePortName, srcAddr net.Addr, sessionAffinityReset bool) (string, error)
NewService(service proxy.ServicePortName, sessionAffinityType api.ServiceAffinity, stickyMaxAgeMinutes int) error NewService(service proxy.ServicePortName, sessionAffinityType api.ServiceAffinity, stickyMaxAgeMinutes int) error
CleanupStaleStickySessions(service proxy.ServicePortName) CleanupStaleStickySessions(service proxy.ServicePortName)
} }
...@@ -87,8 +87,9 @@ func (tcp *tcpProxySocket) ListenPort() int { ...@@ -87,8 +87,9 @@ func (tcp *tcpProxySocket) ListenPort() int {
} }
func tryConnect(service proxy.ServicePortName, srcAddr net.Addr, protocol string, proxier *Proxier) (out net.Conn, err error) { func tryConnect(service proxy.ServicePortName, srcAddr net.Addr, protocol string, proxier *Proxier) (out net.Conn, err error) {
sessionAffinityReset := false
for _, dialTimeout := range endpointDialTimeout { for _, dialTimeout := range endpointDialTimeout {
endpoint, err := proxier.loadBalancer.NextEndpoint(service, srcAddr) endpoint, err := proxier.loadBalancer.NextEndpoint(service, srcAddr, sessionAffinityReset)
if err != nil { if err != nil {
glog.Errorf("Couldn't find an endpoint for %s: %v", service, err) glog.Errorf("Couldn't find an endpoint for %s: %v", service, err)
return nil, err return nil, err
...@@ -102,6 +103,7 @@ func tryConnect(service proxy.ServicePortName, srcAddr net.Addr, protocol string ...@@ -102,6 +103,7 @@ func tryConnect(service proxy.ServicePortName, srcAddr net.Addr, protocol string
panic("Dial failed: " + err.Error()) panic("Dial failed: " + err.Error())
} }
glog.Errorf("Dial failed: %v", err) glog.Errorf("Dial failed: %v", err)
sessionAffinityReset = true
continue continue
} }
return outConn, nil return outConn, nil
......
...@@ -114,7 +114,7 @@ func isSessionAffinity(affinity *affinityPolicy) bool { ...@@ -114,7 +114,7 @@ func isSessionAffinity(affinity *affinityPolicy) bool {
// NextEndpoint returns a service endpoint. // NextEndpoint returns a service endpoint.
// The service endpoint is chosen using the round-robin algorithm. // The service endpoint is chosen using the round-robin algorithm.
func (lb *LoadBalancerRR) NextEndpoint(svcPort proxy.ServicePortName, srcAddr net.Addr) (string, error) { func (lb *LoadBalancerRR) NextEndpoint(svcPort proxy.ServicePortName, srcAddr net.Addr, sessionAffinityReset bool) (string, error) {
// Coarse locking is simple. We can get more fine-grained if/when we // Coarse locking is simple. We can get more fine-grained if/when we
// can prove it matters. // can prove it matters.
lb.lock.Lock() lb.lock.Lock()
...@@ -139,13 +139,15 @@ func (lb *LoadBalancerRR) NextEndpoint(svcPort proxy.ServicePortName, srcAddr ne ...@@ -139,13 +139,15 @@ func (lb *LoadBalancerRR) NextEndpoint(svcPort proxy.ServicePortName, srcAddr ne
if err != nil { if err != nil {
return "", fmt.Errorf("malformed source address %q: %v", srcAddr.String(), err) return "", fmt.Errorf("malformed source address %q: %v", srcAddr.String(), err)
} }
sessionAffinity, exists := state.affinity.affinityMap[ipaddr] if !sessionAffinityReset {
if exists && int(time.Now().Sub(sessionAffinity.lastUsed).Minutes()) < state.affinity.ttlMinutes { sessionAffinity, exists := state.affinity.affinityMap[ipaddr]
// Affinity wins. if exists && int(time.Now().Sub(sessionAffinity.lastUsed).Minutes()) < state.affinity.ttlMinutes {
endpoint := sessionAffinity.endpoint // Affinity wins.
sessionAffinity.lastUsed = time.Now() endpoint := sessionAffinity.endpoint
glog.V(4).Infof("NextEndpoint for service %q from IP %s with sessionAffinity %+v: %s", svcPort, ipaddr, sessionAffinity, endpoint) sessionAffinity.lastUsed = time.Now()
return endpoint, nil glog.V(4).Infof("NextEndpoint for service %q from IP %s with sessionAffinity %+v: %s", svcPort, ipaddr, sessionAffinity, endpoint)
return endpoint, nil
}
} }
} }
// Take the next endpoint. // Take the next endpoint.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment