diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go index 6171b6735be..13388216ef4 100644 --- a/federation/pkg/kubefed/init/init.go +++ b/federation/pkg/kubefed/init/init.go @@ -139,6 +139,7 @@ type initFederationOptions struct { dnsProviderConfig string etcdImage string etcdPVCapacity string + etcdPVStorageClass string etcdPersistentStorage bool dryRun bool apiServerOverridesString string @@ -159,6 +160,7 @@ func (o *initFederationOptions) Bind(flags *pflag.FlagSet, defaultServerImage, d flags.StringVar(&o.dnsProviderConfig, "dns-provider-config", "", "Config file path on local file system for configuring DNS provider.") flags.StringVar(&o.etcdImage, "etcd-image", defaultEtcdImage, "Image to use for etcd server.") flags.StringVar(&o.etcdPVCapacity, "etcd-pv-capacity", "10Gi", "Size of persistent volume claim to be used for etcd.") + flags.StringVar(&o.etcdPVStorageClass, "etcd-pv-storage-class", "", "The storage class of the persistent volume claim used for etcd. Must be provided if a default storage class is not enabled for the host cluster.") flags.BoolVar(&o.etcdPersistentStorage, "etcd-persistent-storage", true, "Use persistent volume for etcd. Defaults to 'true'.") flags.BoolVar(&o.dryRun, "dry-run", false, "dry run without sending commands to server.") flags.StringVar(&o.apiServerOverridesString, "apiserver-arg-overrides", "", "comma separated list of federation-apiserver arguments to override: Example \"--arg1=value1,--arg2=value2...\"") @@ -325,7 +327,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { glog.V(4).Info("Creating a persistent volume and a claim to store the federation API server's state, including etcd data") var pvc *api.PersistentVolumeClaim if i.options.etcdPersistentStorage { - pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.dryRun) + pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.etcdPVStorageClass, i.options.dryRun) if err != nil { return err } @@ -638,20 +640,25 @@ func createControllerManagerKubeconfigSecret(clientset client.Interface, namespa return util.CreateKubeconfigSecret(clientset, config, namespace, kubeconfigName, name, "", dryRun) } -func createPVC(clientset client.Interface, namespace, svcName, federationName, etcdPVCapacity string, dryRun bool) (*api.PersistentVolumeClaim, error) { +func createPVC(clientset client.Interface, namespace, svcName, federationName, etcdPVCapacity, etcdPVStorageClass string, dryRun bool) (*api.PersistentVolumeClaim, error) { capacity, err := resource.ParseQuantity(etcdPVCapacity) if err != nil { return nil, err } + var storageClassName *string + if len(etcdPVStorageClass) > 0 { + storageClassName = &etcdPVStorageClass + } + pvc := &api.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%s-etcd-claim", svcName), Namespace: namespace, Labels: componentLabel, Annotations: map[string]string{ - "volume.alpha.kubernetes.io/storage-class": "yes", - federation.FederationNameAnnotation: federationName}, + federation.FederationNameAnnotation: federationName, + }, }, Spec: api.PersistentVolumeClaimSpec{ AccessModes: []api.PersistentVolumeAccessMode{ @@ -662,6 +669,7 @@ func createPVC(clientset client.Interface, namespace, svcName, federationName, e api.ResourceStorage: capacity, }, }, + StorageClassName: storageClassName, }, } diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go index 4598a6256fe..765bbad5ffb 100644 --- a/federation/pkg/kubefed/init/init_test.go +++ b/federation/pkg/kubefed/init/init_test.go @@ -98,6 +98,7 @@ func TestInitFederation(t *testing.T) { serverImage string etcdImage string etcdPVCapacity string + etcdPVStorageClass string etcdPersistence string expectedErr string dnsProvider string @@ -200,6 +201,7 @@ func TestInitFederation(t *testing.T) { serverImage: "example.test/foo:bar", etcdImage: "gcr.io/google_containers/etcd:latest", etcdPVCapacity: "5Gi", + etcdPVStorageClass: "fast", etcdPersistence: "true", expectedErr: "", dryRun: "", @@ -244,7 +246,7 @@ func TestInitFederation(t *testing.T) { tc.etcdImage = defaultEtcdImage } - hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.serverImage, tc.etcdImage, tc.dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.apiserverArgOverrides, tc.cmArgOverrides, tmpDirPath, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth, tc.isRBACAPIAvailable) + hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.serverImage, tc.etcdImage, tc.dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.etcdPVStorageClass, tc.apiserverArgOverrides, tc.cmArgOverrides, tmpDirPath, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth, tc.isRBACAPIAvailable) if err != nil { t.Fatalf("[%d] unexpected error: %v", i, err) } @@ -271,6 +273,9 @@ func TestInitFederation(t *testing.T) { if tc.etcdPVCapacity != "" { cmd.Flags().Set("etcd-pv-capacity", tc.etcdPVCapacity) } + if tc.etcdPVStorageClass != "" { + cmd.Flags().Set("etcd-pv-storage-class", tc.etcdPVStorageClass) + } if tc.etcdPersistence != "true" { cmd.Flags().Set("etcd-persistent-storage", tc.etcdPersistence) } @@ -616,7 +621,7 @@ func TestCertsHTTPS(t *testing.T) { } } -func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, serverImage, etcdImage, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, apiserverOverrideArg, cmOverrideArg, tmpDirPath string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth, isRBACAPIAvailable bool) (cmdutil.Factory, error) { +func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, serverImage, etcdImage, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, etcdPVStorageClass, apiserverOverrideArg, cmOverrideArg, tmpDirPath string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth, isRBACAPIAvailable bool) (cmdutil.Factory, error) { svcName := federationName + "-apiserver" svcUrlPrefix := "/api/v1/namespaces/federation-system/services" credSecretName := svcName + "-credentials" @@ -729,6 +734,11 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na Data: nil, } + var storageClassName *string + if len(etcdPVStorageClass) > 0 { + storageClassName = &etcdPVStorageClass + } + pvc := v1.PersistentVolumeClaim{ TypeMeta: metav1.TypeMeta{ Kind: "PersistentVolumeClaim", @@ -739,8 +749,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na Namespace: namespaceName, Labels: componentLabel, Annotations: map[string]string{ - "volume.alpha.kubernetes.io/storage-class": "yes", - federation.FederationNameAnnotation: federationName, + federation.FederationNameAnnotation: federationName, }, }, Spec: v1.PersistentVolumeClaimSpec{ @@ -752,6 +761,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na v1.ResourceStorage: capacity, }, }, + StorageClassName: storageClassName, }, } diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 6c87133d4a3..a05df138fa9 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -216,6 +216,7 @@ etcd-mutation-timeout etcd-persistent-storage etcd-prefix etcd-pv-capacity +etcd-pv-storage-class etcd-quorum-read etcd-server etcd-servers