| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <title>Apache Mesos - Framework Development Guide</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| |
| <meta property="og:locale" content="en_US"/> |
| <meta property="og:type" content="website"/> |
| <meta property="og:title" content="Apache Mesos"/> |
| <meta property="og:site_name" content="Apache Mesos"/> |
| <meta property="og:url" content="http://mesos.apache.org/"/> |
| <meta property="og:image" content="http://mesos.apache.org/assets/img/mesos_logo_fb_preview.png"/> |
| <meta property="og:description" |
| content="Apache Mesos abstracts resources away from machines, |
| enabling fault-tolerant and elastic distributed systems |
| to easily be built and run effectively."/> |
| |
| <meta name="twitter:card" content="summary"/> |
| <meta name="twitter:site" content="@ApacheMesos"/> |
| <meta name="twitter:title" content="Apache Mesos"/> |
| <meta name="twitter:image" content="http://mesos.apache.org/assets/img/mesos_logo_fb_preview.png"/> |
| <meta name="twitter:description" |
| content="Apache Mesos abstracts resources away from machines, |
| enabling fault-tolerant and elastic distributed systems |
| to easily be built and run effectively."/> |
| |
| <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> |
| <link rel="alternate" type="application/atom+xml" title="Apache Mesos Blog" href="/blog/feed.xml"> |
| <link href="../../../assets/css/main.css" media="screen" rel="stylesheet" type="text/css" /> |
| |
| |
| |
| <!-- Google Analytics Magic --> |
| <script type="text/javascript"> |
| var _gaq = _gaq || []; |
| _gaq.push(['_setAccount', 'UA-20226872-1']); |
| _gaq.push(['_setDomainName', 'apache.org']); |
| _gaq.push(['_trackPageview']); |
| |
| (function() { |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
| })(); |
| </script> |
| |
| </head> |
| <body> |
| <!-- magical breadcrumbs --> |
| <div class="topnav"> |
| <div class="container"> |
| <ul class="breadcrumb"> |
| <li> |
| <div class="dropdown"> |
| <a data-toggle="dropdown" href="#">Apache Software Foundation <span class="caret"></span></a> |
| <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> |
| <li><a href="http://www.apache.org">Apache Homepage</a></li> |
| <li><a href="http://www.apache.org/licenses/">License</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> |
| <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| <li><a href="http://www.apache.org/security/">Security</a></li> |
| </ul> |
| </div> |
| </li> |
| |
| <li><a href="http://mesos.apache.org">Apache Mesos</a></li> |
| |
| |
| <li><a href="/documentation |
| /">Documentation |
| </a></li> |
| |
| |
| </ul><!-- /.breadcrumb --> |
| </div><!-- /.container --> |
| </div><!-- /.topnav --> |
| |
| <!-- navbar excitement --> |
| <div class="navbar navbar-default navbar-static-top" role="navigation"> |
| <div class="container"> |
| <div class="navbar-header"> |
| <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#mesos-menu" aria-expanded="false"> |
| <span class="sr-only">Toggle navigation</span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </button> |
| <a class="navbar-brand" href="/"><img src="/assets/img/mesos_logo.png" alt="Apache Mesos logo"/></a> |
| </div><!-- /.navbar-header --> |
| |
| <div class="navbar-collapse collapse" id="mesos-menu"> |
| <ul class="nav navbar-nav navbar-right"> |
| <li><a href="/gettingstarted/">Getting Started</a></li> |
| <li><a href="/blog/">Blog</a></li> |
| <li><a href="/documentation/latest/">Documentation</a></li> |
| <li><a href="/downloads/">Downloads</a></li> |
| <li><a href="/community/">Community</a></li> |
| </ul> |
| </div><!-- /#mesos-menu --> |
| </div><!-- /.container --> |
| </div><!-- /.navbar --> |
| |
| <div class="content"> |
| <div class="container"> |
| <div class="row-fluid"> |
| <div class="col-md-4"> |
| <h4>If you're new to Mesos</h4> |
| <p>See the <a href="/gettingstarted/">getting started</a> page for more |
| information about downloading, building, and deploying Mesos.</p> |
| |
| <h4>If you'd like to get involved or you're looking for support</h4> |
| <p>See our <a href="/community/">community</a> page for more details.</p> |
| </div> |
| <div class="col-md-8"> |
| <h1>Framework Development Guide</h1> |
| |
| <p>In this document we refer to Mesos applications as “frameworks”.</p> |
| |
| <p>See one of the example framework schedulers in <code>MESOS_HOME/src/examples/</code> to |
| get an idea of what a Mesos framework scheduler and executor in the language |
| of your choice looks like. <a href="https://github.com/mesosphere/RENDLER">RENDLER</a> |
| provides example framework implementations in C++, Go, Haskell, Java, Python |
| and Scala.</p> |
| |
| <h2>Create your Framework Scheduler</h2> |
| |
| <p>If you are writing a scheduler against Mesos 1.0 or newer, it is recommended |
| to use the new <a href="/documentation/latest/./scheduler-http-api/">HTTP API</a> to talk to Mesos.</p> |
| |
| <p>If your framework needs to talk to Mesos 0.28.0 or older, you can write the |
| scheduler in C++, Java/Scala, or Python. Your framework scheduler should inherit |
| from the <code>Scheduler</code> class (see API below). Your scheduler should create a SchedulerDriver |
| (which will mediate communication between your scheduler and the Mesos master) and then call |
| <code>SchedulerDriver.run()</code>.</p> |
| |
| <h3>Scheduler API</h3> |
| |
| <p>Callback interface to be implemented by framework schedulers.</p> |
| |
| <p>Declared in <code>MESOS_HOME/include/mesos/scheduler.hpp</code></p> |
| |
| <pre><code class="{.cpp}">/* |
| * Invoked when the scheduler successfully registers with a Mesos |
| * master. A unique ID (generated by the master) used for |
| * distinguishing this framework from others and `MasterInfo` |
| * with the ip and port of the current master are provided as arguments. |
| */ |
| virtual void registered( |
| SchedulerDriver* driver, |
| const FrameworkID& frameworkId, |
| const MasterInfo& masterInfo); |
| |
| /* |
| * Invoked when the scheduler re-registers with a newly elected Mesos master. |
| * This is only called when the scheduler has previously been registered. |
| * `MasterInfo` containing the updated information about the elected master |
| * is provided as an argument. |
| */ |
| virtual void reregistered( |
| SchedulerDriver* driver, |
| const MasterInfo& masterInfo); |
| |
| /* |
| * Invoked when the scheduler becomes "disconnected" from the master |
| * (e.g., the master fails and another is taking over). |
| */ |
| virtual void disconnected(SchedulerDriver* driver); |
| |
| /* |
| * Invoked when resources have been offered to this framework. A |
| * single offer will only contain resources from a single slave. |
| * Resources associated with an offer will not be re-offered to |
| * _this_ framework until either (a) this framework has rejected |
| * those resources (see SchedulerDriver::launchTasks) or (b) those |
| * resources have been rescinded (see Scheduler::offerRescinded). |
| * Note that resources may be concurrently offered to more than one |
| * framework at a time (depending on the allocator being used). In |
| * that case, the first framework to launch tasks using those |
| * resources will be able to use them while the other frameworks |
| * will have those resources rescinded (or if a framework has |
| * already launched tasks with those resources then those tasks will |
| * fail with a TASK_LOST status and a message saying as much). |
| */ |
| virtual void resourceOffers( |
| SchedulerDriver* driver, |
| const std::vector<Offer>& offers); |
| |
| /* |
| * Invoked when an offer is no longer valid (e.g., the slave was |
| * lost or another framework used resources in the offer). If for |
| * whatever reason an offer is never rescinded (e.g., dropped |
| * message, failing over framework, etc.), a framework that attempts |
| * to launch tasks using an invalid offer will receive TASK_LOST |
| * status updates for those tasks (see Scheduler::resourceOffers). |
| */ |
| virtual void offerRescinded(SchedulerDriver* driver, const OfferID& offerId); |
| |
| /* |
| * Invoked when the status of a task has changed (e.g., a slave is |
| * lost and so the task is lost, a task finishes and an executor |
| * sends a status update saying so, etc). If implicit |
| * acknowledgements are being used, then returning from this |
| * callback _acknowledges_ receipt of this status update! If for |
| * whatever reason the scheduler aborts during this callback (or |
| * the process exits) another status update will be delivered (note, |
| * however, that this is currently not true if the slave sending the |
| * status update is lost/fails during that time). If explicit |
| * acknowledgements are in use, the scheduler must acknowledge this |
| * status on the driver. |
| */ |
| virtual void statusUpdate(SchedulerDriver* driver, const TaskStatus& status); |
| |
| /* |
| * Invoked when an executor sends a message. These messages are best |
| * effort; do not expect a framework message to be retransmitted in |
| * any reliable fashion. |
| */ |
| virtual void frameworkMessage( |
| SchedulerDriver* driver, |
| const ExecutorID& executorId, |
| const SlaveID& slaveId, |
| const std::string& data); |
| |
| /* |
| * Invoked when a slave has been determined unreachable (e.g., |
| * machine failure, network partition). Most frameworks will need to |
| * reschedule any tasks launched on this slave on a new slave. |
| * |
| * NOTE: This callback is not reliably delivered. If a host or |
| * network failure causes messages between the master and the |
| * scheduler to be dropped, this callback may not be invoked. |
| */ |
| virtual void slaveLost(SchedulerDriver* driver, const SlaveID& slaveId); |
| |
| /* |
| * Invoked when an executor has exited/terminated. Note that any |
| * tasks running will have TASK_LOST status updates automagically |
| * generated. |
| * |
| * NOTE: This callback is not reliably delivered. If a host or |
| * network failure causes messages between the master and the |
| * scheduler to be dropped, this callback may not be invoked. |
| */ |
| virtual void executorLost( |
| SchedulerDriver* driver, |
| const ExecutorID& executorId, |
| const SlaveID& slaveId, |
| int status); |
| |
| /* |
| * Invoked when there is an unrecoverable error in the scheduler or |
| * scheduler driver. The driver will be aborted BEFORE invoking this |
| * callback. |
| */ |
| virtual void error(SchedulerDriver* driver, const std::string& message); |
| </code></pre> |
| |
| <h3>Scheduler Driver API</h3> |
| |
| <p>The Scheduler Driver is responsible for managing the scheduler’s lifecycle |
| (e.g., start, stop, or wait to finish) and interacting with Mesos Master |
| (e.g., launch tasks, kill tasks, etc.).</p> |
| |
| <p>Note that this interface is usually not implemented by a framework itself, |
| but it describes the possible calls a framework scheduler can make to |
| interact with the Mesos Master.</p> |
| |
| <p>Please note that usage of this interface requires an instantiated |
| MesosSchedulerDiver. |
| See <code>src/examples/test_framework.cpp</code> for an example of using the |
| MesosSchedulerDriver.</p> |
| |
| <p>Declared in <code>MESOS_HOME/include/mesos/scheduler.hpp</code></p> |
| |
| <pre><code class="{.cpp}">// Starts the scheduler driver. This needs to be called before any |
| // other driver calls are made. |
| virtual Status start(); |
| |
| // Stops the scheduler driver. If the 'failover' flag is set to |
| // false then it is expected that this framework will never |
| // reconnect to Mesos. So Mesos will unregister the framework and |
| // shutdown all its tasks and executors. If 'failover' is true, all |
| // executors and tasks will remain running (for some framework |
| // specific failover timeout) allowing the scheduler to reconnect |
| // (possibly in the same process, or from a different process, for |
| // example, on a different machine). |
| virtual Status stop(bool failover = false); |
| |
| // Aborts the driver so that no more callbacks can be made to the |
| // scheduler. The semantics of abort and stop have deliberately been |
| // separated so that code can detect an aborted driver (i.e., via |
| // the return status of SchedulerDriver::join, see below), and |
| // instantiate and start another driver if desired (from within the |
| // same process). Note that 'stop()' is not automatically called |
| // inside 'abort()'. |
| virtual Status abort(); |
| |
| // Waits for the driver to be stopped or aborted, possibly |
| // _blocking_ the current thread indefinitely. The return status of |
| // this function can be used to determine if the driver was aborted |
| // (see mesos.proto for a description of Status). |
| virtual Status join(); |
| |
| // Starts and immediately joins (i.e., blocks on) the driver. |
| virtual Status run(); |
| |
| // Requests resources from Mesos (see mesos.proto for a description |
| // of Request and how, for example, to request resources from |
| // specific slaves). Any resources available are offered to the |
| // framework via Scheduler::resourceOffers callback, asynchronously. |
| virtual Status requestResources(const std::vector<Request>& requests); |
| |
| // Launches the given set of tasks. Any remaining resources (i.e., |
| // those that are not used by the launched tasks or their executors) |
| // will be considered declined. Note that this includes resources |
| // used by tasks that the framework attempted to launch but failed |
| // (with `TASK_ERROR`) due to a malformed task description. The |
| // specified filters are applied on all unused resources (see |
| // mesos.proto for a description of Filters). Available resources |
| // are aggregated when multiple offers are provided. Note that all |
| // offers must belong to the same slave. Invoking this function with |
| // an empty collection of tasks declines offers in their entirety |
| // (see Scheduler::declineOffer). |
| virtual Status launchTasks( |
| const std::vector<OfferID>& offerIds, |
| const std::vector<TaskInfo>& tasks, |
| const Filters& filters = Filters()); |
| |
| // Kills the specified task. Note that attempting to kill a task is |
| // currently not reliable. If, for example, a scheduler fails over |
| // while it was attempting to kill a task it will need to retry in |
| // the future. Likewise, if unregistered / disconnected, the request |
| // will be dropped (these semantics may be changed in the future). |
| virtual Status killTask(const TaskID& taskId); |
| |
| // Accepts the given offers and performs a sequence of operations on |
| // those accepted offers. See Offer.Operation in mesos.proto for the |
| // set of available operations. Any remaining resources (i.e., those |
| // that are not used by the launched tasks or their executors) will |
| // be considered declined. Note that this includes resources used by |
| // tasks that the framework attempted to launch but failed (with |
| // `TASK_ERROR`) due to a malformed task description. The specified |
| // filters are applied on all unused resources (see mesos.proto for |
| // a description of Filters). Available resources are aggregated |
| // when multiple offers are provided. Note that all offers must |
| // belong to the same slave. |
| virtual Status acceptOffers( |
| const std::vector<OfferID>& offerIds, |
| const std::vector<Offer::Operation>& operations, |
| const Filters& filters = Filters()); |
| |
| // Declines an offer in its entirety and applies the specified |
| // filters on the resources (see mesos.proto for a description of |
| // Filters). Note that this can be done at any time, it is not |
| // necessary to do this within the Scheduler::resourceOffers |
| // callback. |
| virtual Status declineOffer( |
| const OfferID& offerId, |
| const Filters& filters = Filters()); |
| |
| // Removes all filters previously set by the framework (via |
| // launchTasks()). This enables the framework to receive offers from |
| // those filtered slaves. |
| virtual Status reviveOffers(); |
| |
| // Inform Mesos master to stop sending offers to the framework. The |
| // scheduler should call reviveOffers() to resume getting offers. |
| virtual Status suppressOffers(); |
| |
| // Acknowledges the status update. This should only be called |
| // once the status update is processed durably by the scheduler. |
| // Not that explicit acknowledgements must be requested via the |
| // constructor argument, otherwise a call to this method will |
| // cause the driver to crash. |
| virtual Status acknowledgeStatusUpdate(const TaskStatus& status); |
| |
| // Sends a message from the framework to one of its executors. These |
| // messages are best effort; do not expect a framework message to be |
| // retransmitted in any reliable fashion. |
| virtual Status sendFrameworkMessage( |
| const ExecutorID& executorId, |
| const SlaveID& slaveId, |
| const std::string& data); |
| |
| // Allows the framework to query the status for non-terminal tasks. |
| // This causes the master to send back the latest task status for |
| // each task in 'statuses', if possible. Tasks that are no longer |
| // known will result in a TASK_LOST update. If statuses is empty, |
| // then the master will send the latest status for each task |
| // currently known. |
| virtual Status reconcileTasks(const std::vector<TaskStatus>& statuses); |
| </code></pre> |
| |
| <h3>Handling Failures</h3> |
| |
| <p>How to build Mesos frameworks that remain available in the face of failures is |
| discussed in a <a href="/documentation/latest/./high-availability-framework-guide/">separate document</a>.</p> |
| |
| <h2>Working with Executors</h2> |
| |
| <h3>Using the Mesos Command Executor</h3> |
| |
| <p>Mesos provides a simple executor that can execute shell commands and Docker |
| containers on behalf of the framework scheduler; enough functionality for a |
| wide variety of framework requirements.</p> |
| |
| <p>Any scheduler can make use of the Mesos command executor by filling in the |
| optional <code>CommandInfo</code> member of the <code>TaskInfo</code> protobuf message.</p> |
| |
| <pre><code class="{.proto}">message TaskInfo { |
| ... |
| optional CommandInfo command = 7; |
| ... |
| } |
| </code></pre> |
| |
| <p>The Mesos slave will fill in the rest of the <code>ExecutorInfo</code> for you when tasks |
| are specified this way.</p> |
| |
| <p>Note that the agent will derive an <code>ExecutorInfo</code> from the <code>TaskInfo</code> and |
| additionally copy fields (e.g., <code>Labels</code>) from <code>TaskInfo</code> into the new |
| <code>ExecutorInfo</code>. This <code>ExecutorInfo</code> is only visible on the agent.</p> |
| |
| <h3>Using the Mesos Default Executor</h3> |
| |
| <p>Since Mesos 1.1, a new built-in default executor (<strong>experimental</strong>) is available that |
| can execute a group of tasks. Just like the command executor the tasks can be shell |
| commands or Docker containers.</p> |
| |
| <p>The current semantics of the default executor are as folows:</p> |
| |
| <p>– Tasks are launched as nested containers underneath the executor container.</p> |
| |
| <p>– Task containers and executor container share resources like cpu, memory, |
| network and volumes.</p> |
| |
| <p>– There is no resource isolation between different tasks within an executor. |
| Tasks' resources are added to the executor container.</p> |
| |
| <p>– If any of the tasks exits with a non-zero exit code, all the tasks in the task group |
| are killed and the executor shuts down.</p> |
| |
| <p>– Multiple task groups are not supported.</p> |
| |
| <p>Once the default executor is considered <strong>stable</strong>, the command executor will be deprecated in favor of it.</p> |
| |
| <p>Any scheduler can make use of the Mesos default executor by setting <code>ExecutorInfo.type</code> |
| to <code>DEFAULT</code> when launching a group of tasks using the <code>LAUNCH_GROUP</code> offer operation. |
| If <code>DEFAULT</code> executor is explicitly specified when using <code>LAUNCH</code> offer operation, command |
| executor is used instead of the default executor. This might change in the future when the default |
| executor gets support for handling <code>LAUNCH</code> operation.</p> |
| |
| <pre><code class="{.proto}">message ExecutorInfo { |
| ... |
| optional Type type = 15; |
| ... |
| } |
| </code></pre> |
| |
| <h3>Creating a custom Framework Executor</h3> |
| |
| <p>If your framework has special requirements, you might want to provide your own |
| Executor implementation. For example, you may not want a 1:1 relationship |
| between tasks and processes.</p> |
| |
| <p>If you are writing an executor against Mesos 1.0 or newer, it is recommended |
| to use the new <a href="executor-http-api">HTTP API</a> to talk to Mesos.</p> |
| |
| <p>If writing against Mesos 0.28.0 or older, your framework executor must inherit |
| from the Executor class. It must override the launchTask() method. You can use |
| the $MESOS_HOME environment variable inside of your executor to determine where |
| Mesos is running from.</p> |
| |
| <h4>Executor API</h4> |
| |
| <p>Declared in <code>MESOS_HOME/include/mesos/executor.hpp</code></p> |
| |
| <pre><code class="{.cpp}">/* |
| * Invoked once the executor driver has been able to successfully |
| * connect with Mesos. In particular, a scheduler can pass some |
| * data to its executors through the `FrameworkInfo.ExecutorInfo`'s |
| * data field. |
| */ |
| virtual void registered( |
| ExecutorDriver* driver, |
| const ExecutorInfo& executorInfo, |
| const FrameworkInfo& frameworkInfo, |
| const SlaveInfo& slaveInfo); |
| |
| /* |
| * Invoked when the executor re-registers with a restarted slave. |
| */ |
| virtual void reregistered(ExecutorDriver* driver, const SlaveInfo& slaveInfo); |
| |
| /* |
| * Invoked when the executor becomes "disconnected" from the slave |
| * (e.g., the slave is being restarted due to an upgrade). |
| */ |
| virtual void disconnected(ExecutorDriver* driver); |
| |
| /* |
| * Invoked when a task has been launched on this executor (initiated |
| * via Scheduler::launchTasks). Note that this task can be realized |
| * with a thread, a process, or some simple computation, however, no |
| * other callbacks will be invoked on this executor until this |
| * callback has returned. |
| */ |
| virtual void launchTask(ExecutorDriver* driver, const TaskInfo& task); |
| |
| /* |
| * Invoked when a task running within this executor has been killed |
| * (via SchedulerDriver::killTask). Note that no status update will |
| * be sent on behalf of the executor, the executor is responsible |
| * for creating a new TaskStatus (i.e., with TASK_KILLED) and |
| * invoking ExecutorDriver::sendStatusUpdate. |
| */ |
| virtual void killTask(ExecutorDriver* driver, const TaskID& taskId); |
| |
| /* |
| * Invoked when a framework message has arrived for this |
| * executor. These messages are best effort; do not expect a |
| * framework message to be retransmitted in any reliable fashion. |
| */ |
| virtual void frameworkMessage(ExecutorDriver* driver, const std::string& data); |
| |
| /* |
| * Invoked when the executor should terminate all of its currently |
| * running tasks. Note that after a Mesos has determined that an |
| * executor has terminated any tasks that the executor did not send |
| * terminal status updates for (e.g., TASK_KILLED, TASK_FINISHED, |
| * TASK_FAILED, etc) a TASK_LOST status update will be created. |
| */ |
| virtual void shutdown(ExecutorDriver* driver); |
| |
| /* |
| * Invoked when a fatal error has occurred with the executor and/or |
| * executor driver. The driver will be aborted BEFORE invoking this |
| * callback. |
| */ |
| virtual void error(ExecutorDriver* driver, const std::string& message); |
| </code></pre> |
| |
| <h4>Install your custom Framework Executor</h4> |
| |
| <p>After creating your custom executor, you need to make it available to all slaves |
| in the cluster.</p> |
| |
| <p>One way to distribute your framework executor is to let the |
| <a href="/documentation/latest/./fetcher/">Mesos fetcher</a> download it on-demand when your scheduler launches |
| tasks on that slave. <code>ExecutorInfo</code> is a Protocol Buffer Message class (defined |
| in <code>include/mesos/mesos.proto</code>), and it contains a field of type <code>CommandInfo</code>. |
| <code>CommandInfo</code> allows schedulers to specify, among other things, a number of |
| resources as URIs. These resources are fetched to a sandbox directory on the |
| slave before attempting to execute the <code>ExecutorInfo</code> command. Several URI |
| schemes are supported, including HTTP, FTP, HDFS, and S3 (e.g. see |
| src/examples/java/TestFramework.java for an example of this).</p> |
| |
| <p>Alternatively, you can pass the <code>frameworks_home</code> configuration option |
| (defaults to: <code>MESOS_HOME/frameworks</code>) to your <code>mesos-slave</code> daemons when you |
| launch them to specify where your framework executors are stored (e.g. on an |
| NFS mount that is available to all slaves), then use a relative path in |
| <code>CommandInfo.uris</code>, and the slave will prepend the value of <code>frameworks_home</code> |
| to the relative path provided.</p> |
| |
| <p>Once you are sure that your executors are available to the mesos-slaves, you |
| should be able to run your scheduler, which will register with the Mesos master, |
| and start receiving resource offers!</p> |
| |
| <h2>Labels</h2> |
| |
| <p><code>Labels</code> can be found in the <code>FrameworkInfo</code>, <code>TaskInfo</code>, <code>DiscoveryInfo</code> and |
| <code>TaskStatus</code> messages; framework and module writers can use Labels to tag and |
| pass unstructured information around Mesos. Labels are free-form key-value pairs |
| supplied by the framework scheduler or label decorator hooks. Below is the |
| protobuf definitions of labels:</p> |
| |
| <pre><code class="{.proto}"> optional Labels labels = 11; |
| </code></pre> |
| |
| <pre><code class="{.proto}">/** |
| * Collection of labels. |
| */ |
| message Labels { |
| repeated Label labels = 1; |
| } |
| |
| /** |
| * Key, value pair used to store free form user-data. |
| */ |
| message Label { |
| required string key = 1; |
| optional string value = 2; |
| } |
| </code></pre> |
| |
| <p>Labels are not interpreted by Mesos itself, but will be made available over |
| master and slave state endpoints. Further more, the executor and scheduler can |
| introspect labels on the <code>TaskInfo</code> and <code>TaskStatus</code> programmatically. |
| Below is an example of how two label pairs (<code>"environment": "prod"</code> and |
| <code>"bananas": "apples"</code>) can be fetched from the master state endpoint.</p> |
| |
| <pre><code class="{.sh}">$ curl http://master/state.json |
| ... |
| { |
| "executor_id": "default", |
| "framework_id": "20150312-120017-16777343-5050-39028-0000", |
| "id": "3", |
| "labels": [ |
| { |
| "key": "environment", |
| "value": "prod" |
| }, |
| { |
| "key": "bananas", |
| "value": "apples" |
| } |
| ], |
| "name": "Task 3", |
| "slave_id": "20150312-115625-16777343-5050-38751-S0", |
| "state": "TASK_FINISHED", |
| ... |
| }, |
| </code></pre> |
| |
| <h2>Service discovery</h2> |
| |
| <p>When your framework registers an executor or launches a task, it can provide |
| additional information for service discovery. This information is stored by |
| the Mesos master along with other imporant information such as the slave |
| currently running the task. A service discovery system can programmatically |
| retrieve this information in order to set up DNS entries, configure proxies, |
| or update any consistent store used for service discovery in a Mesos cluster |
| that runs multiple frameworks and multiple tasks.</p> |
| |
| <p>The optional <code>DiscoveryInfo</code> message for <code>TaskInfo</code> and <code>ExecutorInfo</code> is |
| declared in <code>MESOS_HOME/include/mesos/mesos.proto</code></p> |
| |
| <pre><code class="{.proto}">message DiscoveryInfo { |
| enum Visibility { |
| FRAMEWORK = 0; |
| CLUSTER = 1; |
| EXTERNAL = 2; |
| } |
| |
| required Visibility visibility = 1; |
| optional string name = 2; |
| optional string environment = 3; |
| optional string location = 4; |
| optional string version = 5; |
| optional Ports ports = 6; |
| optional Labels labels = 7; |
| } |
| </code></pre> |
| |
| <p><code>Visibility</code> is the key parameter that instructs the service discovery system |
| whether a service should be discoverable. We currently differentiate between |
| three cases:</p> |
| |
| <ul> |
| <li>a task should not be discoverable for anyone but its framework.</li> |
| <li>a task should be discoverable for all frameworks running on the Mesos cluster |
| but not externally.</li> |
| <li>a task should be made discoverable broadly.</li> |
| </ul> |
| |
| |
| <p>Many service discovery systems provide additional features that manage the |
| visibility of services (e.g., ACLs in proxy based systems, security extensions |
| to DNS, VLAN or subnet selection). It is not the intended use of the visibility |
| field to manage such features. When a service discovery system retrieves the |
| task or executor information from the master, it can decide how to handle tasks |
| without <code>DiscoveryInfo</code>. For instance, tasks may be made non discoverable to |
| other frameworks (equivalent to <code>visibility=FRAMEWORK</code>) or discoverable to all |
| frameworks (equivalent to <code>visibility=CLUSTER</code>).</p> |
| |
| <p>The <code>name</code> field is a string that provides the service discovery system |
| with the name under which the task is discoverable. The typical use of the name |
| field will be to provide a valid hostname. If name is not provided, it is up to |
| the service discovery system to create a name for the task based on the name |
| field in <code>taskInfo</code> or other information.</p> |
| |
| <p>The <code>environment</code>, <code>location</code>, and <code>version</code> fields provide first class support |
| for common attributes used to differentiate between similar services in large |
| deployments. The <code>environment</code> may receive values such as <code>PROD/QA/DEV</code>, the |
| <code>location</code> field may receive values like <code>EAST-US/WEST-US/EUROPE/AMEA</code>, and the |
| <code>version</code> field may receive values like v2.0/v0.9. The exact use of these fields |
| is up to the service discovery system.</p> |
| |
| <p>The <code>ports</code> field allows the framework to identify the ports a task listens to |
| and explicitly name the functionality they represent and the layer-4 protocol |
| they use (TCP, UDP, or other). For example, a Cassandra task will define ports |
| like <code>"7000,Cluster,TCP"</code>, <code>"7001,SSL,TCP"</code>, <code>"9160,Thrift,TCP"</code>, |
| <code>"9042,Native,TCP"</code>, and <code>"7199,JMX,TCP"</code>. It is up to the service discovery |
| system to use these names and protocol in appropriate ways, potentially |
| combining them with the <code>name</code> field in <code>DiscoveryInfo</code>.</p> |
| |
| <p>The <code>labels</code> field allows a framework to pass arbitrary labels to the service |
| discovery system in the form of key/value pairs. Note that anything passed |
| through this field is not guaranteed to be supported moving forward. |
| Nevertheless, this field provides extensibility. Common uses of this field will |
| allow us to identify use cases that require first class support.</p> |
| |
| </div> |
| </div> |
| |
| </div><!-- /.container --> |
| </div><!-- /.content --> |
| |
| <hr> |
| |
| |
| |
| <!-- footer --> |
| <div class="footer"> |
| <div class="container"> |
| <div class="col-md-4 social-blk"> |
| <span class="social"> |
| <a href="https://twitter.com/ApacheMesos" |
| class="twitter-follow-button" |
| data-show-count="false" data-size="large">Follow @ApacheMesos</a> |
| <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> |
| <a href="https://twitter.com/intent/tweet?button_hashtag=mesos" |
| class="twitter-hashtag-button" |
| data-size="large" |
| data-related="ApacheMesos">Tweet #mesos</a> |
| <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> |
| </span> |
| </div> |
| |
| <div class="col-md-8 trademark"> |
| <p>© 2012-2017 <a href="http://apache.org">The Apache Software Foundation</a>. |
| Apache Mesos, the Apache feather logo, and the Apache Mesos project logo are trademarks of The Apache Software Foundation. |
| <p> |
| </div> |
| </div><!-- /.container --> |
| </div><!-- /.footer --> |
| |
| <!-- JS --> |
| <script src="//code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script> |
| <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js" type="text/javascript"></script> |
| </body> |
| </html> |