Added PersistentVolumeController
This commit is contained in:
@@ -137,6 +137,7 @@ func NewCMServer() *CMServer {
|
||||
PersistentVolumeRecyclerIncrementTimeoutNFS: 30,
|
||||
PersistentVolumeRecyclerMinimumTimeoutHostPath: 60,
|
||||
PersistentVolumeRecyclerIncrementTimeoutHostPath: 30,
|
||||
EnableHostPathProvisioning: false,
|
||||
},
|
||||
KubeAPIQPS: 20.0,
|
||||
KubeAPIBurst: 30,
|
||||
@@ -176,6 +177,7 @@ type VolumeConfigFlags struct {
|
||||
PersistentVolumeRecyclerPodTemplateFilePathHostPath string
|
||||
PersistentVolumeRecyclerMinimumTimeoutHostPath int
|
||||
PersistentVolumeRecyclerIncrementTimeoutHostPath int
|
||||
EnableHostPathProvisioning bool
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific CMServer to the specified FlagSet
|
||||
@@ -201,6 +203,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.VolumeConfigFlags.PersistentVolumeRecyclerPodTemplateFilePathHostPath, "pv-recycler-pod-template-filepath-hostpath", s.VolumeConfigFlags.PersistentVolumeRecyclerPodTemplateFilePathHostPath, "The file path to a pod definition used as a template for HostPath persistent volume recycling. This is for development and testing only and will not work in a multi-node cluster.")
|
||||
fs.IntVar(&s.VolumeConfigFlags.PersistentVolumeRecyclerMinimumTimeoutHostPath, "pv-recycler-minimum-timeout-hostpath", s.VolumeConfigFlags.PersistentVolumeRecyclerMinimumTimeoutHostPath, "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.IntVar(&s.VolumeConfigFlags.PersistentVolumeRecyclerIncrementTimeoutHostPath, "pv-recycler-timeout-increment-hostpath", s.VolumeConfigFlags.PersistentVolumeRecyclerIncrementTimeoutHostPath, "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.VolumeConfigFlags.EnableHostPathProvisioning, "enable-hostpath-provisioner", s.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.IntVar(&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, "horizontal-pod-autoscaler-sync-period", s.HorizontalPodAutoscalerSyncPeriod, "The period for syncing the number of pods in horizontal pod autoscaler.")
|
||||
fs.DurationVar(&s.DeploymentControllerSyncPeriod, "deployment-controller-sync-period", s.DeploymentControllerSyncPeriod, "Period for syncing the deployments.")
|
||||
@@ -385,15 +388,29 @@ func (s *CMServer) Run(_ []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
volumePlugins := ProbeRecyclableVolumePlugins(s.VolumeConfigFlags)
|
||||
provisioner, err := NewVolumeProvisioner(cloud, s.VolumeConfigFlags)
|
||||
if err != nil {
|
||||
glog.Fatal("A Provisioner could not be created, but one was expected. Provisioning will not work. This functionality is considered an early Alpha version.")
|
||||
}
|
||||
|
||||
pvclaimBinder := persistentvolumecontroller.NewPersistentVolumeClaimBinder(clientForUserAgentOrDie(*kubeconfig, "persistent-volume-binder"), s.PVClaimBinderSyncPeriod)
|
||||
pvclaimBinder.Run()
|
||||
|
||||
pvRecycler, err := persistentvolumecontroller.NewPersistentVolumeRecycler(clientForUserAgentOrDie(*kubeconfig, "persistent-volume-recycler"), s.PVClaimBinderSyncPeriod, ProbeRecyclableVolumePlugins(s.VolumeConfigFlags))
|
||||
pvRecycler, err := persistentvolumecontroller.NewPersistentVolumeRecycler(clientForUserAgentOrDie(*kubeconfig, "persistent-volume-recycler"), s.PVClaimBinderSyncPeriod, ProbeRecyclableVolumePlugins(s.VolumeConfigFlags), cloud)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to start persistent volume recycler: %+v", err)
|
||||
}
|
||||
pvRecycler.Run()
|
||||
|
||||
if provisioner != nil {
|
||||
pvController, err := persistentvolumecontroller.NewPersistentVolumeProvisionerController(persistentvolumecontroller.NewControllerClient(clientForUserAgentOrDie(*kubeconfig, "persistent-volume-provisioner")), s.PVClaimBinderSyncPeriod, volumePlugins, provisioner, cloud)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to start persistent volume provisioner controller: %+v", err)
|
||||
}
|
||||
pvController.Run()
|
||||
}
|
||||
|
||||
var rootCA []byte
|
||||
|
||||
if s.RootCAFile != "" {
|
||||
|
@@ -21,12 +21,18 @@ import (
|
||||
// This should probably be part of some configuration fed into the build for a
|
||||
// given binary target.
|
||||
|
||||
"fmt"
|
||||
|
||||
//Cloud providers
|
||||
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
|
||||
|
||||
// Volume plugins
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/util/io"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/aws_ebs"
|
||||
"k8s.io/kubernetes/pkg/volume/cinder"
|
||||
"k8s.io/kubernetes/pkg/volume/gce_pd"
|
||||
"k8s.io/kubernetes/pkg/volume/host_path"
|
||||
"k8s.io/kubernetes/pkg/volume/nfs"
|
||||
|
||||
@@ -51,7 +57,7 @@ func ProbeRecyclableVolumePlugins(flags VolumeConfigFlags) []volume.VolumePlugin
|
||||
RecyclerTimeoutIncrement: flags.PersistentVolumeRecyclerIncrementTimeoutHostPath,
|
||||
RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(),
|
||||
}
|
||||
if err := attemptToLoadRecycler(flags.PersistentVolumeRecyclerPodTemplateFilePathHostPath, &hostPathConfig); err != nil {
|
||||
if err := AttemptToLoadRecycler(flags.PersistentVolumeRecyclerPodTemplateFilePathHostPath, &hostPathConfig); err != nil {
|
||||
glog.Fatalf("Could not create hostpath recycler pod from file %s: %+v", flags.PersistentVolumeRecyclerPodTemplateFilePathHostPath, err)
|
||||
}
|
||||
allPlugins = append(allPlugins, host_path.ProbeVolumePlugins(hostPathConfig)...)
|
||||
@@ -61,18 +67,49 @@ func ProbeRecyclableVolumePlugins(flags VolumeConfigFlags) []volume.VolumePlugin
|
||||
RecyclerTimeoutIncrement: flags.PersistentVolumeRecyclerIncrementTimeoutNFS,
|
||||
RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(),
|
||||
}
|
||||
if err := attemptToLoadRecycler(flags.PersistentVolumeRecyclerPodTemplateFilePathNFS, &nfsConfig); err != nil {
|
||||
if err := AttemptToLoadRecycler(flags.PersistentVolumeRecyclerPodTemplateFilePathNFS, &nfsConfig); err != nil {
|
||||
glog.Fatalf("Could not create NFS recycler pod from file %s: %+v", flags.PersistentVolumeRecyclerPodTemplateFilePathNFS, err)
|
||||
}
|
||||
allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...)
|
||||
|
||||
allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...)
|
||||
allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...)
|
||||
|
||||
return allPlugins
|
||||
}
|
||||
|
||||
// attemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume.
|
||||
// NewVolumeProvisioner returns a volume provisioner to use when running in a cloud or development environment.
|
||||
// The beta implementation of provisioning allows 1 implied provisioner per cloud, until we allow configuration of many.
|
||||
// We explicitly map clouds to volume plugins here which allows us to configure many later without backwards compatibility issues.
|
||||
// Not all cloudproviders have provisioning capability, which is the reason for the bool in the return to tell the caller to expect one or not.
|
||||
func NewVolumeProvisioner(cloud cloudprovider.Interface, flags VolumeConfigFlags) (volume.ProvisionableVolumePlugin, error) {
|
||||
switch {
|
||||
case cloud == nil && flags.EnableHostPathProvisioning:
|
||||
return getProvisionablePluginFromVolumePlugins(host_path.ProbeVolumePlugins(volume.VolumeConfig{}))
|
||||
// case cloud != nil && aws.ProviderName == cloud.ProviderName():
|
||||
// return getProvisionablePluginFromVolumePlugins(aws_ebs.ProbeVolumePlugins())
|
||||
// case cloud != nil && gce.ProviderName == cloud.ProviderName():
|
||||
// return getProvisionablePluginFromVolumePlugins(gce_pd.ProbeVolumePlugins())
|
||||
// case cloud != nil && openstack.ProviderName == cloud.ProviderName():
|
||||
// return getProvisionablePluginFromVolumePlugins(cinder.ProbeVolumePlugins())
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getProvisionablePluginFromVolumePlugins(plugins []volume.VolumePlugin) (volume.ProvisionableVolumePlugin, error) {
|
||||
for _, plugin := range plugins {
|
||||
if provisonablePlugin, ok := plugin.(volume.ProvisionableVolumePlugin); ok {
|
||||
return provisonablePlugin, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("ProvisionablePlugin expected but not found in %#v: ", plugins)
|
||||
}
|
||||
|
||||
// AttemptToLoadRecycler tries decoding a pod from a filepath for use as a recycler for a volume.
|
||||
// If successful, this method will set the recycler on the config.
|
||||
// If unsucessful, an error is returned.
|
||||
func attemptToLoadRecycler(path string, config *volume.VolumeConfig) error {
|
||||
// If unsuccessful, an error is returned. Function is exported for reuse downstream.
|
||||
func AttemptToLoadRecycler(path string, config *volume.VolumeConfig) error {
|
||||
if path != "" {
|
||||
recyclerPod, err := io.LoadPodFromFile(path)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user