Deploying Services In DC/OS

Reading Time: 5 minutes

DC/OS uses Marathon to manage processes and services. Marathon is the “init system” for DC/OS. Marathon starts and monitors your applications and services, automatically healing failures. A native Marathon instance is installed as a part of DC/OS installation. DC/OS services are Marathon applications that are deployed on DC/OS. We create or install a package from the Catalog to start a service. Both services you create and those you install from Universe appear on the Services tab of the DC/OS web interface when they are running. In this blog, we will learn how to use configure and run a service through JSON. We will launch a Tomcat server using a Docker image.

Prerequisites

A running DC/OS 1.11 cluster with at least 1 public agent node.

Marathon Properties

Let’s see some of the important available properties for Marathon application definitions which can be used in the JSON application definition file used to launch a service.

args

An array of strings that specifies the command to run. The args field may be used in place of cmd even when using the default command executor. You must specify either cmd or args in all app definitions. It is invalid to supply both cmd and args in the same app.

acceptedResourceRoles

An array of resource roles. Marathon considers only resource offers with roles in this list for launching tasks of this app.

cmd

The command that is executed. This value is wrapped by Mesos via./bin/sh -c ${app.cmd}

container

The container information.

  • type The containerized runtime type, either MESOS or DOCKER.
  • portMappings An array of port mappings between host and container. A port mapping is similar to passing -p into the Docker command line to specify a relationship between a port on the host machine and a port inside the container. If unspecified (null) at create time, defaults to { “portMappings”: [ { “containerPort”: 0, “name”: “default” } ], … }. Specify an empty array ([]) to indicate no ports are used by the app; no default is injected in this case.A port mapping consists of:
    • containerPort The container port (e.g., 8080).
    • hostPort The host port (e.g., 0). The default value is 0. In networking mode container, the hostPort is not required, but if left unspecified Marathon will not randomly allocate a port. When using container/bridge mode, an unspecified (null) value for hostPort sets hostPort: 0.
    • servicePort The service port (e.g., 9000).
    • protocol The HTTP protocol, either tcp or udp.

cpus

The number of CPU shares per instance. A decimal fraction or integer.

disk

The amount of disk space needed for the application. A decimal fraction or integer MB

env

Environment variables.

executor

The executor used to launch the application. The default is cmd, which takes the cmd and executes that on the shell level.

fetch

An array of URIs to fetch.

A URI consists of:

  • uri URI to be fetched by Mesos fetcher module.
  • executable Set fetched artefact as executable.
  • extract Extract fetched artefact if supported by Mesos fetcher module.
  • cache Cache fetched artefact if supported by Mesos fetcher module.

healthChecks

An array of checks that are run against an application’s tasks. Marathon health checks perform periodic checks on the containers distributed across a cluster to make sure they’re up and responding.

A health check consists of:

  • gracePeriodSeconds Specifies the amount of time (in seconds) to ignore health checks immediately after a task is started; or until the task becomes healthy for the first time.
  • intervalSeconds Specifies the amount of time (in seconds) to wait between health checks.
  • maxConsecutiveFailures Specifies the number of consecutive health check failures that can occur before a task is killed.
  • path If"protocol": "HTTP" this option specifies the path to the task health status endpoint. For example, "/path/to/health"
  • portIndex Specifies the port index in the ports array that is used for health requests. A port index allows the app to use any port, such as "[0,
    0, 0]"
    and tasks could be started with port environment variables such as $PORT1.
  • protocol Specifies the protocol of the requests: HTTP, HTTPS, TCP, or Command.
  • timeoutSeconds Specifies the amount of time (in seconds) before a health check fails, regardless of the response.

id

(Required) Unique identifier for the app consisting of a series of names separated by slashes. Each name must be at least 1 character and may only contain digits (0-9), dashes (-), dots (.), and lowercase letters (a-z).

instances

The number of instances of this application to start. You can change this number as needed to scale the application.

labels

Metadata to expose additional information to other services.

Deploying Tomcat

Now, let’s move on to the actual implementation of the above properties into an application definition file and start a service.

Step 1

Open the DC/OS GUI and click Services. Then, click on the + symbol (Run A Service) on the top right corner of the screen.

Step 2

Select the JSON Configuration option. Now, write the marathon properties appropriate to the service. For example, mine is :

{
  "id": "/tomcat",
  "instances": 1,
  "cpus": 1,
  "mem": 512,
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "tomcat:8.5",
      "network": "BRIDGE",
      "portMappings": [
        {
          "protocol": "tcp",
          "hostPort": 80,
          "containerPort": 8080
        }
      ]
    }
  },
  "requirePorts": true,
  "acceptedResourceRoles": [
    "slave_public"
  ],
  "env": {
    "JAVA_OPTS": "-Xms256m -Xmx256m"
  },
  "healthChecks": [
    {
      "gracePeriodSeconds": 120,
      "intervalSeconds": 30,
      "maxConsecutiveFailures": 3,
      "path": "/",
      "portIndex": 0,
      "protocol": "HTTP",
      "timeoutSeconds": 5
    }
  ]
}

Here we’ve defined the app (.id) to be./tomcat We want Marathon to run one instance of Tomcat for us on our cluster, each instance will require one CPU share (.cpus), 512 MB of RAM (.mem) and port 80 (.container.docker.portMappings[0].hostPort). We then tell Marathon the container image we want Tomcat to run from, in this case, we’re running tomcat:8.5 from DockerHub (.container.docker.image).

We’ve specified that Marathon should run the Docker image using Bridge Networking (.container.docker.network), and specified that TCP port 80 on the host (.container.docker.portMappings[0].hostPort) should be forwarded to TCP port 8080 inside the container (.container.docker.portMappings[0].containerPort). Further, we tell Marathon that we have to run on the port 80 by setting .requirePorts to true.

To ensure that we can get to Tomcat on the internet we instruct Marathon to only run Tomcat on a node that has the role slave_public (which is the public agent node).

Next, we define the JAVA_OPTS that Tomcat will start with (.env.JAVA_OPTS). Finally, we define a health check for Tomcat, Marathon will use this health check to automatically restart our container if Tomcat becomes unhealthy or unresponsive.

Step 3

Click on the Review & Run on the top right corner. Now, check the Services tab again. The Tomcat service should have begun to be deployed. Wait till the status changes to Deployed.

Step 4

To access Tomcat, navigate to the public agent, that is, http:// and note that you’ll need to find the IP of the public agent first, for this to work.

That’s it. Our service is up and running. Hope, you find this information useful.

References: DCOS Docs

knoldus-advt-sticker

 

Written by 

Sudeep James Tirkey is a software consultant having more than 0.5 year of experience. He likes to explore new technologies and trends in the IT world. His hobbies include playing football and badminton, reading and he also loves travelling a lot. Sudeep is familiar with programming languages such as Java, Scala, C, C++ and he is currently working on DevOps and reactive technologies like Jenkins, DC/OS, Ansible, Scala, Java 8, Lagom and Kafka.

2 thoughts on “Deploying Services In DC/OS6 min read

Comments are closed.