Skip to content
Sergei Parshev edited this page Jan 24, 2023 · 6 revisions

Aquarium Fish - is a main part of Aquarium and completely distributed heterogeneous dynamic resource management system. It's a userspace daemon that serves the resources of the hardware node pool or remote resources (like clouds).

CO: Fish lives in Aquarium

The components of the Aquarium Fish are packed to single binary for each supported OS and configuration are basically not needed, this makes the deployment process as easy as possible and allows developers to quickly run the required environment locally and check what went wrong on the CI system or to play with the pipelines on actual CI/CD Build/Release environments.

Features

  • Distributed - uses SQLite and cluster sync consensus to have no external DB dependencies
  • One binary - golang codebase to simplify integration and distribution
  • ORM - uses transparent Structure - DB - Structure translation so no need to worry about DB data much
  • REST API - simple way to communicate (Basic Auth + TLS transport included) and generated out of OpenAPI specs
  • Drivers - can work with any kind of resources (VMWare Fusion for MacOS, docker... But overall it's able to manage clouds & HW as well)
  • Simple start - just a TCP port (API) & drivers additional configs if needed
  • Modular - easy to replace components with your own implementation
  • Secure - SSL certificates and API keys to securely access the functionality
  • Built-in proxy with allowlists - for proper sandboxing of the environments, business continuity and nice load distribution

Aquarium Fish - Application parts

General usage

When cluster receives the Resource request (Application) - each node solves a task: they are tries to calculate when it will be able to provide the required resource and provides this information for the cluster to decide which one will be chosen.

Also node maintains the Resources in order to quickly respond on the request. For example cluster finds out that xcode12.2 label is in high demand right now, so some nodes can predict it and start in advance to rapidly handle the request. Still way to go - but not that hard to implement as you think.

The common usage path is (check the example scripts here):

  • Run Fish cluster - just run the required amount of nodes on the available pool of machines (or just one machine) and join them together. You can run one node as a seed and join the others to this first node - cluster will be formed automatically.
  • Create Label - labels stores the environment description, so you can be sure that the specified label is exactly what you need. Labels are immutable, but you can create another version of the label.
  • Create Application - to request the resource you need to form an application that will be reviewed by the cluster, each node will vote during the election process and some node will be elected and will provide the resource for you.
  • Monitor the Resource allocation - the election process could take some time (depends on the cluster load), so make sure you check the Application status is not went ERROR.
  • Use the Resource - usually the resource you requested will find you (in Jenkins CI Agent case, for example), but overall it depends on how you setup the cluster & configured the drivers.
  • Deallocate the Resource - when you're completed your workload execution, don't forget to deallocate the resource.

If you want to know better about the internal resources - definitely worth to read the OpenAPI spec documentation - it contains alot of useful information about the objects used by the Fish cluster.

Cluster networking

The next schema shows how the cluster interacts with each node, which interfaces are exposed and how the node are looks inside:

Aquarium Fish - Network schema