[Documentation](../../README.md#documentation) → Installation → S3 for Vitastor ----- [Читать на русском](s3.ru.md) # S3 for Vitastor The moment has come - Vitastor S3 implementation based on Zenko CloudServer is released. ## Highlights - Zenko CloudServer is implemented in node.js. - Object metadata is stored in MongoDB. - Modified Zenko CloudServer version is used for Vitastor. It is slightly different from the original, has an optimised build and unneeded dependencies are stripped off. - Object data is stored in Vitastor block volumes, but the volume metadata is stored in the same MongoDB, not in Vitastor etcd. - Objects are written to volumes sequentially one after another. The space is allocated with rounding to the sector size (4 KB), so each object takes at least 4 KB. - An important property of such storage scheme is that small objects aren't chunked into parts in Vitastor EC N+K pools and thus don't require reads from all N disks when downloading. - Deleted objects are marked as deleted, but the space is only actually freed during asynchronously executed "defragmentation" process. Defragmentation runs automatically in the background when a volume reaches configured amount of "garbage" (20% by default). Defragmentation copies actual objects to new volume(s) and then removes the old volume. Defragmentation can be configured in locationConfig.json. ## Plans for future development - User account storage in the DB instead of a static file. Original Zenko uses a separate closed-source "Scality Vault" service for it, that's why we use a static file for now. - More detailed documentation. - Support for other (and faster) key-value DBMS for object metadata storage. - Other performance optimisations, for example, related to the used hash function - MD5 used for Amazon compatibility purposes is relatively slow. - Object Lifecycle support. There is a Lifecycle implementation for Zenko called [Backbeat](https://github.com/scality/backbeat) but it's not adapted for Vitastor yet. - Quota support. Original Zenko uses a separate "SCUBA" service for quotas, but it's also proprietary and not available publicly. ## Installation In a few words: - Install MongoDB, create a user for S3 metadata DB. - Create a Vitastor pool for S3 data. - Download and setup the Docker container `vitalif/vitastor-zenko`. ### Setup MongoDB You can setup MongoDB yourself, following the [MongoDB manual](https://www.mongodb.com/docs/manual/installation/). Or you can follow the instructions below - it describes a simple example of MongoDB setup in Docker (through docker-compose) with 3 replicas. 1. On each host, create a file `docker-compose.yml` with the content listed below. Replace `` with your future mongodb administrator password, and optionally replace `0.0.0.0` with `localhost,`. It's recommended to either use a private IP or [setup TLS](https://www.mongodb.com/docs/manual/tutorial/configure-ssl/) afterwards. ``` version: '3.1' services: mongo: container_name: mongo image: mongo:7-jammy restart: always environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: network_mode: host volumes: - ./keyfile:/opt/keyfile - ./mongo-data/db:/data/db - ./mongo-data/configdb:/data/configdb entrypoint: /bin/bash -c command: [ "chown mongodb /opt/keyfile && chmod 600 /opt/keyfile && . /usr/local/bin/docker-entrypoint.sh mongod --replSet rs0 --keyFile /opt/keyfile --bind_ip 0.0.0.0" ] ``` 2. Generate a shared cluster key using `openssl rand -base64 756 > ./keyfile` and copy that `keyfile` to all hosts. 3. Start MongoDB on all hosts with `docker compose up -d mongo`. 4. Enter Mongo Shell with `docker exec -it mongo mongosh -u root -p localhost/admin` and execute the following command (replace IP addresses `10.10.10.{1,2,3}` with your host IPs): `rs.initiate({ _id: 'rs0', members: [ { _id: 1, host: '10.10.10.1:27017' }, { _id: 2, host: '10.10.10.2:27017' }, { _id: 3, host: '10.10.10.3:27017' } ] })` 5. Stay in Mongo Shell and create a user for the future S3 database: `db.createUser({ user: 's3', pwd: '', roles: [ { role: 'readWrite', db: 's3' }, { role: 'dbAdmin', db: 's3' }, { role: 'readWrite', db: 'vitastor' }, { role: 'dbAdmin', db: 'vitastor' } ] })` ### Setup Vitastor Create a pool in Vitastor for S3 object data, for example: `vitastor-cli create-pool --ec 2+1 -n 512 s3-data --used_for_app s3:standard` The `--used_for_app` options works as fool-proofing and prevents you from accidentally creating a regular block volume in the S3 pool and overwriting some S3 data. Also it hides inode space statistics from Vitastor etcd. Retrieve the ID of your pool with `vitastor-cli ls-pools s3-data --detail`. ### Setup Vitastor S3 1. Add the following lines to `docker-compose.yml` (instead of `network_mode: host`, you can use `ports: [ "8000:8000", "8002:8002" ]`): ``` zenko: container_name: zenko image: vitalif/vitastor-zenko restart: always security_opt: - seccomp:unconfined ulimits: memlock: -1 network_mode: host volumes: - /etc/vitastor:/etc/vitastor - /etc/vitastor/s3:/conf ``` 2. Download Docker image: `docker pull vitalif/vitastor-zenko` 3. Extract configuration file examples from the Docker image: ``` docker run --rm -it -v /etc/vitastor:/etc/vitastor -v /etc/vitastor/s3:/conf vitalif/vitastor-zenko configure.sh ``` 4. Edit configuration files in `/etc/vitastor/s3/`: - `config.json` - common settings. - `authdata.json` - user accounts and access keys. - `locationConfig.json` - S3 storage class list with placement settings. Note: it actually contains storage classes (like STANDARD, COLD, etc) instead of "locations" (zones like us-east-1) as in the original Zenko CloudServer. - Put your MongoDB connection data into `config.json` and `locationConfig.json`. - Put your Vitastor pool ID into `locationConfig.json`. - For now, the complete list of Vitastor backend settings is only available [in the code](https://git.yourcmc.ru/vitalif/zenko-arsenal/src/branch/master/lib/storage/data/vitastor/VitastorBackend.ts#L94). ### Start Zenko Start the S3 server with: ``` docker run --restart always --security-opt seccomp:unconfined --ulimit memlock=-1 --network=host \ -v /etc/vitastor:/etc/vitastor -v /etc/vitastor/s3:/conf --name zenko vitalif/vitastor-zenko ``` If you use default settings, Zenko CloudServer starts on port 8000. The default access key is `accessKey1` with a secret key of `verySecretKey1`. Now you can access your S3 with, for example, [s3cmd](https://s3tools.org/s3cmd): ``` s3cmd --access_key=accessKey1 --secret_key=verySecretKey1 --host=http://localhost:8000 mb s3://testbucket ``` Or even mount it with [GeeseFS](https://github.com/yandex-cloud/geesefs): ``` AWS_ACCESS_KEY_ID=accessKey1 \ AWS_SECRET_ACCESS_KEY=verySecretKey1 \ geesefs --endpoint http://localhost:8000 testbucket mountdir ``` ## Author & License - [Zenko CloudServer](https://s3-server.readthedocs.io/en/latest/) author is Scality, licensed under [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0) - [Vitastor](https://git.yourcmc.ru/vitalif/vitastor/) and Zenko Vitastor backend author is Vitaliy Filippov, licensed under [VNPL-1.1](https://git.yourcmc.ru/vitalif/vitastor/src/branch/master/VNPL-1.1.txt) (a "network copyleft" license based on AGPL/SSPL, but worded in a better way) - Vitastor S3 repository: https://git.yourcmc.ru/vitalif/zenko-cloudserver-vitastor - Vitastor S3 backend code: https://git.yourcmc.ru/vitalif/zenko-arsenal/src/branch/master/lib/storage/data/vitastor/VitastorBackend.ts