Update to plumb through configurable locking on different resource types.

This commit is contained in:
Timothy St. Clair 2017-05-12 14:13:37 -05:00
parent a2248a2bcd
commit 1173c84ad9
10 changed files with 65 additions and 61 deletions

View File

@ -191,13 +191,16 @@ func Run(s *options.CMServer) error {
return err return err
} }
rlc := resourcelock.ResourceLockConfig{ rl, err := resourcelock.New(s.LeaderElection.ResourceLock,
Identity: id, "kube-system",
EventRecorder: recorder, "kube-controller-manager",
} leaderElectionClient,
rl, err := leaderelection.GetLock(s.LeaderElection, *leaderElectionClient, rlc) resourcelock.ResourceLockConfig{
Identity: id,
EventRecorder: recorder,
})
if err != nil { if err != nil {
return err glog.Fatalf("error creating lock: %v", err)
} }
leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{ leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{

View File

@ -426,6 +426,7 @@ last-release-pr
leader-elect leader-elect
leader-elect-lease-duration leader-elect-lease-duration
leader-elect-renew-deadline leader-elect-renew-deadline
leader-elect-resource-lock
leader-elect-retry-period leader-elect-retry-period
lease-duration lease-duration
leave-stdin-open leave-stdin-open

View File

@ -685,9 +685,9 @@ type LeaderElectionConfiguration struct {
// acquisition and renewal of a leadership. This is only applicable if // acquisition and renewal of a leadership. This is only applicable if
// leader election is enabled. // leader election is enabled.
RetryPeriod metav1.Duration RetryPeriod metav1.Duration
// LockType indicates the type of locking to use for leadership election. // resourceLock indicates the resource object type that will be used to lock
// Supported options are `endpoints` (default) and `configmap`. // during leader election cycles.
LockType string ResourceLock string
} }
type KubeControllerManagerConfiguration struct { type KubeControllerManagerConfiguration struct {

View File

@ -26,6 +26,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kruntime "k8s.io/apimachinery/pkg/runtime" kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/kubelet/qos"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/master/ports"
@ -193,6 +194,9 @@ func SetDefaults_LeaderElectionConfiguration(obj *LeaderElectionConfiguration) {
if obj.RetryPeriod == zero { if obj.RetryPeriod == zero {
obj.RetryPeriod = metav1.Duration{Duration: 2 * time.Second} obj.RetryPeriod = metav1.Duration{Duration: 2 * time.Second}
} }
if obj.ResourceLock == "" {
obj.ResourceLock = rl.EndpointsResourceLock
}
} }
func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) {

View File

@ -233,9 +233,9 @@ type LeaderElectionConfiguration struct {
// acquisition and renewal of a leadership. This is only applicable if // acquisition and renewal of a leadership. This is only applicable if
// leader election is enabled. // leader election is enabled.
RetryPeriod metav1.Duration `json:"retryPeriod"` RetryPeriod metav1.Duration `json:"retryPeriod"`
// LockType indicates the type of locking to use for leadership election. // resourceLock indicates the resource object type that will be used to lock
// Supported options are `endpoints` (default) and `configmap`. // during leader election cycles.
LockType string ResourceLock string `json:"resourceLock"`
} }
// A configuration field should go in KubeletFlags instead of KubeletConfiguration if any of these are true: // A configuration field should go in KubeletFlags instead of KubeletConfiguration if any of these are true:

View File

@ -814,7 +814,6 @@ func autoConvert_v1alpha1_LeaderElectionConfiguration_To_componentconfig_LeaderE
out.LeaseDuration = in.LeaseDuration out.LeaseDuration = in.LeaseDuration
out.RenewDeadline = in.RenewDeadline out.RenewDeadline = in.RenewDeadline
out.RetryPeriod = in.RetryPeriod out.RetryPeriod = in.RetryPeriod
out.LockType = in.LockType
return nil return nil
} }
@ -830,7 +829,6 @@ func autoConvert_componentconfig_LeaderElectionConfiguration_To_v1alpha1_LeaderE
out.LeaseDuration = in.LeaseDuration out.LeaseDuration = in.LeaseDuration
out.RenewDeadline = in.RenewDeadline out.RenewDeadline = in.RenewDeadline
out.RetryPeriod = in.RetryPeriod out.RetryPeriod = in.RetryPeriod
out.LockType = in.LockType
return nil return nil
} }

View File

@ -14,7 +14,6 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/apis/componentconfig:go_default_library", "//pkg/apis/componentconfig:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/leaderelection/resourcelock:go_default_library", "//pkg/client/leaderelection/resourcelock:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library",

View File

@ -53,12 +53,11 @@ import (
"reflect" "reflect"
"time" "time"
apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/apis/componentconfig"
cs "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"github.com/golang/glog" "github.com/golang/glog"
@ -70,9 +69,6 @@ const (
DefaultLeaseDuration = 15 * time.Second DefaultLeaseDuration = 15 * time.Second
DefaultRenewDeadline = 10 * time.Second DefaultRenewDeadline = 10 * time.Second
DefaultRetryPeriod = 2 * time.Second DefaultRetryPeriod = 2 * time.Second
LockTypeEndpoints = "endpoints"
LockTypeConfigMaps = "configmaps"
) )
// NewLeadereElector creates a LeaderElector from a LeaderElecitionConfig // NewLeadereElector creates a LeaderElector from a LeaderElecitionConfig
@ -229,7 +225,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
// 1. obtain or create the ElectionRecord // 1. obtain or create the ElectionRecord
oldLeaderElectionRecord, err := le.config.Lock.Get() oldLeaderElectionRecord, err := le.config.Lock.Get()
if err != nil { if err != nil {
if !apierrors.IsNotFound(err) { if !errors.IsNotFound(err) {
glog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err) glog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err)
return false return false
} }
@ -288,7 +284,7 @@ func DefaultLeaderElectionConfiguration() componentconfig.LeaderElectionConfigur
LeaseDuration: metav1.Duration{Duration: DefaultLeaseDuration}, LeaseDuration: metav1.Duration{Duration: DefaultLeaseDuration},
RenewDeadline: metav1.Duration{Duration: DefaultRenewDeadline}, RenewDeadline: metav1.Duration{Duration: DefaultRenewDeadline},
RetryPeriod: metav1.Duration{Duration: DefaultRetryPeriod}, RetryPeriod: metav1.Duration{Duration: DefaultRetryPeriod},
LockType: LockTypeEndpoints, ResourceLock: rl.EndpointsResourceLock,
} }
} }
@ -311,33 +307,7 @@ func BindFlags(l *componentconfig.LeaderElectionConfiguration, fs *pflag.FlagSet
fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+ fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+
"The duration the clients should wait between attempting acquisition and renewal "+ "The duration the clients should wait between attempting acquisition and renewal "+
"of a leadership. This is only applicable if leader election is enabled.") "of a leadership. This is only applicable if leader election is enabled.")
fs.StringVar(&l.LockType, "leader-elect-lock-type", l.LockType, fmt.Sprintf(""+ fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+
"Indicates the type of locking to use for leadership election. Supported options "+ "The type of resource resource object that is used for locking during"+
"are `%s` (default) and `%s`.", LockTypeConfigMaps, LockTypeEndpoints)) "leader election. Supported options are `endpoints` (default) and `configmap`.")
}
func GetLock(l componentconfig.LeaderElectionConfiguration, client cs.Clientset, rlc rl.ResourceLockConfig) (rl.Interface, error) {
name := "kube-controller-manager"
switch l.LockType {
case LockTypeEndpoints:
return &rl.EndpointsLock{
EndpointsMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceSystem,
Name: name,
},
Client: client,
LockConfig: rlc,
}, nil
case LockTypeConfigMaps:
return &rl.ConfigMapLock{
ConfigMapMeta: metav1.ObjectMeta{
Namespace: metav1.NamespaceSystem,
Name: name,
},
Client: client,
LockConfig: rlc,
}, nil
default:
return nil, fmt.Errorf("Invalid lock-type provided: %s. Supported types are `%s` and `%s`", l.LockType, LockTypeConfigMaps, LockTypeEndpoints)
}
} }

View File

@ -17,12 +17,17 @@ limitations under the License.
package resourcelock package resourcelock
import ( import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
cs "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
) )
const ( const (
LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader" LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader"
EndpointsResourceLock = "endpoints"
ConfigMapsResourceLock = "configmaps"
) )
// LeaderElectionRecord is the record that is stored in the leader election annotation. // LeaderElectionRecord is the record that is stored in the leader election annotation.
@ -69,3 +74,29 @@ type Interface interface {
// into a string // into a string
Describe() string Describe() string
} }
// Manufacture will create a lock of a given type according to the input parameters
func New(lockType string, ns string, name string, client *cs.Clientset, rlc ResourceLockConfig) (Interface, error) {
switch lockType {
case EndpointsResourceLock:
return &EndpointsLock{
EndpointsMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
},
Client: client,
LockConfig: rlc,
}, nil
case ConfigMapsResourceLock:
return &ConfigMapLock{
ConfigMapMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
},
Client: client,
LockConfig: rlc,
}, nil
default:
return nil, fmt.Errorf("Invalid lock-type %s", lockType)
}
}

View File

@ -26,7 +26,6 @@ import (
goruntime "runtime" goruntime "runtime"
"strconv" "strconv"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/healthz"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
@ -112,17 +111,16 @@ func Run(s *options.SchedulerServer) error {
return fmt.Errorf("unable to get hostname: %v", err) return fmt.Errorf("unable to get hostname: %v", err)
} }
// TODO: enable other lock types rl, err := resourcelock.New(s.LeaderElection.ResourceLock,
rl := &resourcelock.EndpointsLock{ s.LockObjectNamespace,
EndpointsMeta: metav1.ObjectMeta{ s.LockObjectName,
Namespace: s.LockObjectNamespace, kubecli,
Name: s.LockObjectName, resourcelock.ResourceLockConfig{
},
Client: kubecli,
LockConfig: resourcelock.ResourceLockConfig{
Identity: id, Identity: id,
EventRecorder: recorder, EventRecorder: recorder,
}, })
if err != nil {
glog.Fatalf("error creating lock: %v", err)
} }
leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{ leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{