From a1401143fbe93b5ef3a6c23a3ebceed1e4ece464 Mon Sep 17 00:00:00 2001 From: Yury Kulazhenkov Date: Tue, 9 May 2023 13:39:55 +0300 Subject: [PATCH] Add support for leader election By default, the leader election is enabled in the deployment yaml, but controller's replica count is set to 1. This is to prevent IPAM controller misbehaviour in case if user will decide to scale deployment. Signed-off-by: Yury Kulazhenkov --- cmd/ipam-controller/app/app.go | 1 + cmd/ipam-controller/app/options/options.go | 27 +++++++++++-------- deploy/nv-ipam.yaml | 30 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/cmd/ipam-controller/app/app.go b/cmd/ipam-controller/app/app.go index 8f0fa66..b659627 100644 --- a/cmd/ipam-controller/app/app.go +++ b/cmd/ipam-controller/app/app.go @@ -121,6 +121,7 @@ func RunController(ctx context.Context, config *rest.Config, opts *options.Optio Port: 9443, HealthProbeBindAddress: opts.ProbeAddr, LeaderElection: opts.EnableLeaderElection, + LeaderElectionNamespace: opts.LeaderElectionNamespace, LeaderElectionID: "dd1643cf.nvidia.com", LeaderElectionReleaseOnCancel: true, }) diff --git a/cmd/ipam-controller/app/options/options.go b/cmd/ipam-controller/app/options/options.go index 9875b71..1e323a0 100644 --- a/cmd/ipam-controller/app/options/options.go +++ b/cmd/ipam-controller/app/options/options.go @@ -25,23 +25,25 @@ import ( // New initialize and return new Options object func New() *Options { return &Options{ - Options: *cmdoptions.New(), - MetricsAddr: ":8080", - ProbeAddr: ":8081", - EnableLeaderElection: false, - ConfigMapName: "nvidia-k8s-ipam-config", - ConfigMapNamespace: "kube-system", + Options: *cmdoptions.New(), + MetricsAddr: ":8080", + ProbeAddr: ":8081", + EnableLeaderElection: false, + LeaderElectionNamespace: "kube-system", + ConfigMapName: "nvidia-k8s-ipam-config", + ConfigMapNamespace: "kube-system", } } // Options holds command line options for controller type Options struct { cmdoptions.Options - MetricsAddr string - ProbeAddr string - EnableLeaderElection bool - ConfigMapName string - ConfigMapNamespace string + MetricsAddr string + ProbeAddr string + EnableLeaderElection bool + LeaderElectionNamespace string + ConfigMapName string + ConfigMapNamespace string } // AddNamedFlagSets register flags for common options in NamedFlagSets @@ -61,6 +63,9 @@ func (o *Options) AddNamedFlagSets(sharedFS *cliflag.NamedFlagSets) { controllerFS.BoolVar(&o.EnableLeaderElection, "leader-elect", o.EnableLeaderElection, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") + controllerFS.StringVar(&o.LeaderElectionNamespace, "leader-elect-namespace", o.LeaderElectionNamespace, + "Determines the namespace in which the leader "+ + "election resource will be created.") controllerFS.StringVar(&o.ConfigMapName, "config-name", o.ConfigMapName, "The name of the ConfigMap which holds controller configuration") controllerFS.StringVar(&o.ConfigMapNamespace, "config-namespace", diff --git a/deploy/nv-ipam.yaml b/deploy/nv-ipam.yaml index 7378244..b6a8373 100644 --- a/deploy/nv-ipam.yaml +++ b/deploy/nv-ipam.yaml @@ -132,6 +132,25 @@ rules: - get - list - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -175,6 +194,15 @@ spec: priorityClassName: system-cluster-critical serviceAccountName: nv-ipam-controller affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: name + operator: In + values: + - nv-ipam-controller + topologyKey: "kubernetes.io/hostname" nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 @@ -209,6 +237,8 @@ spec: args: - --config-name=nvidia-k8s-ipam-config - --config-namespace=$(POD_NAMESPACE) + - --leader-elect=true + - --leader-elect-namespace=$(POD_NAMESPACE) env: - name: POD_NAMESPACE valueFrom: