Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for additional volumes #339

Merged
merged 10 commits into from
Sep 11, 2024
Merged

Conversation

shreddedbacon
Copy link
Member

@shreddedbacon shreddedbacon commented Jul 26, 2024

This adds support for multiple volumes, currently all volumes provisioned in this manner will default to the Lagoon bulk storage class which will almost always be a ReadWriteMany volume (depends on installation).

The default request size will be 5Gi. For some storage provisioners, this value could be ignored. For example, AWS EFS backed storage doesn't restrict data on these volumes to the size in the claim.

Usage

Volume definitions

In a docker-compose.yml file, volumes will need to be defined with a label lagoon.type: persistent.

At the moment, only a persistent type is supported. Other types may be available in the future if a need arises.

volumes:
  config:
    labels:
      lagoon.type: persistent

Service linking

Once a volume has been defined with the label, a service needs to be informed that it can use this volume.

The label used is structured as lagoon.volumes.${volume_name}.path, and the value of the label must be the path to mount the volume.

Note: If a service type provides a default persistent volume, this still needs to be defined using the lagoon.persistent label on the service. See conditions below on other things to be aware of

services:
  basic:
    build:
      context: .
      dockerfile: basic.dockerfile
    labels:
      lagoon.type: basic-persistent
      lagoon.persistent: /data # basic-persistent provides a default volume, this needs to be defined
      lagoon.volumes.config.path: /config
    volumes: # these volumes are ignored by lagoon, only the labels above are consumed to handle volume mapping
      - ./data:/data:delegated
      - config:/config

Conditions

There are some conditions to additional volumes that users need to be aware of.

Default persistent volumes

  • If a service type provides a default persistent volume (nginx-php-persistent, basic-persistent, node-persistent, python-persistent), it will be created and named as the name of the service (unless the lagoon.persistent.name label is assigned).
  • If a volume defined in the volumes block is also named the same as a default volume would be, it will be ignored and only the default volume will be created.
  • If a lagoon.volumes.${volume_name}.path is also defined on a service that has a default volume (or a volume linked to it using the lagoon.persistent.name label, it will also be ignored and the value of the lagoon.persistent path will be used.

Ignored volume

  • If a volume defined in the volumes block has a label lagoon.type: none it will not be created.
  • If a volume defined in the volumes block has a label lagoon.type of a type (currently only persistent), but it is not consumed by any service using a lagoon.volumes.${volume_name}.path, then the volume will not be created.

Maximum number of volumes

  • Currently a hard-coded limit of 6 volumes is in place, this may be made configurable in the future.

Supported service types

Currently, the only service types that support additional volumes are the following

  • basic / basic-persistent
  • worker / worker-persistent
  • node / node-persistent
  • python / python-persistent
  • nginx / nginx-php / nginx-php-persistent
  • cli / cli-persistent

Adding a volume to any other type will result in an error during a build.

Is it possible to extend a non -persistent service with additional volumes?

The implementation of additional volumes makes the -persistent type almost irrelevant.

It makes changing a lagoon type from a basic to basic-persistent (or other similar type changes) mostly not required. The docker-compose.yml can be extended instead to include the additional volumes as required, including a replacement for what would be a default volume.

This would also make it possible to remove the volumes in the future if they are no longer required without having to recreate the service, as changing a lagoon.type is not a very smooth process.

See the example below that describes how this configuration looks for a basic service type.

Example basic-persistent with additional volumes

An example is as below for a basic deployment that requests 3 volumes and shows how they could be mounted to a basic service. It also includes some examples of some of the conditions.

services:
  basic:
    build:
      context: .
      dockerfile: basic.dockerfile
    labels:
      lagoon.type: basic-persistent
      lagoon.persistent: /data
      lagoon.persistent.name: basic # this is only required if shared between services (ie, nginx-php and cli share usually)
      lagoon.volumes.files.path: /app/files/
      lagoon.volumes.config.path: /config
      lagoon.volumes.basic.path: /different/path/data # this is ignored if the default persistent volume has the same name
    volumes: # these volumes are ignored by lagoon, only the labels are consumed to handle volume mapping
      - basic:/data
      - files:/app/files
      - config:/config

volumes:
  basic:
    labels:
      # this is ignored if a default persistent volume has the same name
      lagoon.type: persistent
  config:
    labels:
      lagoon.type: persistent
  files:
    labels:
      lagoon.type: persistent
      lagoon.persistent.size: 10Gi # if not defined, default is 5Gi like all other pvc lagoon will create

Example basic service type extended with volumes

An example is as below for a basic deployment that uses a service type that doesn't provide a default persistent volume (being a basic type), and shows how they can be mounted.

services:
  basic:
    build:
      context: .
      dockerfile: basic.dockerfile
    labels:
      lagoon.type: basic
      lagoon.volumes.basic.path: /data
      lagoon.volumes.files.path: /app/files/
      lagoon.volumes.config.path: /config
    volumes: # these volumes are ignored by lagoon, only the labels are consumed to handle volume mapping
      - basic:/data
      - files:/app/files
      - config:/config

volumes:
  basic:
    labels:
      lagoon.type: persistent
  config:
    labels:
      lagoon.type: persistent
  files:
    labels:
      lagoon.type: persistent

@shreddedbacon shreddedbacon changed the title feat: add support to types for additional volumes feat: add for additional volumes Jul 26, 2024
Copy link
Contributor

@bomoko bomoko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just pushing initial look through - there's a lot here, I'm not sure I've grokked all of it just yet.

internal/generator/helpers_generator.go Show resolved Hide resolved
internal/generator/images.go Outdated Show resolved Hide resolved
internal/templating/services/templates_pvc.go Show resolved Hide resolved
internal/templating/services/templates_pvc.go Show resolved Hide resolved
@shreddedbacon shreddedbacon changed the title feat: add for additional volumes feat: add support for additional volumes Aug 12, 2024
@shreddedbacon shreddedbacon force-pushed the multiple-volumes branch 2 times, most recently from 1af0325 to 59f10d5 Compare August 18, 2024 22:57
@shreddedbacon shreddedbacon added this to the 2.21.0 milestone Aug 18, 2024
@shreddedbacon shreddedbacon force-pushed the multiple-volumes branch 2 times, most recently from bcb4b20 to 1a03365 Compare August 20, 2024 23:51
@shreddedbacon
Copy link
Member Author

shreddedbacon commented Aug 22, 2024

I just realised, that all PVCs created will be flagged with having backups enabled on them. There may be use cases where the volume does not need to be backed up. Ie, a volume that is used as a temporary holding ground for work files that probably don't need to be backed up. For example, temporary backups etc, a sort of playground type directory that is persistent but not data that needs to be backed up.

I think it might be worth having a way to have the volume ignored from backups, like lagoon.backup: false and the default is true

volumes:
  files:
    labels:
      lagoon.type: persistent
  playground:
    labels:
      lagoon.type: persistent
      lagoon.backup: false

Setting that to false would change this annotation on the resulting PVC and it would be ignored by k8up


Edit: now possible to disable backups on a volume

@shreddedbacon shreddedbacon force-pushed the multiple-volumes branch 2 times, most recently from 08b58b7 to 308d9ed Compare August 25, 2024 23:53
@shreddedbacon shreddedbacon marked this pull request as ready for review September 2, 2024 22:18
@shreddedbacon shreddedbacon force-pushed the multiple-volumes branch 2 times, most recently from 35d83ad to f8a52fc Compare September 9, 2024 05:27
Copy link
Member

@tobybellwood tobybellwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with this - our examples using it work well, and sensible limits/guardrails in place.

@shreddedbacon shreddedbacon merged commit d2508ef into main Sep 11, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants