epam / cloud-pipeline

Cloud agnostic genomics analysis, scientific computation and storage platform
https://cloud-pipeline.com
Apache License 2.0
146 stars 59 forks source link

Admins shall be able to manage persistent cluster nodes #841

Open sidoruka opened 4 years ago

sidoruka commented 4 years ago

Background At the moment, Cloud Pipeline allows controlling the number of persistent compute nodes in the cluster. I.e. a certain number (cluster.min.size) of the nodes of a specified size (cluster.instance.type/cluster.instance.hdd) will be always available in the cluster (even if there is no workload). This is useful to speed up the compute instances creation process (as the nodes are already up and running).

Moreover, we need to make this mechanism a bit more flexible.

Approach

SilinPavel commented 4 years ago

The next realization of this issue is proposed: 1) New entity NodeDescription introduced:

NodeDescription:

    Long id

    \\ set of requirements for node 
    RunInstance instance 

    int numberOfInstances

    \\ Start or Stop
    Action

2) When Admin create schedule for specific instance type with disk size, new NodeDescription created and persisted to DB

3) NodeDescription.id is used as schedulableId in RunSchedule to be able to schedule action

4) New type of Job NodeJob is implementeed

4) New field Queue<NodeDescription> freeNodeActions is added, this field will be shared between Autoscaler and NodeJob

5) NodeJob simply populate this queue so many times how specified in NodeDescription

Autoscaler works with this queue in the following manner:

void handleNodeActions() {
    NodeDescription nd = freeNodeActions.pop()
    switch (nd.action) {
        case Start:
            for (i = 0; i < nd.numberOfInstances; i++) {
                startNode(nd.runInstance, nd.id)
            }
        case Stop:
            for (i = 0; i < nd.numberOfInstances; i++) {
                markNodesForTerination(nd.id)
            }
        default:
            throw new IlligalArgumentEx
    }

    terminateAllMarkedNodeIfPossible()
}

In method startNode we will create new node, if it is possible (f.e. if maxNodeCount > currentClusterSize) and mark it with NodeDescription id

In method markNodesForTerination all nodes with specified NodeDescription.id will be marked with tag readyToTerminate

And in method terminateAllMarkedNodeIfPossible all nodes with readyToTerminate tag will terminated if it possible (if no run currently running on that node)

This approach with marking node solves the problem when we should kill a node due to schedule but it still working with some run, in our case it will be terminated as soon as it done with run (if it not possible to do it right now, it will be done on the next step of autoscaler loop)

mzueva commented 4 years ago

Usage of scheduled approach may not cover all the requirements to persistent node management, so I'd suggest to implement a new functionality for this.

Approach

Cluster size management

A new entity PersistentNode is added with the following fields:

Autoscaler changes

Scale up:

Scale down:

Free (Persistent) nodes handling

mzueva commented 3 years ago

@sidoruka server part backported to release/0.16

NShaforostov commented 3 years ago

Test cases were created by #1929 and located here.

NShaforostov commented 3 years ago

Docs were added via #1516.