Skip to content

Latest commit

 

History

History
224 lines (183 loc) · 8.04 KB

README.md

File metadata and controls

224 lines (183 loc) · 8.04 KB

catapult

Catapult is a mesos framework SDK that abstracts the scheduler and executor interfaces into user friendly objects (with default callback implementations), and handles persistent storage for application state using apache zookeeper. Catapult allows you to turn your application into an application as a service letting you to spin 100s or 1000s of instances of your application. And the best part is, you don't have to worry about any of the multitenantcy logic (although you can still impose specific scheduling constraints if you want to).

Catapult has 3 major components. The SchedulerApp which is an object that handles application level orchestration logic. Mainly this object will be used to deploy SchedulerNodes. SchedulerNodes are where the meat of the orchestration logic is. SchedulerNodes will handle callbacks such as "running", "failed", or "message" which are all ultimately generated by the ExecutableApp objects. Finally the ExecutableApp object is what's physically running on each node. This is where you will start your database, kick off some jobs, or start some node of some proprietary application.

Catapult provides high availability / failover support by using apache zookeeper. You can deploy Catapult through Marathon OR (if you don't want a dependency on Marathon) you can deploy a cluster of systemd Catapult instances.

Build Requirements

  • java
  • maven

Install

Catapult is not currently hosted as a maven artifact so you'll need to download the source and built it manually :(. During the install phase of the build the jar file will be installed into your local maven repo.

git clone https://github.com/timbouvier/catapult.git
cd catapult
make install

After the install completes you can then import the catapult library to your project using a maven dependency.

<dependency>
   <groupId>com.tbouvier.mesos</groupId>
   <artifactId>sdk</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

Usage

The two main components to any mesos framework are the scheduler and executor. The scheduler is what orchestrates the application deployment and event handling, while the executor is where the application node physically runs. Catapult's scheduler and executor components each are made up of a few sub-components detailed below.

  • Scheduler
    • SchedulerNode
      • An object you will extend to implement any node level logic and event processing
    • SchedulerApp
      • An object you will extend to implement any app level logic and event processing
    • MesosAppListener
      • An interface you will implement to handle any framework level logic and event processing
  • Executor
    • ExecutableApp
      • An interface you will implement so the catapult library can start your application node

Create ExecutableApp

public class MyExecutableApp implements ExecutableApp {

  @Override
  public void restart(){
    ...
  }
  
  @Override
  public int getExitStatus() {
    ...
  }
  
  @Override
  public void message(AppExecutor appExecutor, byte[] message){
    ...
  }
  
  @Override
  public void kill(){
    ...
  }
  
  @Override
  public void run(AppExecutor executor){
    ...
  }
}

Create Scheduler Node Listener

import com.tbouvier.scheduler.Protos;

public class MyNode extends SchedulerNode {
   
   public MyNode(Protos.SchedulerNodeInfo nodeInfo){
      /*initialize parent obj with nodeInfo*/
      super(nodeInfo);
   }

   @Override
   public void failed(AppDriver appDriver){
      /*default implementation will relaunch node*/
   }
   
   @Override
   public void running(AppDriver appDriver){
     /*default implementation does nothing*/
   }
   
   @Override
   public void finished(AppDriver appDriver){
    /*default implementation does nothing*/
   }
   
   @Override
   public void killed(AppDriver appDriver){
     /*default implementation relaunches node*/
   }
   
   @Override 
   public void message(AppDriver appDriver, byte[] data){
     /*default implementation drops message*/
   }
}

The schedulerNode callbacks are events for pretty much what they look like they're events for. The message callback is a communication channel between the SchedulerNode and the ExecutableApp (what's running on the physical node).

Create Scheduler Application Listener

public class MyApplication extends SchedulerApp {
  
   public MyApplication(){
      super("my-app-name");
   }
  
   @Override
   public void initialized(AppDriver appDriver, Protos.AppID appID){
   
     /*containerLite info is a user friendly way of spinning docker containers + volume api supports
       local host mounts as well as docker volumes*/
     Protos.ContainerLiteInfo.Builder containerLiteInfo = Protos.ContainerLiteInfo.newBuilder()
                .setDockerImage("executor-docker-image")
                .addVolumes(Protos.SchedulerVolume.newBuilder()
                        .setHostMountPoint("mesos-shared-lib-path")
                        .setContainerMountPoint("mesos-shared-lib-path")
                        .setMode(org.apache.mesos.Protos.Volume.Mode.RO)
                        .build())
   
     /*create nodeInfo*/
     Protos.SchedulerNodeInfo nodeInfo = Protos.SchedulerNodeInfo.newBuilder()
                .setSchedulerContainer( Protos.SchedulerContainer.newBuilder()
                        .setName("node-name")
                        .setCpus(1.0)
                        .setMemory(1024)
                        .setExecutor(true)//if this is a custom executor or not
                        .setContainerLiteInfo(containerLiteInfo.build())
                        .build())
                .build();
   
     /*Start launching nodes*/
     MyNode node = new MyNode(nodeInfo);
     appDriver.launchNode(node);
   }
   
   @Override
   public void initFailed(){
    /*
    no driver supplied because it failed to create it
    Most common reason for this to happen is if zookeeper 
    or mesos environment variables are misconfigured
    */
   }
}

There are additional methods that can be overriden but the default implementations are almost always what you want. For instance, "message" can be overriden but its default implementation delivers the message to the schedulerNode object to which it belongs.

Create Main Framework Listener

public class MyFrameworkListener implements MesosAppListener {
  
  public void disconnected(AppFramework appFramework){
    ...
  }
  
  public void connected(AppFramework appFramework){
    /*start deploying apps!*/
    MyApplication app = new MyApplication();
    appFramework.register(app);
  }
  
  public void applicationFailed(AppFramework appFramework){
    ...
  }
}

Once the connected callback fires you can safely assume the library is initialized an ready to receive API callins.

Putting it All Together

Scheduler Main
import com.tbouvier.mesos.MesosAppFramework;
import com.tbouvier.mesos.scheduler.Protos;

public class SchedulerMain {

  public static void main(String[] args){
    Protos.SchedulerConfig schedulerConfig = Protos.SchedulerConfig.newBuilder()
             .setZooKeeperInfo(Protos.ZookeeperInfo.newBuilder()
                     .setAddress("zk://my-zookeeper-ip-list")
                     .setRootNode("framework-root-zk-node-name")
                      .build())
             .setMesosInfo(Protos.MesosInfo.newBuilder()
                     .setAddress("zk://my-zookeeper-ip-list/mesos/")
                     .build())
             .setFrameworkName("my-framework")
             .build();
    
    MyFrameworkListener myFramework = new MyFrameworkListener();
    new MesosAppFramework(schedulerConfig, myFramework).run();
  }
}
Executor Main
public class ExecutorMain {

  public static void main(String[] args){
     new MesosApplicationFrameworkExecutor(new MyExecutableApp()).run();
  }
}

After you familiarize yourself with the general architecture of catapult, please checkout the full example which uses dropwizard for the app deployer API endpoints, and docker containers for the scheduler, executor components!

Deployment Requirements

  • Apache Mesos
  • Apache Zookeeper