Volumes

Introduction

Bunnyshell enables you to define persistent volumes and attach them to nodes/pods using the Volumes key. A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes.
It is a resource in the cluster just like a node is a cluster resource. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual Pod that uses the PV. Read more about Volumes on the official Kubernetes documentation platform.

Types of volumes

There are two types of volumes users can define in Bunnyshell:
  • Disk volumes: persistent volumes with ReadWriteOnce. Such volumes can be attached to a single Node.
  • Network volumes: persistent volumes with ReadWriteMany. Such volumes can be attached to multiple Nodes.

Requirements

Disk and network volumes

  • Are persistent
  • Can have configurable sizes and names
  • Support subpaths on mount
Volumes that are not claimed by anyone will be removed.
For all persistent volumes, the file mode will be 0777. File modes are handled by init containers. Each pod has an init container that modifies permissions for all volumes.
Before the pod container starts, the init container executes a chown 0777 on all those volumes.

Specifications

A Volumes key may be added at both the environment level and the component level. Below we will list the volumes for each of the cases.

Environment level

  • name: the name of the volume. This field is mandatory;
  • size: the size of the volume. This field is mandatory;
  • type: the volume type mapped to Kubernetes cloud volume types. The following options are available:
    • disk: can be attached to a single Node;
    • network: can be attached to multiple Nodes.
Volumes are isolated at the environment level. This means that if two env.yaml configs declare volumes with the same name, Bunnyshell will add the unique ID of their respective environments to their name, making them unique.

Component level

At the component level, the Volumes property will contain claims to volumes defined at the environment level. It contains the following properties:
  • name: the name of the volume claimed. This field is mandatory;
  • mount: the path where to mount the volume in the component. This field is mandatory;
  • subPath: Path of what to mount into the component.

Validations and constraints

Environment level

  • Volume names must be unique. Two volumes can not have the same name;
  • The name must consist of lower case alphanumeric characters. It can also contain hyphens -, but it must start and end with an alphanumeric character (e.g. 123-abc).
  • The volume type must be either disk, or network;
  • The volume size must be greater than zero (any float number is accepted);
  • The volume size syntax must be composed of two (case sensitive) parts : float and unit. Unit is a memory unit like Gi. 'KB', 'MB', 'GB', 'TB', 'b', 'Gi';
  • An environment volume must be used by a container, otherwise Bunnyshell will show errors.

Component level

  • The name must belong to one of the volumes declared at the environment level, otherwise Bunnyshell will show errors;
  • The mount field must include a directory path where to mount the volume, in linux format (e.g. /var/mnt/vol1)
  • The name must consist of lower case alphanumeric characters. It can also contain hyphens -, but it must start and end with an alphanumeric character (e.g. 123-abc).
  • Two volumes declared at the component level can not be mounted in the same path. The mount path must be unique in list.

Docker-compose import

All volumes declared in docker-compose will be interpreted as persistent volumes and will have a default size of 1Gi after parsing. These volumes can be found at environment level (declared) or requested by components, pods, init containers or sidecar containers.
The volumes section from docker-compose is not parsed and interpreted.
Here's an example of a volume declared in docker-compose.
services:
nginx-01:
image: nginx
volumes:
- database_volume
And this is how it will be transformed in env.yaml.
kind:...
...
components:
-
name: nginx
volumes:
-
name: database_volume
mount: /var/db
volumes:
-
name: database_volume
type: disk
size: 1Gi

Conversions from Docker-compose

  • Bunnyshell ignores volumes that are not used by any services (root directive identation 0 in docker-compose.yam file).
  • Bunnyshell ignores bind and tmpfs Volumes, as well as any local bind that does not use a Volume defined under the global key Volumes.
  • Volume names will be random values when only the target is defined, as a string.
  • After a Storage Class is added in a cluster that was already connected to Bunnyshell, the user must wait until the cluster is verified to determine whether or not a storage class exists.
  • If a volume is attached to several separate services in Docker-compose, or if it is mounted several times inside the same service, it will be migrated as a network volume.
  • The default size is 1Gi.
  • When adding an app that comes with a Volume name already found inside the environment, a random string will be added to the Volume name to make it unique.

Example Manifest

# all volumes are persistent
# if you don't need persistance, don't use a mount path
# - the only thing that might not make sense here, is breaking out of the container resource pool
# - I.E. backend php with 1GB disk space having an external mount of 5G
volumes:
-
type: network
# means ReadWriteMany
name: logs-all
size: 10Gi
-
type: disk
# means ReadWriteOnce
# passes validation if used by only 1 ServiceComponent
# passes validation if used by any Init/Sidecar
name: data-mysql
size: 3Gi
components:
-
name: mysql
volumes:
# now we have a persistent database
# what we lack is a way to "kickoff" the database
- name: data-mysql
mountPath: /var/lib/mysql
pod:
init_container:
# this init_container needs to:
# 1. be able to init mysql data
# 2. detect if init has already took place
# 3. not force the volume to become a network volume
- name: init-mysql-data
mounts:
- name: data-mysql
mountPath: /var/lib/mysql
-
name: nginx
volumes:
- name: logs-all
mount: /var/log/nginx
subPath: /nginx
-
name: monitor
volumes:
- name: logs-all
mount: /opt/logs
pod:
sidecar_container:
- name: log-rotate
volumes:
- name: logs-all
mountPath: /opt/logs
Copy link
On this page
Introduction
Types of volumes
Requirements
Disk and network volumes
Specifications
Environment level
Component level
Validations and constraints
Docker-compose import
Conversions from Docker-compose
Example Manifest