A deeper look into the Ansible playbook

When preparing a VM for the Oneprovider, you have run an Ansible playbook. Here is a short explanation of some of the more important/mysterious commands there.

File limits

    - name: Set max number of files
      lineinfile:
        regexp: soft nofile
        line: "* soft nofile 63535"
        state: present
        path: /etc/security/limits.conf
    - name: Set max number of files
      lineinfile:
        regexp: hard nofile
        line: "* hard nofile 63535"
        state: present
        path: /etc/security/limits.conf

We are increasing the maximum number of open files as Oneprovider components (such as RTransfer, Oneprovider Worker) may open a lot of files in order to work as efficiently as possible, especially if numerous clients are connected.

Disabling swappiness

    - name: Set swappiness
      lineinfile:
        regexp: vm.swappiness=
        line: vm.swappiness=0
        state: present
        path: /etc/sysctl.d/50-swappiness.conf

We are disabling RAM swappiness as this is needed for Couchbase (underlying database service) to work optimally.

Network buffers

    - name: Set net.core.wmem_max
      sysctl:
        name: net.core.wmem_max
        value: "16777216"
    - name: Set net.core.rmem_max
      sysctl:
        name: net.core.rmem_max
        value: "16777216"

RTransfer intensively uses buffering on incoming and outgoing connections — this value is set to be 2 times the size of RTransger buffers so it is working efficiently.

Disabling a potentially unsafe feature

    - name: Set kernel.unprivileged_userns_clone
      sysctl:
        name: kernel.unprivileged_userns_clone
        value: "0"

Just in case, to mitigate the exploit CVE-2023-32233.

Disabling the default Ubuntu DNS

    - name: Disable resolvconf
      systemd:
        name: systemd-resolved
        state: stopped
        enabled: no
      when: ansible_distribution == "Ubuntu"
    - name: Remove /etc/resolv.conf
      file:
        path: /etc/resolv.conf
        state: absent
    - name: Create /etc/resolv.conf
      copy:
        content: "nameserver 8.8.8.8\n"
        dest: /etc/resolv.conf

The default DNS setup for Ubuntu is known to cause issues and interfere with our services. Instead, we just use the 8.8.8.8 DNS server.

Creating the LVM volume

    - name: Create /opt/onedata
      ...
    - name: Create volume group
      ...
    - name: Create logical volume
      ...
    - name: Create filesystem
      ...
    - name: Mount /opt/onedata
      ...

An LVM is created to store the Oneprovider persistent data, allowing us to easily create live backups — to be covered in the upcoming chapter.

Before we proceed

Make sure you are in the docker group for more convenient docker command usage:

sudo usermod -aG docker $USER

Log out and in for the changes to take effect.



Ignore this step if you are already in the group.

Onedatify directory

Upon initial installation, a /opt/onedata/onedatify/ directory (on the host) was allocated for Onedatify. It contains essential files — from configurations to scripts.

~$ cd /opt/onedata/onedatify
~$ ls
config                       logs.sh
config.template              onedatify.sh
config.sh                    oneprovider_conf
console.sh                   op-panel-overlay.config
docker-compose.yml           op-worker-overlay.config
docker-compose.yml.template  storage.sh
install.sh                   support.sh
lib                          upgrade.sh

Config

The config file holds admin-supplied information about Oneprovider deployment, collected through the installation process, with default values for parameters the admin has not provided.

~$ cat config
version=onedata/oneprovider:21.02.2
zone_fqdn=demo.onedata.org
admin_password=XXXXXXXXXXXXXX
admin_email=joe@example.com

...

geo_latitude=50.07072067260742
geo_longitude=19.93099021911621

Docker Compose

The docker-compose.yml file orchestrates the setup of a Dockerized environment for the Oneprovider service, leveraging information from the config file.

~$ cat docker-compose.yml
version: '2.0'
services:
  node1.oneprovider:
    # Oneprovider Docker image version
    image: ${version}
    # dns: 8.8.8.8 # Optional, in case Docker containers have no DNS access
    container_name: onedatify-oneprovider-1  # DO NOT CHANGE! some scripts depend on that name
    # Oneprovider hostname inside a container
    hostname: "${subdomain}"
    domainname: "${domain_name}"
    ...

The volumes section plays a crucial role by specifying mappings for:

  • persistence, which enables the storage of Oneprovider runtime files between different container runs. This ensures that logs, configuration files, and database data remain accessible consistently, even between the container restarts.
  • applications configuration overrides (a detailed exploration of those will happen later).
  • access to the entire host filesystem from within the Docker container, so that /hostfs/<host_path> can be used e.g. as the mount point for imported storage.
# Mapping of volumes to Oneprovider container
volumes:
    - "/var/run/docker.sock:/var/run/docker.sock"
    # Oneprovider runtime files
    - "$persistence_volume:/volumes/persistence"
    # Oneprovider configuration override
    - "$overlay_panel_volume:/etc/op_panel/overlay.config"
    - "$overlay_worker_volume:/etc/op_worker/overlay.config"
    # The whole host filesystem - for convenience
    - "/:/hostfs"

Adding custom volume mappings is a standard approach to Oneprovider service customization (e.g. overriding config settings).

The environment section, specifically the ONEPROVIDER_CONFIG variable, serves as config for the batch deployment of the Oneprovider service.

environment:
  ...
  ONEPROVIDER_CONFIG: |
    # Cluster configuration allows to specify distribution of Oneprovider
    # components over multiple nodes - here we deploy entire service on
    # a single node
    cluster:
      domainName: "$domain_name"
      nodes:
        n1:
          hostname: "$subdomain"
          # ... (Additional node configuration details)
      managers:
        mainNode: "n1"
        nodes:
          - "n1"
      workers:
        nodes:
          - "n1"
      databases:
        # ... (Database configuration details)
      oneprovider:
        # ... (Oneprovider configuration details)
      onezone:
        # ... (Onezone registration details)

The default configuration, as shown, is structured for a single-node deployment. For more extensive deployments, additional nodes and configurations can be added following the provided structure.

For comprehensive information on available configurations and options, refer to the Onepanel API Documentation.

Application configuration

The basis for configuration are app.config read-only files you can find at each application directory in /var/lib/ after attaching yourself to the running container:

~$ docker exec -it onedatify-oneprovider-1 bash
var
└── lib
   ├── cluster_manager
   │   └── app.config
   ├── op_panel
   │   └── app.config
   └── op_worker
       └── app.config

You can use them as references for defaults in use and extensive comments explaining contained variables, but do not modify them.

You can also view them on GitHub (make sure to select branches corresponding to a specific release): cluster_manager, op_panel, and op_worker.

Notably, they are not persisted in the persistence directory (oneprovider_conf/) but are preinstalled in the container. During application startup, they are overlaid with user-supplied config files from the persistence directory.

.
├── oneprovider_conf
│   └── etc
│      ├── cluster_manager
│      │   └── config.d/
│      ├── op_panel
│      │   ├── overlay.config
│      │   └── config.d/
│      └── op_worker
│          ├── overlay.config
│          └── config.d/
├── op-panel-overlay.config
└── op-worker-overlay.config

To apply custom configurations, you have two options:

Option 1 — use config.d application directory. Any file matching *.config placed in this directory will be read on service startup. Files are ordered alphabetically, with later files overriding values from earlier. Additionally, the use of the config.d directory is recommended when you have sensitive data, such as secrets, in the configuration. Placing such settings in a separate file allows excluding it from version control systems like Git.

As an exercise, upload a ~10MB file to your space. Download it and note the speed. Next, create a custom configuration for op_worker download parameters, restart the service and once again try to download the file.

~$ sudo vi /opt/onedata/onedatify/oneprovider_conf/etc/op_worker/config.d/download.config
[
    {op_worker, [
        {max_download_buffer_size, 1},
        {default_download_read_block_size, 1}
    ]}
].
~$ onedatify restart

Option 2 — use the overlay.config file. Variables set in this file will override the values from the files in the config.d/ directory. This approach is simpler and recommended for users who do not have a complex configuration setup.

As an exercise, overwrite op-worker-overlay.config, restart the service and once again try to download the file.

~$ sudo vi /opt/onedata/onedatify/op-worker-overlay.config
[
    {op_worker, [
        {max_download_buffer_size, 1048576},
        {default_download_read_block_size, 1048576}
    ]}
].
~$ onedatify stop
~$ onedatify start

Next chapter:

Oneprovider maintenance — practice