diff --git a/cmd/agent/app/agent.go b/cmd/agent/app/agent.go index e8584ad89..8295b1e30 100644 --- a/cmd/agent/app/agent.go +++ b/cmd/agent/app/agent.go @@ -67,10 +67,12 @@ func run(ctx context.Context, karmadaConfig karmadactl.KarmadaConfig, opts *opti } controllerManager, err := controllerruntime.NewManager(controlPlaneRestConfig, controllerruntime.Options{ - Scheme: gclient.NewSchema(), - Namespace: executionSpace, - LeaderElection: false, - LeaderElectionID: "agent.karmada.io", + Scheme: gclient.NewSchema(), + Namespace: executionSpace, + LeaderElection: opts.LeaderElection.LeaderElect, + LeaderElectionID: fmt.Sprintf("karmada-agent-%s", opts.ClusterName), + LeaderElectionNamespace: opts.LeaderElection.ResourceNamespace, + LeaderElectionResourceLock: opts.LeaderElection.ResourceLock, }) if err != nil { klog.Errorf("failed to build controller manager: %v", err) diff --git a/cmd/agent/app/options/options.go b/cmd/agent/app/options/options.go index 3f49daecd..270ab045c 100644 --- a/cmd/agent/app/options/options.go +++ b/cmd/agent/app/options/options.go @@ -5,10 +5,15 @@ import ( "github.com/spf13/pflag" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/leaderelection/resourcelock" + componentbaseconfig "k8s.io/component-base/config" + + "github.com/karmada-io/karmada/pkg/util" ) // Options contains everything necessary to create and run controller-manager. type Options struct { + LeaderElection componentbaseconfig.LeaderElectionConfiguration KarmadaKubeConfig string // ClusterContext is the name of the cluster context in control plane KUBECONFIG file. // Default value is the current-context. @@ -28,7 +33,13 @@ type Options struct { // NewOptions builds an default scheduler options. func NewOptions() *Options { - return &Options{} + return &Options{ + LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: true, + ResourceLock: resourcelock.LeasesResourceLock, + ResourceNamespace: util.NamespaceKarmadaSystem, + }, + } } // AddFlags adds flags of scheduler to the specified FlagSet @@ -37,6 +48,7 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) { return } + fs.BoolVar(&o.LeaderElection.LeaderElect, "leader-elect", true, "Start a leader election client and gain leadership before executing the main loop. Enable this when running replicated components for high availability.") fs.StringVar(&o.KarmadaKubeConfig, "karmada-kubeconfig", o.KarmadaKubeConfig, "Path to karmada control plane kubeconfig file.") fs.StringVar(&o.KarmadaContext, "karmada-context", "", "Name of the cluster context in karmada control plane kubeconfig file.") fs.StringVar(&o.ClusterName, "cluster-name", o.ClusterName, "Name of member cluster that the agent serves for.") diff --git a/cmd/controller-manager/app/controllermanager.go b/cmd/controller-manager/app/controllermanager.go index 72b709f45..ea24a73a3 100644 --- a/cmd/controller-manager/app/controllermanager.go +++ b/cmd/controller-manager/app/controllermanager.go @@ -44,7 +44,6 @@ func NewControllerManagerCommand(ctx context.Context) *cobra.Command { Use: "controller-manager", Long: `The controller manager runs a bunch of controllers`, Run: func(cmd *cobra.Command, args []string) { - opts.Complete() if err := Run(ctx, opts); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) @@ -64,11 +63,13 @@ func Run(ctx context.Context, opts *options.Options) error { panic(err) } controllerManager, err := controllerruntime.NewManager(config, controllerruntime.Options{ - Scheme: gclient.NewSchema(), - LeaderElection: opts.LeaderElection.LeaderElect, - LeaderElectionID: "karmada-controller-manager", - HealthProbeBindAddress: fmt.Sprintf("%s:%d", opts.BindAddress, opts.SecurePort), - LivenessEndpointName: "/healthz", + Scheme: gclient.NewSchema(), + LeaderElection: opts.LeaderElection.LeaderElect, + LeaderElectionID: opts.LeaderElection.ResourceName, + LeaderElectionNamespace: opts.LeaderElection.ResourceNamespace, + LeaderElectionResourceLock: opts.LeaderElection.ResourceLock, + HealthProbeBindAddress: fmt.Sprintf("%s:%d", opts.BindAddress, opts.SecurePort), + LivenessEndpointName: "/healthz", }) if err != nil { klog.Errorf("failed to build controller manager: %v", err) diff --git a/cmd/controller-manager/app/options/options.go b/cmd/controller-manager/app/options/options.go index 19263c475..4b8079c99 100644 --- a/cmd/controller-manager/app/options/options.go +++ b/cmd/controller-manager/app/options/options.go @@ -7,13 +7,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/leaderelection/resourcelock" componentbaseconfig "k8s.io/component-base/config" - "k8s.io/klog/v2" -) -var ( - defaultElectionLeaseDuration = metav1.Duration{Duration: 15 * time.Second} - defaultElectionRenewDeadline = metav1.Duration{Duration: 10 * time.Second} - defaultElectionRetryPeriod = metav1.Duration{Duration: 2 * time.Second} + "github.com/karmada-io/karmada/pkg/util" ) const ( @@ -23,7 +18,6 @@ const ( // Options contains everything necessary to create and run controller-manager. type Options struct { - HostNamespace string LeaderElection componentbaseconfig.LeaderElectionConfiguration // BindAddress is the IP address on which to listen for the --secure-port port. BindAddress string @@ -57,34 +51,13 @@ type Options struct { // NewOptions builds an empty options. func NewOptions() *Options { - return &Options{} -} - -// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. -func (o *Options) Complete() { - if len(o.HostNamespace) == 0 { - o.HostNamespace = "default" - klog.Infof("Set default value: Options.HostNamespace = %s", "default") - } - - if len(o.LeaderElection.ResourceLock) == 0 { - o.LeaderElection.ResourceLock = resourcelock.EndpointsLeasesResourceLock - klog.Infof("Set default value: Options.LeaderElection.ResourceLock = %s", resourcelock.EndpointsLeasesResourceLock) - } - - if o.LeaderElection.LeaseDuration.Duration.Seconds() == 0 { - o.LeaderElection.LeaseDuration = defaultElectionLeaseDuration - klog.Infof("Set default value: Options.LeaderElection.LeaseDuration = %s", defaultElectionLeaseDuration.Duration.String()) - } - - if o.LeaderElection.RenewDeadline.Duration.Seconds() == 0 { - o.LeaderElection.RenewDeadline = defaultElectionRenewDeadline - klog.Infof("Set default value: Options.LeaderElection.RenewDeadline = %s", defaultElectionRenewDeadline.Duration.String()) - } - - if o.LeaderElection.RetryPeriod.Duration.Seconds() == 0 { - o.LeaderElection.RetryPeriod = defaultElectionRetryPeriod - klog.Infof("Set default value: Options.LeaderElection.RetryPeriod = %s", defaultElectionRetryPeriod.Duration.String()) + return &Options{ + LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ + LeaderElect: true, + ResourceLock: resourcelock.LeasesResourceLock, + ResourceNamespace: util.NamespaceKarmadaSystem, + ResourceName: "karmada-controller-manager", + }, } } diff --git a/cmd/scheduler/app/options/options.go b/cmd/scheduler/app/options/options.go index ef11cd5ef..f108ee303 100644 --- a/cmd/scheduler/app/options/options.go +++ b/cmd/scheduler/app/options/options.go @@ -7,6 +7,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/leaderelection/resourcelock" componentbaseconfig "k8s.io/component-base/config" + + "github.com/karmada-io/karmada/pkg/util" ) const ( @@ -38,11 +40,13 @@ type Options struct { func NewOptions() *Options { return &Options{ LeaderElection: componentbaseconfig.LeaderElectionConfiguration{ - LeaderElect: false, - ResourceLock: resourcelock.LeasesResourceLock, - LeaseDuration: defaultElectionLeaseDuration, - RenewDeadline: defaultElectionRenewDeadline, - RetryPeriod: defaultElectionRetryPeriod, + LeaderElect: true, + ResourceLock: resourcelock.LeasesResourceLock, + ResourceNamespace: util.NamespaceKarmadaSystem, + ResourceName: "karmada-scheduler", + LeaseDuration: defaultElectionLeaseDuration, + RenewDeadline: defaultElectionRenewDeadline, + RetryPeriod: defaultElectionRetryPeriod, }, } } @@ -53,8 +57,7 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) { return } - fs.BoolVar(&o.LeaderElection.LeaderElect, "leader-elect", false, "Enable leader election, which must be true when running multi instances.") - fs.StringVar(&o.LeaderElection.ResourceNamespace, "lock-namespace", "", "Define the namespace of the lock object.") + fs.BoolVar(&o.LeaderElection.LeaderElect, "leader-elect", true, "Enable leader election, which must be true when running multi instances.") fs.StringVar(&o.KubeConfig, "kubeconfig", o.KubeConfig, "Path to a KubeConfig. Only required if out-of-cluster.") fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server. Overrides any value in KubeConfig. Only required if out-of-cluster.") fs.StringVar(&o.BindAddress, "bind-address", defaultBindAddress, "The IP address on which to listen for the --secure-port port.") diff --git a/cmd/scheduler/app/scheduler.go b/cmd/scheduler/app/scheduler.go index 2d5205d06..a12c627b3 100644 --- a/cmd/scheduler/app/scheduler.go +++ b/cmd/scheduler/app/scheduler.go @@ -80,7 +80,7 @@ func run(opts *options.Options, stopChan <-chan struct{}) error { rl, err := resourcelock.New(opts.LeaderElection.ResourceLock, opts.LeaderElection.ResourceNamespace, - "karmada-scheduler", + opts.LeaderElection.ResourceName, leaderElectionClient.CoreV1(), leaderElectionClient.CoordinationV1(), resourcelock.ResourceLockConfig{ diff --git a/cmd/webhook/app/options/options.go b/cmd/webhook/app/options/options.go index 3e29b74d1..e66b78c52 100644 --- a/cmd/webhook/app/options/options.go +++ b/cmd/webhook/app/options/options.go @@ -1,19 +1,7 @@ package options import ( - "time" - "github.com/spf13/pflag" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/leaderelection/resourcelock" - componentbaseconfig "k8s.io/component-base/config" - "k8s.io/klog/v2" -) - -var ( - defaultElectionLeaseDuration = metav1.Duration{Duration: 15 * time.Second} - defaultElectionRenewDeadline = metav1.Duration{Duration: 10 * time.Second} - defaultElectionRetryPeriod = metav1.Duration{Duration: 2 * time.Second} ) const ( @@ -33,8 +21,7 @@ type Options struct { // CertDir is the directory that contains the server key and certificate. // if not set, webhook server would look up the server key and certificate in {TempDir}/k8s-webhook-server/serving-certs. // The server key and certificate must be named `tls.key` and `tls.crt`, respectively. - CertDir string - LeaderElection componentbaseconfig.LeaderElectionConfiguration + CertDir string } // NewOptions builds an empty options. @@ -42,29 +29,6 @@ func NewOptions() *Options { return &Options{} } -// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. -func (o *Options) Complete() { - if len(o.LeaderElection.ResourceLock) == 0 { - o.LeaderElection.ResourceLock = resourcelock.EndpointsLeasesResourceLock - klog.Infof("Set default value: Options.LeaderElection.ResourceLock = %s", resourcelock.EndpointsLeasesResourceLock) - } - - if o.LeaderElection.LeaseDuration.Duration.Seconds() == 0 { - o.LeaderElection.LeaseDuration = defaultElectionLeaseDuration - klog.Infof("Set default value: Options.LeaderElection.LeaseDuration = %s", defaultElectionLeaseDuration.Duration.String()) - } - - if o.LeaderElection.RenewDeadline.Duration.Seconds() == 0 { - o.LeaderElection.RenewDeadline = defaultElectionRenewDeadline - klog.Infof("Set default value: Options.LeaderElection.RenewDeadline = %s", defaultElectionRenewDeadline.Duration.String()) - } - - if o.LeaderElection.RetryPeriod.Duration.Seconds() == 0 { - o.LeaderElection.RetryPeriod = defaultElectionRetryPeriod - klog.Infof("Set default value: Options.LeaderElection.RetryPeriod = %s", defaultElectionRetryPeriod.Duration.String()) - } -} - // AddFlags adds flags to the specified FlagSet. func (o *Options) AddFlags(flags *pflag.FlagSet) { flags.StringVar(&o.BindAddress, "bind-address", defaultBindAddress, diff --git a/cmd/webhook/app/webhook.go b/cmd/webhook/app/webhook.go index 2afe62f46..3e4664be5 100644 --- a/cmd/webhook/app/webhook.go +++ b/cmd/webhook/app/webhook.go @@ -8,7 +8,6 @@ import ( "os" "github.com/spf13/cobra" - "k8s.io/component-base/logs" "k8s.io/klog/v2" controllerruntime "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -31,7 +30,6 @@ func NewWebhookCommand(ctx context.Context) *cobra.Command { Use: "webhook", Long: `Start a webhook server`, Run: func(cmd *cobra.Command, args []string) { - opts.Complete() if err := Run(ctx, opts); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) @@ -47,20 +45,16 @@ func NewWebhookCommand(ctx context.Context) *cobra.Command { // Run runs the webhook server with options. This should never exit. func Run(ctx context.Context, opts *options.Options) error { - logs.InitLogs() - defer logs.FlushLogs() - config, err := controllerruntime.GetConfig() if err != nil { panic(err) } hookManager, err := controllerruntime.NewManager(config, controllerruntime.Options{ - Scheme: gclient.NewSchema(), - Host: opts.BindAddress, - Port: opts.SecurePort, - CertDir: opts.CertDir, - LeaderElection: false, - LeaderElectionID: "webhook.karmada.io", + Scheme: gclient.NewSchema(), + Host: opts.BindAddress, + Port: opts.SecurePort, + CertDir: opts.CertDir, + LeaderElection: false, }) if err != nil { klog.Errorf("failed to build webhook server: %v", err) diff --git a/pkg/util/constants.go b/pkg/util/constants.go index 258ef554e..672c42cd3 100644 --- a/pkg/util/constants.go +++ b/pkg/util/constants.go @@ -96,3 +96,8 @@ const ( // PropagationInstructionSuppressed indicates that the resource should not be propagated. PropagationInstructionSuppressed = "suppressed" ) + +const ( + // NamespaceKarmadaSystem is the karmada system namespace. + NamespaceKarmadaSystem = "karmada-system" +)