From 0858d84e2aef4195d1b9ce04e704e82fc1fb376e Mon Sep 17 00:00:00 2001 From: David Robson Date: Tue, 3 Mar 2020 10:06:08 -0800 Subject: [PATCH] [k8s] Remove pv name at startup and replace with "useMountSourceForVolumeName" (#2621) Fix Unit tests. --- .../Constants.cs | 2 +- .../deployment/KubernetesDeploymentMapper.cs | 21 ++++++--------- .../edgedeployment/pvc/KubernetesPvcMapper.cs | 15 +++++------ .../Program.cs | 4 +-- .../modules/KubernetesModule.cs | 10 +++---- .../KubernetesDeploymentMapperTest.cs | 10 +++---- .../pvc/KubernetesPvcMapperTest.cs | 26 +++++++++---------- .../podwatch.txt | 3 ++- .../edge-kubernetes/templates/_helpers.tpl | 4 +-- kubernetes/charts/edge-kubernetes/values.yaml | 13 +++------- .../edge-deployment-to-k8s-translations.md | 22 ++++++++-------- 11 files changed, 58 insertions(+), 72 deletions(-) diff --git a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/Constants.cs b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/Constants.cs index e9546b9af76..de598e33963 100644 --- a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/Constants.cs +++ b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/Constants.cs @@ -67,7 +67,7 @@ public static class EdgeDeployment public const string ProxyTrustBundleConfigMapEnvKey = "ProxyTrustBundleConfigMapName"; - public const string PersistentVolumeNameKey = "PersistentVolumeName"; + public const string UseMountSourceForVolumeNameKey = "UseMountSourceForVolumeName"; public const string StorageClassNameKey = "StorageClassName"; diff --git a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/deployment/KubernetesDeploymentMapper.cs b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/deployment/KubernetesDeploymentMapper.cs index 0cf895764b2..a8d61346915 100644 --- a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/deployment/KubernetesDeploymentMapper.cs +++ b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/deployment/KubernetesDeploymentMapper.cs @@ -31,7 +31,7 @@ public class KubernetesDeploymentMapper : IKubernetesDeploymentMapper readonly string proxyTrustBundleVolumeName; readonly string proxyTrustBundleConfigMapName; readonly PortMapServiceType defaultServiceType; - readonly Option persistentVolumeName; + readonly bool useMountSourceForVolumeName; readonly Option storageClassName; readonly Option persistentVolumeClaimDefaultSizeMb; readonly string workloadApiVersion; @@ -53,7 +53,7 @@ public KubernetesDeploymentMapper( string proxyTrustBundleVolumeName, string proxyTrustBundleConfigMapName, PortMapServiceType defaultServiceType, - string persistentVolumeName, + bool useMountSourceForVolumeName, string storageClassName, Option persistentVolumeClaimDefaultSizeMb, string workloadApiVersion, @@ -74,8 +74,7 @@ public KubernetesDeploymentMapper( this.proxyTrustBundleVolumeName = proxyTrustBundleVolumeName; this.proxyTrustBundleConfigMapName = proxyTrustBundleConfigMapName; this.defaultServiceType = defaultServiceType; - this.persistentVolumeName = Option.Maybe(persistentVolumeName) - .Filter(p => !string.IsNullOrWhiteSpace(p)); + this.useMountSourceForVolumeName = useMountSourceForVolumeName; this.storageClassName = Option.Maybe(storageClassName); this.persistentVolumeClaimDefaultSizeMb = persistentVolumeClaimDefaultSizeMb; this.workloadApiVersion = workloadApiVersion; @@ -228,7 +227,7 @@ List CollectModuleEnv(KubernetesModule module, IModuleIdentity identit envList.Add(new V1EnvVar(KubernetesConstants.EdgeK8sObjectOwnerUidKey, module.Owner.Uid)); envList.Add(new V1EnvVar(KubernetesConstants.PortMappingServiceType, this.defaultServiceType.ToString())); envList.Add(new V1EnvVar(KubernetesConstants.EnableK8sServiceCallTracingName, this.enableServiceCallTracing.ToString())); - this.persistentVolumeName.ForEach(pvName => envList.Add(new V1EnvVar(KubernetesConstants.PersistentVolumeNameKey, pvName))); + envList.Add(new V1EnvVar(KubernetesConstants.UseMountSourceForVolumeNameKey, this.useMountSourceForVolumeName.ToString())); this.storageClassName.ForEach(scName => envList.Add(new V1EnvVar(KubernetesConstants.StorageClassNameKey, scName))); this.persistentVolumeClaimDefaultSizeMb.ForEach(size => envList.Add(new V1EnvVar(KubernetesConstants.PersistentVolumeClaimDefaultSizeInMbKey, size.ToString()))); envList.AddRange(this.experimentalFeatures.Select(env => new V1EnvVar(env.Key, env.Value.ToString()))); @@ -361,10 +360,8 @@ static string ToProxyLogLevel(LogEventLevel level) V1Volume GetVolume(KubernetesModule module, Mount mount) { - // Volume name will be pvName if persistent volume is set, else will be volumeName - string volumeName = this.persistentVolumeName - .Map(KubeUtils.SanitizeK8sValue) - .GetOrElse(() => KubeUtils.SanitizeDNSValue(mount.Source)); + // Volume name will be mount.Source + string volumeName = KubeUtils.SanitizeDNSValue(mount.Source); // PVC name will be volume name string pvcName = volumeName; @@ -377,10 +374,8 @@ V1Volume GetVolume(KubernetesModule module, Mount mount) V1VolumeMount GetVolumeMount(Mount mount) { - // Volume name will be pvName if persistent volume is set, else will be volumeName - string volumeName = this.persistentVolumeName - .Map(KubeUtils.SanitizeK8sValue) - .GetOrElse(() => KubeUtils.SanitizeDNSValue(mount.Source)); + // Volume name will be mount.Source + string volumeName = KubeUtils.SanitizeDNSValue(mount.Source); return new V1VolumeMount(mount.Target, volumeName, readOnlyProperty: mount.ReadOnly); } diff --git a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/pvc/KubernetesPvcMapper.cs b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/pvc/KubernetesPvcMapper.cs index 7e3268d9734..fdeaf4c1901 100644 --- a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/pvc/KubernetesPvcMapper.cs +++ b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Kubernetes/edgedeployment/pvc/KubernetesPvcMapper.cs @@ -10,17 +10,16 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Kubernetes.EdgeDeployment.Pvc public class KubernetesPvcMapper : IKubernetesPvcMapper { - readonly Option persistentVolumeName; + readonly bool useMountSourceForVolumeName; readonly Option storageClassName; readonly uint persistentVolumeClaimSizeMb; public KubernetesPvcMapper( - string persistentVolumeName, + bool useMountSourceForVolumeName, string storageClassName, uint persistentVolumeClaimSizeMb) { - this.persistentVolumeName = Option.Maybe(persistentVolumeName) - .Filter(p => !string.IsNullOrWhiteSpace(p)); + this.useMountSourceForVolumeName = useMountSourceForVolumeName; this.storageClassName = Option.Maybe(storageClassName); this.persistentVolumeClaimSizeMb = persistentVolumeClaimSizeMb; } @@ -38,7 +37,7 @@ bool ShouldCreatePvc(Mount mount) return false; } - return this.storageClassName.HasValue || this.persistentVolumeName.HasValue; + return this.storageClassName.HasValue; } V1PersistentVolumeClaim ExtractPvc(KubernetesModule module, Mount mount, IDictionary labels) @@ -58,11 +57,9 @@ V1PersistentVolumeClaim ExtractPvc(KubernetesModule module, Mount mount, IDictio Requests = new Dictionary() { { "storage", new ResourceQuantity($"{this.persistentVolumeClaimSizeMb}Mi") } } }, }; - if (this.persistentVolumeName.HasValue) + if (this.useMountSourceForVolumeName) { - string pvName = this.persistentVolumeName.OrDefault(); - pvcName = KubeUtils.SanitizeK8sValue(pvName); - persistentVolumeClaimSpec.VolumeName = pvcName; + persistentVolumeClaimSpec.VolumeName = volumeName; } if (this.storageClassName.HasValue) diff --git a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/Program.cs b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/Program.cs index cef5e813b71..1a8892994d0 100644 --- a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/Program.cs +++ b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/Program.cs @@ -188,7 +188,7 @@ public static async Task MainAsync(IConfiguration configuration) string proxyTrustBundleConfigMapName = configuration.GetValue(K8sConstants.ProxyTrustBundleConfigMapEnvKey); PortMapServiceType mappedServiceDefault = GetDefaultServiceType(configuration); bool enableServiceCallTracing = configuration.GetValue(K8sConstants.EnableK8sServiceCallTracingName); - string persistentVolumeName = configuration.GetValue(K8sConstants.PersistentVolumeNameKey); + bool useMountSourceForVolumeName = configuration.GetValue(K8sConstants.UseMountSourceForVolumeNameKey, false); string storageClassName = configuration.GetValue(K8sConstants.StorageClassNameKey); Option persistentVolumeClaimDefaultSizeMb = Option.Maybe(configuration.GetValue(K8sConstants.PersistentVolumeClaimDefaultSizeInMbKey)); string deviceNamespace = configuration.GetValue(K8sConstants.K8sNamespaceKey); @@ -223,7 +223,7 @@ public static async Task MainAsync(IConfiguration configuration) Option.Some(productInfo), mappedServiceDefault, enableServiceCallTracing, - persistentVolumeName, + useMountSourceForVolumeName, storageClassName, persistentVolumeClaimDefaultSizeMb, proxy, diff --git a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/modules/KubernetesModule.cs b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/modules/KubernetesModule.cs index 9b2d02c299a..e3fbd802aba 100755 --- a/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/modules/KubernetesModule.cs +++ b/edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Service/modules/KubernetesModule.cs @@ -54,7 +54,7 @@ public class KubernetesModule : Module readonly Option productInfo; readonly PortMapServiceType defaultMapServiceType; readonly bool enableServiceCallTracing; - readonly string persistentVolumeName; + readonly bool useMountSourceForVolumeName; readonly string storageClassName; readonly Option persistentVolumeClaimSizeMb; readonly Option proxy; @@ -86,7 +86,7 @@ public KubernetesModule( Option productInfo, PortMapServiceType defaultMapServiceType, bool enableServiceCallTracing, - string persistentVolumeName, + bool useMountSourceForVolumeName, string storageClassName, Option persistentVolumeClaimSizeMb, Option proxy, @@ -117,7 +117,7 @@ public KubernetesModule( this.productInfo = productInfo; this.defaultMapServiceType = defaultMapServiceType; this.enableServiceCallTracing = enableServiceCallTracing; - this.persistentVolumeName = persistentVolumeName; + this.useMountSourceForVolumeName = useMountSourceForVolumeName; this.storageClassName = storageClassName; this.persistentVolumeClaimSizeMb = persistentVolumeClaimSizeMb; this.proxy = proxy; @@ -256,7 +256,7 @@ protected override void Load(ContainerBuilder builder) this.proxyTrustBundleVolumeName, this.proxyTrustBundleConfigMapName, this.defaultMapServiceType, - this.persistentVolumeName, + this.useMountSourceForVolumeName, this.storageClassName, this.persistentVolumeClaimSizeMb, this.apiVersion, @@ -272,7 +272,7 @@ protected override void Load(ContainerBuilder builder) .As(); // KubernetesPvcMapper - builder.Register(c => new KubernetesPvcMapper(this.persistentVolumeName, this.storageClassName, this.persistentVolumeClaimSizeMb.OrDefault())) + builder.Register(c => new KubernetesPvcMapper(this.useMountSourceForVolumeName, this.storageClassName, this.persistentVolumeClaimSizeMb.OrDefault())) .As(); // KubernetesServiceAccountProvider diff --git a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/KubernetesDeploymentMapperTest.cs b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/KubernetesDeploymentMapperTest.cs index 88e6347ed5b..3ae61c8dc0c 100644 --- a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/KubernetesDeploymentMapperTest.cs +++ b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/KubernetesDeploymentMapperTest.cs @@ -193,7 +193,7 @@ public void PvcMappingForVolumeNameVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(labels: labels, hostConfig: hostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = CreateMapper("a-volume", null); + var mapper = CreateMapper(true, null); var deployment = mapper.CreateDeployment(identity, module, labels); @@ -573,7 +573,7 @@ public void EdgeAgentEnvSettingsHaveLotsOfStuff() ["feature1"] = true, ["feature2"] = false }; - var mapper = CreateMapper(runAsNonRoot: true, persistentVolumeName: "pvname", storageClassName: "scname", proxyImagePullSecretName: "secret name", experimentalFeatures: features); + var mapper = CreateMapper(runAsNonRoot: true, useMountSourceForVolumeName: true, storageClassName: "scname", proxyImagePullSecretName: "secret name", experimentalFeatures: features); var deployment = mapper.CreateDeployment(identity, module, labels); @@ -598,7 +598,7 @@ public void EdgeAgentEnvSettingsHaveLotsOfStuff() Assert.Equal("123", container.Env.Single(e => e.Name == KubernetesConstants.EdgeK8sObjectOwnerUidKey).Value); Assert.Equal("ClusterIP", container.Env.Single(e => e.Name == KubernetesConstants.PortMappingServiceType).Value); Assert.Equal("False", container.Env.Single(e => e.Name == KubernetesConstants.EnableK8sServiceCallTracingName).Value); - Assert.Equal("pvname", container.Env.Single(e => e.Name == KubernetesConstants.PersistentVolumeNameKey).Value); + Assert.Equal("True", container.Env.Single(e => e.Name == KubernetesConstants.UseMountSourceForVolumeNameKey).Value); Assert.Equal("scname", container.Env.Single(e => e.Name == KubernetesConstants.StorageClassNameKey).Value); Assert.Equal("100", container.Env.Single(e => e.Name == KubernetesConstants.PersistentVolumeClaimDefaultSizeInMbKey).Value); Assert.Equal("True", container.Env.Single(e => e.Name == "feature1").Value); @@ -606,7 +606,7 @@ public void EdgeAgentEnvSettingsHaveLotsOfStuff() } static KubernetesDeploymentMapper CreateMapper( - string persistentVolumeName = "", + bool useMountSourceForVolumeName = false, string storageClassName = "", string proxyImagePullSecretName = null, bool runAsNonRoot = false, @@ -623,7 +623,7 @@ static KubernetesDeploymentMapper CreateMapper( "trustBundleVolumeName", "trustBundleConfigMapName", PortMapServiceType.ClusterIP, - persistentVolumeName, + useMountSourceForVolumeName, storageClassName, Option.Some(100), "apiVersion", diff --git a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/edgedeployment/pvc/KubernetesPvcMapperTest.cs b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/edgedeployment/pvc/KubernetesPvcMapperTest.cs index 013b854554f..8680be43617 100644 --- a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/edgedeployment/pvc/KubernetesPvcMapperTest.cs +++ b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/edgedeployment/pvc/KubernetesPvcMapperTest.cs @@ -79,7 +79,7 @@ public void NullMountsNoClaims() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeNullMount), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(string.Empty, "storage", 1); + var mapper = new KubernetesPvcMapper(false, "storage", 1); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -92,7 +92,7 @@ public void NoMountsNoClaims() var config = new KubernetesConfig("image", CreatePodParameters.Create(), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(string.Empty, "storage", 1); + var mapper = new KubernetesPvcMapper(false, "storage", 1); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -105,7 +105,7 @@ public void EmptyDirMappingForVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(null, null, 0); + var mapper = new KubernetesPvcMapper(false, null, 0); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -118,7 +118,7 @@ public void EmptyDirMappingForVolume2() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(string.Empty, null, 0); + var mapper = new KubernetesPvcMapper(false, null, 0); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -131,7 +131,7 @@ public void DefaultStorageClassMappingForVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(string.Empty, string.Empty, 10); + var mapper = new KubernetesPvcMapper(false, string.Empty, 10); var resourceQuantity = new ResourceQuantity("10Mi"); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -168,7 +168,7 @@ public void StorageClassMappingForVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper(string.Empty, "default", 10); + var mapper = new KubernetesPvcMapper(false, "default", 10); var resourceQuantity = new ResourceQuantity("10Mi"); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -205,7 +205,7 @@ public void VolumeNameMappingForVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper("pvname", "storage-class", 37); + var mapper = new KubernetesPvcMapper(true, "storage-class", 37); var resourceQuantity = new ResourceQuantity("37Mi"); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); @@ -215,23 +215,21 @@ public void VolumeNameMappingForVolume() Assert.True(pvcList.Any()); Assert.Equal(2, pvcList.Count); - var aVolumeClaim = pvcList[0]; - Assert.Equal("pvname", aVolumeClaim.Metadata.Name); + var aVolumeClaim = pvcList.Single(pvc => pvc.Metadata.Name == "a-volume"); Assert.True(aVolumeClaim.Metadata.Labels.SequenceEqual(DefaultLabels)); Assert.Equal("ReadOnlyMany", aVolumeClaim.Spec.AccessModes[0]); Assert.Equal("storage-class", aVolumeClaim.Spec.StorageClassName); - Assert.Equal("pvname", aVolumeClaim.Spec.VolumeName); + Assert.Equal("a-volume", aVolumeClaim.Spec.VolumeName); Assert.Equal(resourceQuantity, aVolumeClaim.Spec.Resources.Requests["storage"]); Assert.Equal(1, aVolumeClaim.Metadata.OwnerReferences.Count); Assert.Equal(V1Deployment.KubeKind, aVolumeClaim.Metadata.OwnerReferences[0].Kind); Assert.Equal(EdgeletModuleOwner.Name, aVolumeClaim.Metadata.OwnerReferences[0].Name); - var bVolumeClaim = pvcList[1]; - Assert.Equal("pvname", bVolumeClaim.Metadata.Name); + var bVolumeClaim = pvcList.Single(pvc => pvc.Metadata.Name == "b-volume"); Assert.True(bVolumeClaim.Metadata.Labels.SequenceEqual(DefaultLabels)); Assert.Equal("ReadWriteMany", bVolumeClaim.Spec.AccessModes[0]); Assert.Equal("storage-class", bVolumeClaim.Spec.StorageClassName); - Assert.Equal("pvname", bVolumeClaim.Spec.VolumeName); + Assert.Equal("b-volume", bVolumeClaim.Spec.VolumeName); Assert.Equal(resourceQuantity, bVolumeClaim.Spec.Resources.Requests["storage"]); Assert.Equal(1, bVolumeClaim.Metadata.OwnerReferences.Count); Assert.Equal(V1Deployment.KubeKind, bVolumeClaim.Metadata.OwnerReferences[0].Kind); @@ -244,7 +242,7 @@ public void PreferVolumeNameMappingForVolume() var config = new KubernetesConfig("image", CreatePodParameters.Create(hostConfig: VolumeMountHostConfig1), Option.None()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config, EdgeletModuleOwner); - var mapper = new KubernetesPvcMapper("a-volume", "storageclass", 1); + var mapper = new KubernetesPvcMapper(true, "storageclass", 1); var resourceQuantity = new ResourceQuantity("1Mi"); var pvcs = mapper.CreatePersistentVolumeClaims(module, DefaultLabels); diff --git a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/podwatch.txt b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/podwatch.txt index 384bb2b50f3..99cabfa3c17 100644 --- a/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/podwatch.txt +++ b/edge-agent/test/Microsoft.Azure.Devices.Edge.Agent.Kubernetes.Test/podwatch.txt @@ -120,7 +120,8 @@ "value": "2" }, { - "name": "PersistentVolumeName" + "name": "UseMountSourceForVolumeName", + "value": "False" }, { "name": "StorageClassName", diff --git a/kubernetes/charts/edge-kubernetes/templates/_helpers.tpl b/kubernetes/charts/edge-kubernetes/templates/_helpers.tpl index beebc4af353..5d1146b9c23 100644 --- a/kubernetes/charts/edge-kubernetes/templates/_helpers.tpl +++ b/kubernetes/charts/edge-kubernetes/templates/_helpers.tpl @@ -82,8 +82,8 @@ agent: {{- if .Values.iotedged.data.httpsProxy }} https_proxy: {{ .Values.iotedged.data.httpsProxy | quote }} {{- end}} - {{- if .Values.edgeAgent.env.persistentVolumeName}} - PersistentVolumeName: {{ .Values.edgeAgent.env.persistentVolumeName | quote }} + {{- if .Values.edgeAgent.env.useMountSourceForVolumeName}} + UseMountSourceForVolumeName: {{ .Values.edgeAgent.env.useMountSourceForVolumeName | quote }} {{- end }} {{- if .Values.edgeAgent.env.storageClassName}} StorageClassName: {{- if (eq "-" .Values.edgeAgent.env.storageClassName) }} "" {{- else }} {{ .Values.edgeAgent.env.storageClassName | quote }} {{- end }} diff --git a/kubernetes/charts/edge-kubernetes/values.yaml b/kubernetes/charts/edge-kubernetes/values.yaml index b3824dcff50..5a6744ec035 100644 --- a/kubernetes/charts/edge-kubernetes/values.yaml +++ b/kubernetes/charts/edge-kubernetes/values.yaml @@ -130,15 +130,10 @@ edgeAgent: # Configure the default claim size to use (in megabytes) when creating PVCs. # persistentVolumeClaimDefaultSizeInMb: "" - # Set this to the name of a persistent volume if you wish the volumes that - # back persistent storage in modules to use that PV. Note that you may - # sometimes to also need to set the "storageClassName" field below to an - # empty string in order for this to work. Since Helm does not provide a - # clean way of specifying an empty string (see: https://github.com/helm/helm/issues/2600) - # you'll need to set the value "-" in liue of an empty string. This literal - # will be interpreted to mean that the storage class needs to be set to an - # empty string. - # persistentVolumeName: "" + # Set this as guidance for converting Docker Volume mounts to Persistent Volume Claims. + # Set to true to tell the runtime to use the Volume mount source (mount.Source) as the + # Persistent volume name (volumeName) in the PVC + useMountSourceForVolumeName: false # Set this to the name of a storage class name if you wish the volumes that # back persistent storage in modules to use dynamically provisioned PVCs. diff --git a/kubernetes/doc/edge-deployment-to-k8s-translations.md b/kubernetes/doc/edge-deployment-to-k8s-translations.md index fa5dd3b6e98..81029fbb01f 100644 --- a/kubernetes/doc/edge-deployment-to-k8s-translations.md +++ b/kubernetes/doc/edge-deployment-to-k8s-translations.md @@ -60,7 +60,7 @@ they affect the Kubernetes objects. | ------- | -------------------- | | edgeAgent.env.portMappingServiceType | [Service](#service) | | edgeAgent.env.persistentVolumeClaimDefaultSizeInMb | [Deployment](#podtemplate), [PersistentVolumeClaim](#persistentvolumeclaim) | -| edgeAgent.env.persistentVolumeName | [Deployment](#podtemplate), [PersistentVolumeClaim](#persistentvolumeclaim) | +| edgeAgent.env.useMountSourceForVolumeName | [Deployment](#podtemplate), [PersistentVolumeClaim](#persistentvolumeclaim) | | edgeAgent.env.storageClassName | [Deployment](#podtemplate), [PersistentVolumeClaim](#persistentvolumeclaim) | | edgeAgent.env.enableExperimentalFeatures | [Deployment](#podtemplate) - See [K8s Extensions](#k8s-extensions) for details | | edgeAgent.env.enableK8sExtensions | [Deployment](#podtemplate) - See [K8s Extensions](#k8s-extensions) for details | @@ -166,9 +166,9 @@ Each IoT Edge Module will create one Deployment. This will run the module's spec - volume mounts from `settings.createOptions.HostConfig.Mounts` - name = mount.Source - persistentVolumeClaim is always assigned - - if edge runtime is started with `persistentVolumeName` or `storageClassName` set it will create a [Persistent Volume Claim](#PersistentVolumeClaim) - - if neither is set Pod will be created but stuck in `Pending` phase not been able to make any progress - - claimName = persistentVolumeName if `persistentVolumeName` is set, mount.Source otherwise. + - if edge runtime is started with `useMountSourceForVolumeName` or `storageClassName` set it will create a [Persistent Volume Claim](#PersistentVolumeClaim) + - if neither is set Pod will be created but stuck in `Pending` phase until a PVC is created. + - claimName = mount.Source - readOnlyProperty = mount.ReadOnly - volume mounts from `settings.k8s-extensions.volumes[*].volume`. Placed in spec as provided. - **serviceAccountName** = The module name, sanitized to be a K8s identifier. See [Module Authentication](rbac.md#module-authentication) for details. @@ -216,14 +216,14 @@ Persistent volume claims are created when a docker volume is requested (all volu `settings.createOptions.HostConfig.Mounts`), the persistent volume claim has not been created by the user, and the runtime has been set to expect to use persistent volumes. -The runtime is set to expect PVs by assigning `persistentVolumeName` or `storageClassName` at -startup. User will also need to set a value for `persistentVolumeClaimDefaultSizeInMb`. This value -gives the IoT Edge Runtime a default claim size as this is not provided by `createOptions`. - +The runtime is set to expect PVs by assigning `storageClassName` and a value for +`persistentVolumeClaimDefaultSizeInMb`. This value gives the IoT Edge Runtime a default claim size +as this is not provided by `createOptions`. An optional value `useMountSourceForVolumeName` informs +the runtime to use `mount.Source` in the Docker Volume spec as the persistent volume name. ### metadata -- **name** = persistentVolumeName if `persistentVolumeName` is set, else mount.Source from `settings.createOptions.HostConfig.Mounts`. +- **name** = mount.Source from `settings.createOptions.HostConfig.Mounts`. - **namespace** = The given namespace. - **labels** = Default label set. @@ -233,8 +233,8 @@ gives the IoT Edge Runtime a default claim size as this is not provided by `crea - **resources** - **requests** - **storage** = `persistentVolumeClaimDefaultSizeInMb` - - **volumeName** = `persistentVolumeName` - assigned if set. - - **storageClass** = `storageClassName` - assigned if set and `persistentVolumeName` is not set. + - **volumeName** = mount.Source if `useMountSourceForVolumeName` is true, unset otherwise. + - **storageClass** = `storageClassName` - assigned if set. ## ServiceAccount