Skip to content

Commit f338883

Browse files
authored
Merge pull request #261 from andrewsykim/leader-election
Use leader election library from csi-lib-utils
2 parents 5f88ece + 736e67e commit f338883

File tree

13 files changed

+342
-19
lines changed

13 files changed

+342
-19
lines changed

Gopkg.lock

Lines changed: 11 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@
3434
name = "sigs.k8s.io/sig-storage-lib-external-provisioner"
3535
version = ">=v3.0.0-beta"
3636

37-
# TODO: remove when official 0.4.0 tagged
38-
[[constraint]]
39-
name = "github.com/kubernetes-csi/csi-lib-utils"
40-
version = ">=0.4.0-rc1"
41-
4237
# TODO: remove when released
4338
[[constraint]]
4439
name = "github.com/kubernetes-csi/external-snapshotter"
@@ -57,6 +52,14 @@
5752
name = "k8s.io/component-base"
5853
version = "kubernetes-1.14.0"
5954

55+
[[constraint]]
56+
name = "k8s.io/client-go"
57+
version = "kubernetes-1.14.0"
58+
59+
[[constraint]]
60+
name = "github.com/kubernetes-csi/csi-lib-utils"
61+
version = ">=0.6.1"
62+
6063
[prune]
6164
non-go = true
6265
go-tests = true

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Note that the external-provisioner does not scale with more replicas. Only one e
4949

5050
* `--enable-leader-election`: Enables leader election. This is mandatory when there are multiple replicas of the same external-provisioner running for one CSI driver. Only one of them may be active (=leader). A new leader will be re-elected when current leader dies or becomes unresponsive for ~15 seconds.
5151

52+
* `--leader-election-type`: The resource type to use for leader election, options are 'endpoints' (default) or 'leases' (recommended)
53+
5254
* `--timeout <duration>`: Timeout of all calls to CSI driver. It should be set to value that accommodates majority of `ControllerCreateVolume` and `ControllerDeleteVolume` calls. See [CSI error and timeout handling](#csi-error-and-timeout-handling) for details. 15 seconds is used by default.
5355

5456
* `--retry-interval-start <duration>` - Initial retry interval of failed provisioning or deletion. It doubles with each failure, up to `--retry-interval-max` and then it stops increasing. Default value is 1 second. See [CSI error and timeout handling](#csi-error-and-timeout-handling) for details.

cmd/csi-provisioner/csi-provisioner.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"context"
2021
goflag "flag"
2122
"fmt"
2223
"math/rand"
@@ -28,6 +29,7 @@ import (
2829
flag "github.com/spf13/pflag"
2930

3031
"github.com/kubernetes-csi/csi-lib-utils/deprecatedflags"
32+
"github.com/kubernetes-csi/csi-lib-utils/leaderelection"
3133
ctrl "github.com/kubernetes-csi/external-provisioner/pkg/controller"
3234
snapclientset "github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned"
3335
"sigs.k8s.io/sig-storage-lib-external-provisioner/controller"
@@ -52,19 +54,25 @@ var (
5254
volumeNamePrefix = flag.String("volume-name-prefix", "pvc", "Prefix to apply to the name of a created volume.")
5355
volumeNameUUIDLength = flag.Int("volume-name-uuid-length", -1, "Truncates generated UUID of a created volume to this length. Defaults behavior is to NOT truncate.")
5456
showVersion = flag.Bool("version", false, "Show version.")
55-
enableLeaderElection = flag.Bool("enable-leader-election", false, "Enables leader election. If leader election is enabled, additional RBAC rules are required. Please refer to the Kubernetes CSI documentation for instructions on setting up these RBAC rules.")
5657
retryIntervalStart = flag.Duration("retry-interval-start", time.Second, "Initial retry interval of failed provisioning or deletion. It doubles with each failure, up to retry-interval-max.")
5758
retryIntervalMax = flag.Duration("retry-interval-max", 5*time.Minute, "Maximum retry interval of failed provisioning or deletion.")
5859
workerThreads = flag.Uint("worker-threads", 100, "Number of provisioner worker threads, in other words nr. of simultaneous CSI calls.")
5960
operationTimeout = flag.Duration("timeout", 10*time.Second, "Timeout for waiting for creation or deletion of a volume")
6061
_ = deprecatedflags.Add("provisioner")
6162

63+
enableLeaderElection = flag.Bool("enable-leader-election", false, "Enables leader election. If leader election is enabled, additional RBAC rules are required. Please refer to the Kubernetes CSI documentation for instructions on setting up these RBAC rules.")
64+
leaderElectionType = flag.String("leader-election-type", "endpoints", "the type of leader election, options are 'endpoints' (default) or 'leases' (strongly recommended). The 'endpoints' option is deprecated in favor of 'leases'.")
65+
6266
featureGates map[string]bool
6367
provisionController *controller.ProvisionController
6468
version = "unknown"
6569
)
6670

67-
func init() {
71+
type leaderElection interface {
72+
Run() error
73+
}
74+
75+
func main() {
6876
var config *rest.Config
6977
var err error
7078

@@ -178,8 +186,32 @@ func init() {
178186
serverVersion.GitVersion,
179187
provisionerOptions...,
180188
)
181-
}
182189

183-
func main() {
184-
provisionController.Run(wait.NeverStop)
190+
run := func(context.Context) {
191+
provisionController.Run(wait.NeverStop)
192+
}
193+
194+
if !*enableLeaderElection {
195+
run(context.TODO())
196+
} else {
197+
// this lock name pattern is also copied from sigs.k8s.io/sig-storage-lib-external-provisioner/controller
198+
// to preserve backwards compatibility
199+
lockName := strings.Replace(provisionerName, "/", "-", -1)
200+
201+
var le leaderElection
202+
if *leaderElectionType == "endpoints" {
203+
klog.Warning("The 'endpoints' leader election type is deprecated and will be removed in a future release. Use '--leader-election-type=leases' instead.")
204+
le = leaderelection.NewLeaderElectionWithEndpoints(clientset, lockName, run)
205+
} else if *leaderElectionType == "leases" {
206+
le = leaderelection.NewLeaderElection(clientset, lockName, run)
207+
} else {
208+
klog.Error("--leader-election-type must be either 'endpoints' or 'lease'")
209+
os.Exit(1)
210+
}
211+
212+
if err := le.Run(); err != nil {
213+
klog.Fatalf("failed to initialize leader election: %v", err)
214+
}
215+
}
216+
185217
}

deploy/kubernetes/rbac.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,14 @@ metadata:
7676
namespace: default
7777
name: external-provisioner-cfg
7878
rules:
79+
# Only one of the following rules for endpoints or leases is required based on
80+
# what is set for `--leader-election-type`. Endpoints are deprecated in favor of Leases.
7981
- apiGroups: [""]
8082
resources: ["endpoints"]
8183
verbs: ["get", "watch", "list", "delete", "update", "create"]
84+
- apiGroups: ["coordination.k8s.io"]
85+
resources: ["leases"]
86+
verbs: ["get", "watch", "list", "delete", "update", "create"]
8287

8388
---
8489
kind: RoleBinding

0 commit comments

Comments
 (0)