diff --git a/README.md b/README.md index 4894bdb69a..42163d8a49 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ See the [storage capacity section](#capacity-support) below for details. * `--node-deployment-max-delay`: Determines how long the external-provisioner sleeps at most before trying to own a PVC with immediate binding. Defaults to 60 seconds. +* `--local-topology`: Instead of watching Node and CSINode objects, use only the topology provided by the CSI driver. Only valid in combination with `--node-deployment`. Disabled by default, but recommended for drivers which have a single topology key with different values for each node (i.e. local volumes). + #### Other recognized arguments * `--feature-gates `: A set of comma separated `=` pairs that describe feature gates for alpha/experimental features. See [list of features](#feature-status) or `--help` output for list of recognized features. Example: `--feature-gates Topology=true` to enable Topology feature that's disabled by default. @@ -262,6 +264,8 @@ each CSI driver on different nodes. The CSI driver deployment must: to match the expected cluster size and desired response times (only relevant when there are storage classes with immediate binding, see below for details) +- use `--local-topology` if volumes are only accessible inside the node + where they get provisioned - set the `NODE_NAME` environment variable to the name of the Kubernetes node - implement `GetCapacity` @@ -294,11 +298,10 @@ can own it. The `--node-deployment-base-delay` parameter determines the initial wait period. It also sets the jitter, so in practice the delay will be -in the range from zero to the base delay. After a collision, the delay -increases exponentially. If the value is high, volumes with immediate -binding get created more slowly. If it is low, then the risk of -conflicts while setting the "selected node" annotation increases and -the apiserver load will be higher. +in the range from zero to the base delay. If the value is high, +volumes with immediate binding get created more slowly. If it is low, +then the risk of conflicts while setting the "selected node" +annotation increases and the apiserver load will be higher. There is an exponential backoff per PVC which is used for unexpected problems. Normally, an owner for a PVC is chosen during the first diff --git a/cmd/csi-provisioner/csi-provisioner.go b/cmd/csi-provisioner/csi-provisioner.go index 73936d872f..49507f2527 100644 --- a/cmd/csi-provisioner/csi-provisioner.go +++ b/cmd/csi-provisioner/csi-provisioner.go @@ -309,6 +309,7 @@ func main() { controller.Threadiness(int(*workerThreads)), controller.CreateProvisionedPVLimiter(workqueue.DefaultControllerRateLimiter()), controller.ClaimsInformer(claimInformer), + controller.NodesLister(nodeLister), } translator := csitrans.New() diff --git a/go.mod b/go.mod index 0882022877..d85d40b68f 100644 --- a/go.mod +++ b/go.mod @@ -71,3 +71,6 @@ replace k8s.io/component-base => k8s.io/component-base v0.19.0 replace k8s.io/controller-manager => k8s.io/controller-manager v0.19.0 replace k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.19.3 + +// node-informer branch = https://github.com/kubernetes-sigs/sig-storage-lib-external-provisioner/pull/100 +replace sigs.k8s.io/sig-storage-lib-external-provisioner/v6 => github.com/pohly/sig-storage-lib-external-provisioner/v6 v6.0.0-20201203095743-057b3397dbc4 diff --git a/go.sum b/go.sum index 62daf55612..0ebef6664a 100644 --- a/go.sum +++ b/go.sum @@ -462,6 +462,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pohly/sig-storage-lib-external-provisioner/v6 v6.0.0-20201203095743-057b3397dbc4 h1:mh0dACPt4diFllwfL/NFPAeutj2wTYWEiDXsOqNG4v0= +github.com/pohly/sig-storage-lib-external-provisioner/v6 v6.0.0-20201203095743-057b3397dbc4/go.mod h1:DhZ52sQMJHW21+JXyA2LRUPRIxKnrNrwh+QFV+2tVA4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -917,8 +919,6 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQb sigs.k8s.io/controller-runtime v0.6.2 h1:jkAnfdTYBpFwlmBn3pS5HFO06SfxvnTZ1p5PeEF/zAA= sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.1.0 h1:4kyxBJ/3fzLooWOZkx5NEO/pUN6woM9JBnHuyWzqkc8= -sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.1.0/go.mod h1:DhZ52sQMJHW21+JXyA2LRUPRIxKnrNrwh+QFV+2tVA4= sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= diff --git a/vendor/modules.txt b/vendor/modules.txt index 2fa6f45128..68e98233d1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -561,7 +561,7 @@ sigs.k8s.io/controller-runtime/pkg/client sigs.k8s.io/controller-runtime/pkg/client/apiutil sigs.k8s.io/controller-runtime/pkg/client/fake sigs.k8s.io/controller-runtime/pkg/internal/objectutil -# sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.1.0 +# sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.1.0 => github.com/pohly/sig-storage-lib-external-provisioner/v6 v6.0.0-20201203095743-057b3397dbc4 ## explicit sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller/metrics @@ -595,3 +595,4 @@ sigs.k8s.io/yaml # k8s.io/component-base => k8s.io/component-base v0.19.0 # k8s.io/controller-manager => k8s.io/controller-manager v0.19.0 # k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.19.3 +# sigs.k8s.io/sig-storage-lib-external-provisioner/v6 => github.com/pohly/sig-storage-lib-external-provisioner/v6 v6.0.0-20201203095743-057b3397dbc4 diff --git a/vendor/sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller/controller.go b/vendor/sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller/controller.go index 7182edc0bd..f687302915 100644 --- a/vendor/sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller/controller.go +++ b/vendor/sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller/controller.go @@ -45,6 +45,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" + corelistersv1 "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/leaderelection" "k8s.io/client-go/tools/leaderelection/resourcelock" @@ -130,6 +131,7 @@ type ProvisionController struct { volumeInformer cache.SharedInformer volumes cache.Store classInformer cache.SharedInformer + nodeLister corelistersv1.NodeLister classes cache.Store // To determine if the informer is internal or external @@ -498,6 +500,22 @@ func ClassesInformer(informer cache.SharedInformer) func(*ProvisionController) e } } +// NodesLister sets the informer to use for accessing Nodes. +// This is needed only for PVCs which have a selected node. +// Defaults to using a GET instead of an informer. +// +// Which approach is better depends on factors like cluster size and +// ratio of PVCs with a selected node. +func NodesLister(nodeLister corelistersv1.NodeLister) func(*ProvisionController) error { + return func(c *ProvisionController) error { + if c.HasRun() { + return errRuntime + } + c.nodeLister = nodeLister + return nil + } +} + // MetricsInstance defines which metrics collection to update. Default: metrics.Metrics. func MetricsInstance(m metrics.Metrics) func(*ProvisionController) error { return func(c *ProvisionController) error { @@ -1361,7 +1379,11 @@ func (ctrl *ProvisionController) provisionClaimOperation(ctx context.Context, cl if ctrl.kubeVersion.AtLeast(utilversion.MustParseSemantic("v1.11.0")) { // Get SelectedNode if nodeName, ok := getString(claim.Annotations, annSelectedNode, annAlphaSelectedNode); ok { - selectedNode, err = ctrl.client.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) // TODO (verult) cache Nodes + if ctrl.nodeLister != nil { + selectedNode, err = ctrl.nodeLister.Get(nodeName) + } else { + selectedNode, err = ctrl.client.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) // TODO (verult) cache Nodes + } if err != nil { err = fmt.Errorf("failed to get target node: %v", err) ctrl.eventRecorder.Event(claim, v1.EventTypeWarning, "ProvisioningFailed", err.Error())