Architecture
Overview
This page describes how the role works under the hood and how it configures the managed servers. The purpose is to enable everyone to understand exactly what the role does and aid in advanced customization or troubleshooting. In practice anyone should be able to successfully use the role without ever needing to read this.
Docker compose
The role utilizes Docker Compose. Each client is defined as a service in the corresponding compose file. The compose files are templated out using Jinja2 (Ansible templating language) and are dynamically generated every time the role runs based on the defined variables. There is one Docker compose service defined per file which enables the role to "compose" the desired client mix or deploy them on their own. The files use the following naming convention:
As of writing the role comprises the following compose templates:
Docker network
Docker compose services (execution, consensus and validator) are "connected" to the same Docker network. The network is defined in each Compose file.
If you have any containers managed outside of slingnode.ethereum role (for example monitoring such as Prometheus) that you want to be able to connect to the running clients, you will need to either connect it to the same Docker network or expose the required ports to the host.
Starting the Docker compose project
The compose templates are rendered and copied to the target server location defined by the following variable:
Ansible merges the files and starts the services as a single project. Refer to Docker Compose documentation for details on using multiple compose files.
Directory structure
The role creates the following directory structure.
The location can be modified by overriding the following variable:
The exact sub-directories will depend on the deployed layers and client mix. For instance, if you deploy only execution client, the consensus and validator directories will not be created. The example below shows the directory and file layout that would exist if Geth and Lighthouse (consensus and validator) were deployed.
Volume mapping
Clients' data directories are mapped to the host directories.
For example if Geth is started with the two following flags:
The volume mapping in the Compose file is:
User accounts and groups
The role creates three user accounts and corresponding groups and one additional group with predefined UIDs and GIDs. Each container runs in the context of a dedicated user account. Additionally the execution and consensus containers are added to the "jwt_secret_access_group" that allows them to read the file containing the JWT secret.
Created users:
execution_client
execution_client
Runs execution client container
consensus_client
consensus_client
Runs consensus client container
validator_client
validator_client
Runs validator client container
jwt_secret_access_group
Grants access to JWT secret
execution_client and consensus_client users are members of the jwt_secret_access_group.
The UIDs, GIDs, user and group names can be modified using variables. See defaults/main/main.yml.
Container users
The container processes run in the context of their respective user accounts by passing UID and GID using the user Compose directive. This overrides the default user defined in the Dockerfile of the image. Since those UIDs don't exist in the containers, all writable directories must be mapped to the host.
jwt_secret_access_group
Execution and consensus client container are added to the the jwt_secret_access_group using group_add Compose directive.
Directory permissions
The container processes have read and write permissions only their own data directories. The execution and consensus processes have additional read permission to the jwt directory.
Last updated