// ProbeControllerVolumePlugins collects all persistent volume plugins into an // easy to use list. Only volume plugins that implement any of // provisioner/recycler/deleter interface should be returned. func ProbeControllerVolumePlugins(cloud cloudprovider.Interface, config componentconfig.VolumeConfiguration) []volume.VolumePlugin { allPlugins := []volume.VolumePlugin{} // The list of plugins to probe is decided by this binary, not // by dynamic linking or other "magic". Plugins will be analyzed and // initialized later. // Each plugin can make use of VolumeConfig. The single arg to this func contains *all* enumerated // options meant to configure volume plugins. From that single config, create an instance of volume.VolumeConfig // for a specific plugin and pass that instance to the plugin's ProbeVolumePlugins(config) func. // HostPath recycling is for testing and development purposes only! hostPathConfig := volume.VolumeConfig{ RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutHostPath), RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutHostPath), RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(), ProvisioningEnabled: config.EnableHostPathProvisioning, } if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, &hostPathConfig); err != nil { glog.Fatalf("Could not create hostpath recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathHostPath, err) } allPlugins = append(allPlugins, host_path.ProbeVolumePlugins(hostPathConfig)...) nfsConfig := volume.VolumeConfig{ RecyclerMinimumTimeout: int(config.PersistentVolumeRecyclerConfiguration.MinimumTimeoutNFS), RecyclerTimeoutIncrement: int(config.PersistentVolumeRecyclerConfiguration.IncrementTimeoutNFS), RecyclerPodTemplate: volume.NewPersistentVolumeRecyclerPodTemplate(), } if err := AttemptToLoadRecycler(config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, &nfsConfig); err != nil { glog.Fatalf("Could not create NFS recycler pod from file %s: %+v", config.PersistentVolumeRecyclerConfiguration.PodTemplateFilePathNFS, err) } allPlugins = append(allPlugins, nfs.ProbeVolumePlugins(nfsConfig)...) allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) // add rbd provisioner allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, quobyte.ProbeVolumePlugins()...) allPlugins = append(allPlugins, flocker.ProbeVolumePlugins()...) if cloud != nil { switch { case aws.ProviderName == cloud.ProviderName(): allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...) case gce.ProviderName == cloud.ProviderName(): allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...) case openstack.ProviderName == cloud.ProviderName(): allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) case vsphere.ProviderName == cloud.ProviderName(): allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) case azure.CloudProviderName == cloud.ProviderName(): allPlugins = append(allPlugins, azure_dd.ProbeVolumePlugins()...) } } return allPlugins }
func nodeExistsInCloudProvider(cloud cloudprovider.Interface, nodeName string) (bool, error) { instances, ok := cloud.Instances() if !ok { return false, fmt.Errorf("%v", ErrCloudInstance) } if _, err := instances.ExternalID(nodeName); err != nil { if err == cloudprovider.InstanceNotFound { return false, nil } return false, err } return true, nil }
// 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 }
// getNodeName returns the node name according to the cloud provider // if cloud provider is specified. Otherwise, returns the hostname of the node. func getNodeName(cloud cloudprovider.Interface, hostname string) (types.NodeName, error) { if cloud == nil { return types.NodeName(hostname), nil } instances, ok := cloud.Instances() if !ok { return "", fmt.Errorf("failed to get instances from cloud provider") } nodeName, err := instances.CurrentNodeName(hostname) if err != nil { return "", fmt.Errorf("error fetching current node name from cloud provider: %v", err) } glog.V(2).Infof("cloud provider determined current node name to be %s", nodeName) return nodeName, nil }
// NewAlphaVolumeProvisioner returns a volume provisioner to use when running in // a cloud or development environment. The alpha implementation of provisioning // allows 1 implied provisioner per cloud and is here only for compatibility // with Kubernetes 1.3 // TODO: remove in Kubernetes 1.5 func NewAlphaVolumeProvisioner(cloud cloudprovider.Interface, config componentconfig.VolumeConfiguration) (volume.ProvisionableVolumePlugin, error) { switch { case !utilconfig.DefaultFeatureGate.DynamicVolumeProvisioning(): return nil, nil case cloud == nil && config.EnableHostPathProvisioning: return getProvisionablePluginFromVolumePlugins(host_path.ProbeVolumePlugins( volume.VolumeConfig{ ProvisioningEnabled: true, })) 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()) case cloud != nil && vsphere.ProviderName == cloud.ProviderName(): return getProvisionablePluginFromVolumePlugins(vsphere_volume.ProbeVolumePlugins()) case cloud != nil && azure.CloudProviderName == cloud.ProviderName(): return getProvisionablePluginFromVolumePlugins(azure_dd.ProbeVolumePlugins()) } return nil, nil }
// 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, config componentconfig.VolumeConfiguration) (volume.ProvisionableVolumePlugin, error) { switch { case cloud == nil && config.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()) case cloud != nil && vsphere.ProviderName == cloud.ProviderName(): return getProvisionablePluginFromVolumePlugins(vsphere_volume.ProbeVolumePlugins()) } return nil, nil }
// StartControllers starts the cloud specific controller loops. func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restclient.Config, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}, recorder record.EventRecorder, cloud cloudprovider.Interface) error { // Function to build the kube client object client := func(serviceAccountName string) clientset.Interface { return rootClientBuilder.ClientOrDie(serviceAccountName) } sharedInformers := informers.NewSharedInformerFactory(client("shared-informers"), nil, resyncPeriod(s)()) _, clusterCIDR, err := net.ParseCIDR(s.ClusterCIDR) if err != nil { glog.Warningf("Unsuccessful parsing of cluster CIDR %v: %v", s.ClusterCIDR, err) } // Start the CloudNodeController nodeController, err := nodecontroller.NewCloudNodeController( sharedInformers.Nodes(), client("cloud-node-controller"), cloud, s.NodeMonitorPeriod.Duration) if err != nil { glog.Fatalf("Failed to initialize nodecontroller: %v", err) } nodeController.Run() time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) // Start the service controller serviceController, err := servicecontroller.New(cloud, client("service-controller"), s.ClusterName) if err != nil { glog.Errorf("Failed to start service controller: %v", err) } else { serviceController.Run(int(s.ConcurrentServiceSyncs)) } time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) // If CIDRs should be allocated for pods and set on the CloudProvider, then start the route controller if s.AllocateNodeCIDRs && s.ConfigureCloudRoutes { if routes, ok := cloud.Routes(); !ok { glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.") } else { routeController := routecontroller.New(routes, client("route-controller"), s.ClusterName, clusterCIDR) routeController.Run(s.RouteReconciliationPeriod.Duration) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) } } else { glog.Infof("Will not configure cloud provider routes for allocate-node-cidrs: %v, configure-cloud-routes: %v.", s.AllocateNodeCIDRs, s.ConfigureCloudRoutes) } // If apiserver is not running we should wait for some time and fail only then. This is particularly // important when we start apiserver and controller manager at the same time. var versionStrings []string err = wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) { if versionStrings, err = restclient.ServerAPIVersions(kubeconfig); err == nil { return true, nil } glog.Errorf("Failed to get api versions from server: %v", err) return false, nil }) if err != nil { glog.Fatalf("Failed to get api versions from server: %v", err) } sharedInformers.Start(stop) select {} }