Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow disabling of dynamic provisioning #27128

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/kube-controller-manager/app/controllermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig
cloud,
s.ClusterName,
nil, nil, nil,
s.VolumeConfiguration.EnableDynamicProvisioning,
)
volumeController.Run()
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
Expand Down
2 changes: 2 additions & 0 deletions cmd/kube-controller-manager/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func NewCMServer() *CMServer {
TerminatedPodGCThreshold: 12500,
VolumeConfiguration: componentconfig.VolumeConfiguration{
EnableHostPathProvisioning: false,
EnableDynamicProvisioning: true,
PersistentVolumeRecyclerConfiguration: componentconfig.PersistentVolumeRecyclerConfiguration{
MaximumRetry: 3,
MinimumTimeoutNFS: 300,
Expand Down Expand Up @@ -125,6 +126,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath, "pv-recycler-minimum-timeout-hostpath", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath, "The minimum ActiveDeadlineSeconds to use for a HostPath Recycler pod. This is for development and testing only and will not work in a multi-node cluster.")
fs.Int32Var(&s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath, "pv-recycler-timeout-increment-hostpath", s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath, "the increment of time added per Gi to ActiveDeadlineSeconds for a HostPath scrubber pod. This is for development and testing only and will not work in a multi-node cluster.")
fs.BoolVar(&s.VolumeConfiguration.EnableHostPathProvisioning, "enable-hostpath-provisioner", s.VolumeConfiguration.EnableHostPathProvisioning, "Enable HostPath PV provisioning when running without a cloud provider. This allows testing and development of provisioning features. HostPath provisioning is not supported in any way, won't work in a multi-node cluster, and should not be used for anything other than testing or development.")
fs.BoolVar(&s.VolumeConfiguration.EnableDynamicProvisioning, "enable-dynamic-provisioning", s.VolumeConfiguration.EnableDynamicProvisioning, "Enable dynamic provisioning for environments that support it.")
fs.StringVar(&s.VolumeConfiguration.FlexVolumePluginDir, "flex-volume-plugin-dir", s.VolumeConfiguration.FlexVolumePluginDir, "Full path of the directory in which the flex volume plugin should search for additional third party volume plugins.")
fs.Int32Var(&s.TerminatedPodGCThreshold, "terminated-pod-gc-threshold", s.TerminatedPodGCThreshold, "Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled.")
fs.DurationVar(&s.HorizontalPodAutoscalerSyncPeriod.Duration, "horizontal-pod-autoscaler-sync-period", s.HorizontalPodAutoscalerSyncPeriod.Duration, "The period for syncing the number of pods in horizontal pod autoscaler.")
Expand Down
1 change: 1 addition & 0 deletions contrib/mesos/pkg/controllermanager/controllermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ func (s *CMServer) Run(_ []string) error {
nil,
nil,
nil,
s.VolumeConfiguration.EnableDynamicProvisioning,
)
volumeController.Run()

Expand Down
1 change: 1 addition & 0 deletions hack/verify-flags/known-flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ enable-controller-attach-detach
enable-custom-metrics
enable-debugging-handlers
enable-garbage-collector
enable-dynamic-provisioning
enable-hostpath-provisioner
enable-server
enable-swagger-ui
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/componentconfig/deep_copy_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ func DeepCopy_componentconfig_PortRangeVar(in PortRangeVar, out *PortRangeVar, c

func DeepCopy_componentconfig_VolumeConfiguration(in VolumeConfiguration, out *VolumeConfiguration, c *conversion.Cloner) error {
out.EnableHostPathProvisioning = in.EnableHostPathProvisioning
out.EnableDynamicProvisioning = in.EnableDynamicProvisioning
if err := DeepCopy_componentconfig_PersistentVolumeRecyclerConfiguration(in.PersistentVolumeRecyclerConfiguration, &out.PersistentVolumeRecyclerConfiguration, c); err != nil {
return err
}
Expand Down
119 changes: 80 additions & 39 deletions pkg/apis/componentconfig/types.generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -8914,14 +8914,14 @@ func (x *VolumeConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
r.EncodeArrayStart(4)
} else {
yynn2 = 3
yynn2 = 4
for _, b := range yyq2 {
if b {
yynn2++
Expand Down Expand Up @@ -8951,19 +8951,38 @@ func (x *VolumeConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy7 := &x.PersistentVolumeRecyclerConfiguration
yy7.CodecEncodeSelf(e)
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeBool(bool(x.EnableDynamicProvisioning))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("enableDynamicProvisioning"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeBool(bool(x.EnableDynamicProvisioning))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy10 := &x.PersistentVolumeRecyclerConfiguration
yy10.CodecEncodeSelf(e)
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("persitentVolumeRecyclerConfiguration"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy9 := &x.PersistentVolumeRecyclerConfiguration
yy9.CodecEncodeSelf(e)
yy12 := &x.PersistentVolumeRecyclerConfiguration
yy12.CodecEncodeSelf(e)
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym12 := z.EncBinary()
_ = yym12
yym15 := z.EncBinary()
_ = yym15
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.FlexVolumePluginDir))
Expand All @@ -8972,8 +8991,8 @@ func (x *VolumeConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("flexVolumePluginDir"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym13 := z.EncBinary()
_ = yym13
yym16 := z.EncBinary()
_ = yym16
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.FlexVolumePluginDir))
Expand Down Expand Up @@ -9046,12 +9065,18 @@ func (x *VolumeConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decoder
} else {
x.EnableHostPathProvisioning = bool(r.DecodeBool())
}
case "enableDynamicProvisioning":
if r.TryDecodeAsNil() {
x.EnableDynamicProvisioning = false
} else {
x.EnableDynamicProvisioning = bool(r.DecodeBool())
}
case "persitentVolumeRecyclerConfiguration":
if r.TryDecodeAsNil() {
x.PersistentVolumeRecyclerConfiguration = PersistentVolumeRecyclerConfiguration{}
} else {
yyv5 := &x.PersistentVolumeRecyclerConfiguration
yyv5.CodecDecodeSelf(d)
yyv6 := &x.PersistentVolumeRecyclerConfiguration
yyv6.CodecDecodeSelf(d)
}
case "flexVolumePluginDir":
if r.TryDecodeAsNil() {
Expand All @@ -9070,16 +9095,16 @@ func (x *VolumeConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Decod
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj7 int
var yyb7 bool
var yyhl7 bool = l >= 0
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
var yyj8 int
var yyb8 bool
var yyhl8 bool = l >= 0
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
Expand All @@ -9089,30 +9114,46 @@ func (x *VolumeConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Decod
} else {
x.EnableHostPathProvisioning = bool(r.DecodeBool())
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.EnableDynamicProvisioning = false
} else {
x.EnableDynamicProvisioning = bool(r.DecodeBool())
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.PersistentVolumeRecyclerConfiguration = PersistentVolumeRecyclerConfiguration{}
} else {
yyv9 := &x.PersistentVolumeRecyclerConfiguration
yyv9.CodecDecodeSelf(d)
yyv11 := &x.PersistentVolumeRecyclerConfiguration
yyv11.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
Expand All @@ -9123,17 +9164,17 @@ func (x *VolumeConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Decod
x.FlexVolumePluginDir = string(r.DecodeString())
}
for {
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj7-1, "")
z.DecStructFieldNotFound(yyj8-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/componentconfig/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ type VolumeConfiguration struct {
// provisioning is not supported in any way, won't work in a multi-node cluster, and
// should not be used for anything other than testing or development.
EnableHostPathProvisioning bool `json:"enableHostPathProvisioning"`
// enableDynamicProvisioning enables the provisioning of volumes when running within an environment
// that supports dynamic provisioning. Defaults to true.
EnableDynamicProvisioning bool `json:"enableDynamicProvisioning"`
// persistentVolumeRecyclerConfiguration holds configuration for persistent volume plugins.
PersistentVolumeRecyclerConfiguration PersistentVolumeRecyclerConfiguration `json:"persitentVolumeRecyclerConfiguration"`
// volumePluginDir is the full path of the directory in which the flex
Expand Down
30 changes: 17 additions & 13 deletions pkg/controller/persistentvolume/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,19 @@ const createProvisionedPVInterval = 10 * time.Second
// framework.Controllers that watch PersistentVolume and PersistentVolumeClaim
// changes.
type PersistentVolumeController struct {
volumeController *framework.Controller
volumeControllerStopCh chan struct{}
volumeSource cache.ListerWatcher
claimController *framework.Controller
claimControllerStopCh chan struct{}
claimSource cache.ListerWatcher
kubeClient clientset.Interface
eventRecorder record.EventRecorder
cloud cloudprovider.Interface
recyclePluginMgr vol.VolumePluginMgr
provisioner vol.ProvisionableVolumePlugin
clusterName string
volumeController *framework.Controller
volumeControllerStopCh chan struct{}
volumeSource cache.ListerWatcher
claimController *framework.Controller
claimControllerStopCh chan struct{}
claimSource cache.ListerWatcher
kubeClient clientset.Interface
eventRecorder record.EventRecorder
cloud cloudprovider.Interface
recyclePluginMgr vol.VolumePluginMgr
provisioner vol.ProvisionableVolumePlugin
enableDynamicProvisioning bool
clusterName string

// Cache of the last known version of volumes and claims. This cache is
// thread safe as long as the volumes/claims there are not modified, they
Expand Down Expand Up @@ -1060,8 +1061,11 @@ func (ctrl *PersistentVolumeController) doDeleteVolume(volume *api.PersistentVol
return nil
}

// provisionClaim starts new asynchronous operation to provision a claim.
// provisionClaim starts new asynchronous operation to provision a claim if provisioning is enabled.
func (ctrl *PersistentVolumeController) provisionClaim(claim *api.PersistentVolumeClaim) error {
if !ctrl.enableDynamicProvisioning {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be checked at the site that does the provisioning and this method just not invoked if it shouldn't be.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO result would be the same and syncUnboundClaim is complicated enough.

return nil
}
glog.V(4).Infof("provisionClaim[%s]: started", claimToClaimKey(claim))
opName := fmt.Sprintf("provision-%s[%s]", claimToClaimKey(claim), string(claim.UID))
ctrl.scheduleOperation(opName, func() error {
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/persistentvolume/controller_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func NewPersistentVolumeController(
clusterName string,
volumeSource, claimSource cache.ListerWatcher,
eventRecorder record.EventRecorder,
enableDynamicProvisioning bool,
) *PersistentVolumeController {

if eventRecorder == nil {
Expand All @@ -68,6 +69,7 @@ func NewPersistentVolumeController(
runningOperations: goroutinemap.NewGoRoutineMap(),
cloud: cloud,
provisioner: provisioner,
enableDynamicProvisioning: enableDynamicProvisioning,
clusterName: clusterName,
createProvisionedPVRetryCount: createProvisionedPVRetryCount,
createProvisionedPVInterval: createProvisionedPVInterval,
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/persistentvolume/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func TestControllerSync(t *testing.T) {
client := &fake.Clientset{}
volumeSource := framework.NewFakeControllerSource()
claimSource := framework.NewFakeControllerSource()
ctrl := newTestController(client, volumeSource, claimSource)
ctrl := newTestController(client, volumeSource, claimSource, true)
reactor := newVolumeReactor(client, ctrl, volumeSource, claimSource, test.errors)
for _, claim := range test.initialClaims {
claimSource.Add(claim)
Expand Down
7 changes: 4 additions & 3 deletions pkg/controller/persistentvolume/framework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ func newVolumeReactor(client *fake.Clientset, ctrl *PersistentVolumeController,
return reactor
}

func newTestController(kubeClient clientset.Interface, volumeSource, claimSource cache.ListerWatcher) *PersistentVolumeController {
func newTestController(kubeClient clientset.Interface, volumeSource, claimSource cache.ListerWatcher, enableDynamicProvisioning bool) *PersistentVolumeController {
if volumeSource == nil {
volumeSource = framework.NewFakeControllerSource()
}
Expand All @@ -572,6 +572,7 @@ func newTestController(kubeClient clientset.Interface, volumeSource, claimSource
volumeSource,
claimSource,
record.NewFakeRecorder(1000), // event recorder
enableDynamicProvisioning,
)

// Speed up the test
Expand Down Expand Up @@ -822,7 +823,7 @@ func runSyncTests(t *testing.T, tests []controllerTest) {

// Initialize the controller
client := &fake.Clientset{}
ctrl := newTestController(client, nil, nil)
ctrl := newTestController(client, nil, nil, true)
reactor := newVolumeReactor(client, ctrl, nil, nil, test.errors)
for _, claim := range test.initialClaims {
ctrl.claims.Add(claim)
Expand Down Expand Up @@ -866,7 +867,7 @@ func runMultisyncTests(t *testing.T, tests []controllerTest) {

// Initialize the controller
client := &fake.Clientset{}
ctrl := newTestController(client, nil, nil)
ctrl := newTestController(client, nil, nil, true)
reactor := newVolumeReactor(client, ctrl, nil, nil, test.errors)
for _, claim := range test.initialClaims {
ctrl.claims.Add(claim)
Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/persistentvolume/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type VolumeConfigFlags struct {
PersistentVolumeRecyclerMinimumTimeoutHostPath int
PersistentVolumeRecyclerIncrementTimeoutHostPath int
EnableHostPathProvisioning bool
EnableDynamicProvisioning bool
}

type PersistentVolumeControllerOptions struct {
Expand All @@ -53,6 +54,7 @@ func NewPersistentVolumeControllerOptions() PersistentVolumeControllerOptions {
PersistentVolumeRecyclerMinimumTimeoutHostPath: 60,
PersistentVolumeRecyclerIncrementTimeoutHostPath: 30,
EnableHostPathProvisioning: false,
EnableDynamicProvisioning: true,
},
}
}
Expand Down Expand Up @@ -84,4 +86,6 @@ func (o *PersistentVolumeControllerOptions) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&o.VolumeConfigFlags.EnableHostPathProvisioning, "enable-hostpath-provisioner", o.VolumeConfigFlags.EnableHostPathProvisioning,
"Enable HostPath PV provisioning when running without a cloud provider. This allows testing and development of provisioning features. "+
"HostPath provisioning is not supported in any way, won't work in a multi-node cluster, and should not be used for anything other than testing or development.")
fs.BoolVar(&o.VolumeConfigFlags.EnableDynamicProvisioning, "enable-dynamic-provisioning", o.VolumeConfigFlags.EnableDynamicProvisioning,
"Enable dynamic provisioning for environments that support it.")
}