A volume is a persistent storage device that keeps data across restarts. On
Unikraft Cloud (UKC), you can initialize a volume through an instance, or you
can create one by importing local data, either from a directory, or through a
Dockerfile-driven build.
In this guide we will create a volume, attach it to an instance (a web server), and write to it.
We will then show how to detach it, kill that instance, and attach it to a new instance, showing that what we wrote to it persisted across instances.
Finally, we will discuss how you can share volumes across instances (read-only at present).
Unikraft Cloud also supports sharing a volume across multiple instances,
currently only as a read-only mount (read-write for volume sharing is in the
works).
Setting Up the Volume
To start, let's create the volume via kraft cloud volume, with size in MBs and
name my-volume:
The command should return the volume's UUID, and you can check the operation
worked via:
kraft cloud volume list
which should output something similar to:
NAME CREATED AT SIZE ATTACHED TO STATE PERSISTENTmy-volume 15 seconds ago 100 MiB available true
Notice the ATTACHED TO field is empty as we haven't attached it to any
instances yet.
Populating the Volume with Local Data (Optional)
If you'd like to populate your empty volume with local data, you can use the
kraft cloud volume import command. For example, assuming the volume's name is
my-volume and that the data you want to import are in your my-data
directory, you would run:
from flask import Flask, send_from_directoryfrom datetime import datetimeimport osapp = Flask(__name__)file_path = "/mnt/log.txt"def initialize_file(): if not os.path.exists(file_path): with open(file_path, 'w') as log_file: log_file.write("Log file created.\n")@app.route('/')def write_to_file(): initialize_file() current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Write to file with open(file_path, 'a') as log_file: log_file.write(f"{current_datetime}\n") # Read contents of the file with open(file_path, 'r') as log_file: file_contents = log_file.read() return file_contentsif __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
On every request, this simple server will write a timestamp to a file on the
mounted persistent volume and print out the current contents of the file.
With this in place, let's start our Flask web server, create a
service for it via the -p flag, and have the
instance mount the my-volume volume we created earlier at /mnt:
NAME CREATED AT SIZE ATTACHED TO STATE PERSISTENTmy-volume 34 minutes ago 100 MiB http-python312-flask30-2h608 mounted true
Testing it
Our Python Flask server should write the time and date to the volume (more
specifically to /mnt/log.txt) each time the server's URL is accessed. To test
simply curl the URL multiple times, you should see output similar to:
To test that the data (the date and time) were properly written to the
persistent volume, let's first stop the instance, detaching the volume, and
removing the instance: