From a2248a2bcde6407a12d2fe4fa9638f6c4b697058 Mon Sep 17 00:00:00 2001 From: Jamie Hannaford Date: Fri, 5 May 2017 14:01:59 +0200 Subject: [PATCH] Add lock type flags for controller-manager leadership election --- .../app/controllermanager.go | 21 ++++------ pkg/apis/componentconfig/types.go | 3 ++ pkg/apis/componentconfig/v1alpha1/types.go | 3 ++ .../v1alpha1/zz_generated.conversion.go | 2 + pkg/client/leaderelection/BUILD | 1 + pkg/client/leaderelection/leaderelection.go | 38 ++++++++++++++++++- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 6bb57029d34..7b656786377 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -32,7 +32,6 @@ import ( "strconv" "time" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" @@ -192,21 +191,17 @@ func Run(s *options.CMServer) error { return err } - // TODO: enable other lock types - rl := resourcelock.EndpointsLock{ - EndpointsMeta: metav1.ObjectMeta{ - Namespace: "kube-system", - Name: "kube-controller-manager", - }, - Client: leaderElectionClient, - LockConfig: resourcelock.ResourceLockConfig{ - Identity: id, - EventRecorder: recorder, - }, + rlc := resourcelock.ResourceLockConfig{ + Identity: id, + EventRecorder: recorder, + } + rl, err := leaderelection.GetLock(s.LeaderElection, *leaderElectionClient, rlc) + if err != nil { + return err } leaderelection.RunOrDie(leaderelection.LeaderElectionConfig{ - Lock: &rl, + Lock: rl, LeaseDuration: s.LeaderElection.LeaseDuration.Duration, RenewDeadline: s.LeaderElection.RenewDeadline.Duration, RetryPeriod: s.LeaderElection.RetryPeriod.Duration, diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index 69cc119424a..3c4b8db98a0 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -685,6 +685,9 @@ type LeaderElectionConfiguration struct { // acquisition and renewal of a leadership. This is only applicable if // leader election is enabled. RetryPeriod metav1.Duration + // LockType indicates the type of locking to use for leadership election. + // Supported options are `endpoints` (default) and `configmap`. + LockType string } type KubeControllerManagerConfiguration struct { diff --git a/pkg/apis/componentconfig/v1alpha1/types.go b/pkg/apis/componentconfig/v1alpha1/types.go index 8211e8f0aaa..02bb13e6b51 100644 --- a/pkg/apis/componentconfig/v1alpha1/types.go +++ b/pkg/apis/componentconfig/v1alpha1/types.go @@ -233,6 +233,9 @@ type LeaderElectionConfiguration struct { // acquisition and renewal of a leadership. This is only applicable if // leader election is enabled. RetryPeriod metav1.Duration `json:"retryPeriod"` + // LockType indicates the type of locking to use for leadership election. + // Supported options are `endpoints` (default) and `configmap`. + LockType string } // A configuration field should go in KubeletFlags instead of KubeletConfiguration if any of these are true: diff --git a/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go b/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go index f607ea6174c..e73e7bfc065 100644 --- a/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go @@ -814,6 +814,7 @@ func autoConvert_v1alpha1_LeaderElectionConfiguration_To_componentconfig_LeaderE out.LeaseDuration = in.LeaseDuration out.RenewDeadline = in.RenewDeadline out.RetryPeriod = in.RetryPeriod + out.LockType = in.LockType return nil } @@ -829,6 +830,7 @@ func autoConvert_componentconfig_LeaderElectionConfiguration_To_v1alpha1_LeaderE out.LeaseDuration = in.LeaseDuration out.RenewDeadline = in.RenewDeadline out.RetryPeriod = in.RetryPeriod + out.LockType = in.LockType return nil } diff --git a/pkg/client/leaderelection/BUILD b/pkg/client/leaderelection/BUILD index 796151b02f2..a3b352b2390 100644 --- a/pkg/client/leaderelection/BUILD +++ b/pkg/client/leaderelection/BUILD @@ -14,6 +14,7 @@ go_library( tags = ["automanaged"], deps = [ "//pkg/apis/componentconfig:go_default_library", + "//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/leaderelection/resourcelock:go_default_library", "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", diff --git a/pkg/client/leaderelection/leaderelection.go b/pkg/client/leaderelection/leaderelection.go index 4a22eded442..01818db83e0 100644 --- a/pkg/client/leaderelection/leaderelection.go +++ b/pkg/client/leaderelection/leaderelection.go @@ -53,11 +53,12 @@ import ( "reflect" "time" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/kubernetes/pkg/apis/componentconfig" + cs "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "github.com/golang/glog" @@ -69,6 +70,9 @@ const ( DefaultLeaseDuration = 15 * time.Second DefaultRenewDeadline = 10 * time.Second DefaultRetryPeriod = 2 * time.Second + + LockTypeEndpoints = "endpoints" + LockTypeConfigMaps = "configmaps" ) // NewLeadereElector creates a LeaderElector from a LeaderElecitionConfig @@ -225,7 +229,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool { // 1. obtain or create the ElectionRecord oldLeaderElectionRecord, err := le.config.Lock.Get() if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { glog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err) return false } @@ -284,6 +288,7 @@ func DefaultLeaderElectionConfiguration() componentconfig.LeaderElectionConfigur LeaseDuration: metav1.Duration{Duration: DefaultLeaseDuration}, RenewDeadline: metav1.Duration{Duration: DefaultRenewDeadline}, RetryPeriod: metav1.Duration{Duration: DefaultRetryPeriod}, + LockType: LockTypeEndpoints, } } @@ -306,4 +311,33 @@ func BindFlags(l *componentconfig.LeaderElectionConfiguration, fs *pflag.FlagSet fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+ "The duration the clients should wait between attempting acquisition and renewal "+ "of a leadership. This is only applicable if leader election is enabled.") + fs.StringVar(&l.LockType, "leader-elect-lock-type", l.LockType, fmt.Sprintf(""+ + "Indicates the type of locking to use for leadership election. Supported options "+ + "are `%s` (default) and `%s`.", LockTypeConfigMaps, LockTypeEndpoints)) +} + +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) + } }