diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go index 841c85ecb851..95bda0a1cb12 100644 --- a/federation/pkg/kubefed/init/init.go +++ b/federation/pkg/kubefed/init/init.go @@ -134,6 +134,7 @@ func NewCmdInit(cmdOut io.Writer, config util.AdminConfig) *cobra.Command { cmd.Flags().String("image", defaultImage, "Image to use for federation API server and controller manager binaries.") cmd.Flags().String("dns-provider", "google-clouddns", "Dns provider to be used for this deployment.") cmd.Flags().String("etcd-pv-capacity", "10Gi", "Size of persistent volume claim to be used for etcd.") + cmd.Flags().Bool("etcd-persistent-storage", true, "Use persistent volume for etcd. Defaults to 'true'.") cmd.Flags().Bool("dry-run", false, "dry run without sending commands to server.") cmd.Flags().String("storage-backend", "etcd2", "The storage backend for persistence. Options: 'etcd2' (default), 'etcd3'.") return cmd @@ -158,6 +159,7 @@ func initFederation(cmdOut io.Writer, config util.AdminConfig, cmd *cobra.Comman image := cmdutil.GetFlagString(cmd, "image") dnsProvider := cmdutil.GetFlagString(cmd, "dns-provider") etcdPVCapacity := cmdutil.GetFlagString(cmd, "etcd-pv-capacity") + etcdPersistence := cmdutil.GetFlagBool(cmd, "etcd-persistent-storage") dryRun := cmdutil.GetDryRunFlag(cmd) storageBackend := cmdutil.GetFlagString(cmd, "storage-backend") @@ -208,9 +210,12 @@ func initFederation(cmdOut io.Writer, config util.AdminConfig, cmd *cobra.Comman // 5. Create a persistent volume and a claim to store the federation // API server's state. This is where federation API server's etcd // stores its data. - pvc, err := createPVC(hostClientset, initFlags.FederationSystemNamespace, svc.Name, etcdPVCapacity, dryRun) - if err != nil { - return err + var pvc *api.PersistentVolumeClaim + if etcdPersistence { + pvc, err = createPVC(hostClientset, initFlags.FederationSystemNamespace, svc.Name, etcdPVCapacity, dryRun) + if err != nil { + return err + } } // Since only one IP address can be specified as advertise address, @@ -226,7 +231,7 @@ func initFederation(cmdOut io.Writer, config util.AdminConfig, cmd *cobra.Comman } // 6. Create federation API server - _, err = createAPIServer(hostClientset, initFlags.FederationSystemNamespace, serverName, image, serverCredName, pvc.Name, advertiseAddress, storageBackend, dryRun) + _, err = createAPIServer(hostClientset, initFlags.FederationSystemNamespace, serverName, image, serverCredName, advertiseAddress, storageBackend, pvc, dryRun) if err != nil { return err } @@ -445,7 +450,7 @@ func createPVC(clientset *client.Clientset, namespace, svcName, etcdPVCapacity s return clientset.Core().PersistentVolumeClaims(namespace).Create(pvc) } -func createAPIServer(clientset *client.Clientset, namespace, name, image, credentialsName, pvcName, advertiseAddress, storageBackend string, dryRun bool) (*extensions.Deployment, error) { +func createAPIServer(clientset *client.Clientset, namespace, name, image, credentialsName, advertiseAddress, storageBackend string, pvc *api.PersistentVolumeClaim, dryRun bool) (*extensions.Deployment, error) { command := []string{ "/hyperkube", "federation-apiserver", @@ -462,8 +467,6 @@ func createAPIServer(clientset *client.Clientset, namespace, name, image, creden command = append(command, fmt.Sprintf("--advertise-address=%s", advertiseAddress)) } - dataVolumeName := "etcddata" - dep := &extensions.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -509,12 +512,6 @@ func createAPIServer(clientset *client.Clientset, namespace, name, image, creden "--data-dir", "/var/etcd/data", }, - VolumeMounts: []api.VolumeMount{ - { - Name: dataVolumeName, - MountPath: "/var/etcd", - }, - }, }, }, Volumes: []api.Volume{ @@ -526,20 +523,35 @@ func createAPIServer(clientset *client.Clientset, namespace, name, image, creden }, }, }, - { - Name: dataVolumeName, - VolumeSource: api.VolumeSource{ - PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ - ClaimName: pvcName, - }, - }, - }, }, }, }, }, } + if pvc != nil { + dataVolumeName := "etcddata" + etcdVolume := api.Volume{ + Name: dataVolumeName, + VolumeSource: api.VolumeSource{ + PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ + ClaimName: pvc.Name, + }, + }, + } + etcdVolumeMount := api.VolumeMount{ + Name: dataVolumeName, + MountPath: "/var/etcd", + } + + dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, etcdVolume) + for i, container := range dep.Spec.Template.Spec.Containers { + if container.Name == "etcd" { + dep.Spec.Template.Spec.Containers[i].VolumeMounts = append(dep.Spec.Template.Spec.Containers[i].VolumeMounts, etcdVolumeMount) + } + } + } + if dryRun { return dep, nil } diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go index 42ccfde7d7a6..7cce25964b25 100644 --- a/federation/pkg/kubefed/init/init_test.go +++ b/federation/pkg/kubefed/init/init_test.go @@ -79,6 +79,7 @@ func TestInitFederation(t *testing.T) { lbIP string image string etcdPVCapacity string + etcdPersistence string expectedErr string dnsProvider string storageBackend string @@ -92,6 +93,7 @@ func TestInitFederation(t *testing.T) { lbIP: "10.20.30.40", image: "example.test/foo:bar", etcdPVCapacity: "5Gi", + etcdPersistence: "true", expectedErr: "", dnsProvider: "test-dns-provider", storageBackend: "etcd2", @@ -105,6 +107,7 @@ func TestInitFederation(t *testing.T) { lbIP: "10.20.30.40", image: "example.test/foo:bar", etcdPVCapacity: "", //test for default value of pvc-size + etcdPersistence: "true", expectedErr: "", dnsProvider: "", //test for default value of dns provider storageBackend: "etcd2", @@ -118,6 +121,7 @@ func TestInitFederation(t *testing.T) { lbIP: "10.20.30.40", image: "example.test/foo:bar", etcdPVCapacity: "", + etcdPersistence: "true", expectedErr: "", dnsProvider: "test-dns-provider", storageBackend: "etcd2", @@ -131,6 +135,7 @@ func TestInitFederation(t *testing.T) { lbIP: "10.20.30.40", image: "example.test/foo:bar", etcdPVCapacity: "5Gi", + etcdPersistence: "false", expectedErr: "", dnsProvider: "test-dns-provider", storageBackend: "etcd3", @@ -150,7 +155,7 @@ func TestInitFederation(t *testing.T) { } else { dnsProvider = "google-clouddns" //default value of dns-provider } - hostFactory, err := fakeInitHostFactory(tc.federation, util.DefaultFederationSystemNamespace, tc.lbIP, tc.dnsZoneName, tc.image, dnsProvider, tc.etcdPVCapacity, tc.storageBackend) + hostFactory, err := fakeInitHostFactory(tc.federation, util.DefaultFederationSystemNamespace, tc.lbIP, tc.dnsZoneName, tc.image, dnsProvider, tc.etcdPersistence, tc.etcdPVCapacity, tc.storageBackend) if err != nil { t.Fatalf("[%d] unexpected error: %v", i, err) } @@ -175,6 +180,9 @@ func TestInitFederation(t *testing.T) { if tc.etcdPVCapacity != "" { cmd.Flags().Set("etcd-pv-capacity", tc.etcdPVCapacity) } + if tc.etcdPersistence != "true" { + cmd.Flags().Set("etcd-persistent-storage", tc.etcdPersistence) + } if tc.dryRun == "valid-run" { cmd.Flags().Set("dry-run", "true") } @@ -445,7 +453,7 @@ func TestCertsHTTPS(t *testing.T) { } } -func fakeInitHostFactory(federationName, namespaceName, ip, dnsZoneName, image, dnsProvider, etcdPVCapacity, storageProvider string) (cmdutil.Factory, error) { +func fakeInitHostFactory(federationName, namespaceName, ip, dnsZoneName, image, dnsProvider, etcdPersistence, etcdPVCapacity, storageProvider string) (cmdutil.Factory, error) { svcName := federationName + "-apiserver" svcUrlPrefix := "/api/v1/namespaces/federation-system/services" credSecretName := svcName + "-credentials" @@ -673,12 +681,6 @@ func fakeInitHostFactory(federationName, namespaceName, ip, dnsZoneName, image, "--data-dir", "/var/etcd/data", }, - VolumeMounts: []v1.VolumeMount{ - { - Name: "etcddata", - MountPath: "/var/etcd", - }, - }, }, }, Volumes: []v1.Volume{ @@ -690,19 +692,33 @@ func fakeInitHostFactory(federationName, namespaceName, ip, dnsZoneName, image, }, }, }, - { - Name: "etcddata", - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: pvcName, - }, - }, - }, }, }, }, }, } + if etcdPersistence == "true" { + dataVolumeName := "etcddata" + etcdVolume := v1.Volume{ + Name: dataVolumeName, + VolumeSource: v1.VolumeSource{ + PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvcName, + }, + }, + } + etcdVolumeMount := v1.VolumeMount{ + Name: dataVolumeName, + MountPath: "/var/etcd", + } + + apiserver.Spec.Template.Spec.Volumes = append(apiserver.Spec.Template.Spec.Volumes, etcdVolume) + for i, container := range apiserver.Spec.Template.Spec.Containers { + if container.Name == "etcd" { + apiserver.Spec.Template.Spec.Containers[i].VolumeMounts = append(apiserver.Spec.Template.Spec.Containers[i].VolumeMounts, etcdVolumeMount) + } + } + } cmName := federationName + "-controller-manager" cm := v1beta1.Deployment{ diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 5e6dea99a89c..c2a249d4caa8 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -177,6 +177,7 @@ etcd-keyfile etcd-mutation-timeout etcd-prefix etcd-pv-capacity +etcd-persistent-storage etcd-quorum-read etcd-server etcd-servers