Set balancing mode

This commit is contained in:
bprashanth 2017-02-08 13:54:27 -08:00
parent 016f3a2bc7
commit 24d9aada11

View file

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"time" "time"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
@ -32,6 +33,41 @@ import (
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
) )
// BalancingMode represents the loadbalancing configuration of an individual
// Backend in a BackendService. This is *effectively* a cluster wide setting
// since you can't mix modes across Backends pointing to the same IG, and you
// can't have a single node in more than 1 loadbalanced IG.
type BalancingMode string
const (
// Rate balances incoming requests based on observed RPS.
// As of this writing, it's the only balancing mode supported by GCE's
// internal LB. This setting doesn't make sense for Kubernets clusters
// because requests can get proxied between instance groups in different
// zones by kube-proxy without GCE even knowing it. Setting equal RPS on
// all IGs should achieve roughly equal distribution of requests.
Rate BalancingMode = "RATE"
// Utilization balances incoming requests based on observed utilization.
// This mode is only useful if you want to divert traffic away from IGs
// running other compute intensive workloads. Utilization statistics are
// aggregated per instances, not per container, and requests can get proxied
// between instance groups in different zones by kube-proxy without GCE even
// knowing about it.
Utilization BalancingMode = "UTILIZATION"
// Connections balances incoming requests based on a connection counter.
// This setting currently doesn't make sense for Kubernetes clusters,
// because we use NodePort Services as HTTP LB backends, so GCE's connection
// counters don't accurately represent connections per container.
Connections BalancingMode = "CONNECTION"
)
// maxRPS is the RPS setting for all Backends with BalancingMode RATE. The exact
// value doesn't matter, as long as it's the same for all Backends. Requests
// received by GCLB above this RPS are NOT dropped, GCLB continues to distribute
// them across IGs.
// TODO: Should this be math.MaxInt64?
const maxRPS = 1
// Backends implements BackendPool. // Backends implements BackendPool.
type Backends struct { type Backends struct {
cloud BackendServices cloud BackendServices
@ -116,20 +152,35 @@ func (b *Backends) create(igs []*compute.InstanceGroup, namedPort *compute.Named
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Create a new backend errs := []string{}
backend := &compute.BackendService{ for _, bm := range []BalancingMode{Rate, Utilization} {
Name: name, backends := getBackendsForIGs(igs)
Protocol: "HTTP", for _, b := range backends {
Backends: getBackendsForIGs(igs), switch bm {
// Api expects one, means little to kubernetes. case Rate:
HealthChecks: []string{hc.SelfLink}, b.MaxRate = maxRPS
Port: namedPort.Port, default:
PortName: namedPort.Name, // TODO: Set utilization and connection limits when we accept them
// as valid fields.
}
b.BalancingMode = string(bm)
}
// Create a new backend
backend := &compute.BackendService{
Name: name,
Protocol: "HTTP",
Backends: backends,
HealthChecks: []string{hc.SelfLink},
Port: namedPort.Port,
PortName: namedPort.Name,
}
if err := b.cloud.CreateBackendService(backend); err != nil {
glog.Infof("Error creating backend service with balancing mode %v", bm)
errs = append(errs, fmt.Sprintf("%v", err))
}
return b.Get(namedPort.Port)
} }
if err := b.cloud.CreateBackendService(backend); err != nil { return nil, fmt.Errorf("%v", strings.Join(errs, "\n"))
return nil, err
}
return b.Get(namedPort.Port)
} }
// Add will get or create a Backend for the given port. // Add will get or create a Backend for the given port.