k8s icon indicating copy to clipboard operation
k8s copied to clipboard

How to dynamically create volume for a deployment

Open heurtematte opened this issue 2 years ago • 1 comments

I try to dynamically create volumes for a deployment based on a config file with many volume declarations.

Is there a way to achieve this?

The only way that works is the declarative way, like in the example code

local k8s = (import "github.com/jsonnet-libs/k8s-libsonnet/1.25/main.libsonnet");

local deployment = k8s.apps.v1.deployment.new(
    name=deployment.name, 
    containers=[
      k8sContainer.new(name=deployment.name, image=deployment.image) +
      ...
    ]
  ) +
  k8s.apps.v1.deployment.metadata.withNamespace(namespace) + 

=>  k8s.apps.v1.deployment.emptyVolumeMount("data", deployment.volume.data.path);

config file:

    name: "mydeployment",
    image: "debian",
    namespace: "mynamespace",
    volume:{
        local volume = self,
        local rootMountPath = "/root",
        data:{
            path: rootMountPath + "/data1",
            type: "emptyDir"
        },
        data2:{
            path: rootMountPath + "/data2",
            type: "emptyDir"
        },
        data3:{
            path: rootMountPath + "/data3",
            type: "emptyDir"
        },
    },
}

I try different manner :

1- loop in the deployment configuration, but stuck with super keyword from mapContainers

2- convert the deployment as a function by passing volume

local deployment(volume) = k8sDeployment.new(...

local deployVolume = [deployment(v) for v in std.objectFieldsAll(deployment.volume)];

The result is as expected, there is as much deployment as volume declare. but how merge config recursively?

Another odd behavior when trying something like:

deployVolume[0]+deployVolume[1]

There is a missing VolumeMount in the result!!

 },
                  "volumeMounts": [
                     {
                        "mountPath": "/data2",
                        "name": "data2"
                     }
                  ]
               }
            ],
            "volumes": [
               {
                  "emptyDir": { },
                  "name": "data1"
               },
               {
                  "emptyDir": { },
                  "name": "data2"
               }
            ]
         }

The purpose of this is to create volume factory.

Hope you can help me! :-)

heurtematte avatar Jan 12 '23 17:01 heurtematte

I answered a similar question like this on Slack recently, this was the example I came up with:

local k = import 'github.com/jsonnet-libs/k8s-libsonnet/1.24/main.libsonnet';

local myapp = {
  emptyDirVolumes: [
    { name: 'etc', path: '/opt/etc' },
    { name: 'ops', path: '/opt/ops' },
    // ... we have many
  ],
};

{
  local deployment = k.apps.v1.deployment,
  deployment:
    deployment.new('a', containers=[k.core.v1.container.new('a', 'a')])
    + deployment.spec.template.spec.withInitContainers([k.core.v1.container.new('b', 'b')])
    + std.foldl(
      function(acc, item)
        acc + deployment.emptyVolumeMount(item.name, item.path, includeInitContainers=true),
      myapp.emptyDirVolumes,
      {}
    ),
}```

Duologic avatar Jun 26 '23 08:06 Duologic