Getting Started with Mesos Resource Reservation & Marathon Watchdog – A “Hello World” Example

2016-12-14-01_22_32

Today, we will introduce Apache Mesos, an open source distributed computing system with the target to allow applications to run on a computer cluster as if it was running on a single computer. On top of a Mesos cluster, we will run Mesosphere Marathon, an open source container orchestration platform. Similar to a watchdog, Marathon helps running and maintaining long-running applications. However, unlike a mere watchdog, Marathon runs the applications in containers, and it provides a modern Web Portal and a modern RESTful API.

With the help of Marathon, we will

  • run several instances of a simple “Hello World” script on the cluster (within and outside of Docker containers);
  • see, what happens, if an application dies unexpectedly;
  • see, what happens, if an application reservation request exceeds the available resources.

For simplicity and quick installation purposes, all components of the Mesos architecture will be run within Docker containers.

What is Mesos?

Mesos is an open source framework and provides a distributed computer system. Mesos provides applications (e.g. Hadoop, Spark, Kafka, Elasticsearch) with APIs for resource management and scheduling across entire datacenters and cloud environments.

 

2016-12-14-02_28_36-mesos-marathon-architecture-google-slides

The Mesos Agents advertise the available resources (CPU, DRAM, …) to the master, which will relay those offers to frameworks like Marathon, Hadoop and Jenkins and many more. The frameworks may reserve all or part of the offered resources and run the application on the Mesos agents (slave).

What is Marathon?

Mesosphere, the owner of Marathon calls Marathon “a production-grade container orchestration platform for Mesosphere’s Datacenter Operating System (DC/OS) and Apache Mesos.”

Among others, it offers:

  • active-standby redundancy for increased availability
  • Marathon is starting containers on the Mesos Agent. Both, Mesos containers (using cgroups) and Docker containers are supported.
  • It offers a powerful GUI and
  • a REST API for easier integration.

A more complete feature list can be found here.

Compared to other schedulers like Apache Aurora used by Twitter, Marathon seems to be much easier to handle. On the other side, Aurora offers elaborate prioritization and preemption features. Those may be important, if the same resources are shared between production and development: if a production workload does not find any resources on a Mesos slave, Aurora will kill of less important applications in order to free up resources.

A good comparison between Mesosphere Marathon and Apache Aurora can be found on this Hootsuite Development’s web page.

Target Configuration for this Blog Post

In this “Hello World” example, we will create a simple Mesos configuration with a Marathon framework, a single Zookeeper, a single master and a single agent (slave):

2016-12-14-02_14_43-mesos-marathon-architecture-google-slides

We will also show what happens, if we kill a Marathon app.

Versions & Tools used

Prerequisites:

  • >~4 GB RAM: after starting the a Mesos master, a Mesos agent (slave), a ZooKeeper and a Marathon Docker container, I have observed a DRAM usage of ~3.8 GB

Step 1: Install a Docker Host via Vagrant and Connect to the Host via SSH

If you are using an existing docker host, make sure that your host has enough free memory.

We will run the applications in Docker containers in order to allow for maximum interoperability. This way, we always can use the latest versions without the need to control the java version used.

If you are new to Docker, you might want to read this blog post.

Installing Docker on Windows and Mac can be a real challenge, but no worries: we will show an easy way here, that is much quicker than the one described in Docker’s official documentation:

Prerequisites of this step:

  • I recommend to have direct access to the Internet: via Firewall, but without HTTP proxy. However, if you cannot get rid of your HTTP proxy, read this blog post.
  • Administration rights on you computer.

Steps to install a Docker Host VirtualBox VM:

Download and install Virtualbox (if the installation fails with error message “<to be completed> see Appendix A of this blog post: Virtualbox Installation Workaround)

1. Download and Install Vagrant (requires a reboot)

2. Download Vagrant Box containing an Ubuntu-based Docker Host and create a VirtualBox VM like follows:

basesystem# mkdir ubuntu-trusty64-docker ; cd ubuntu-trusty64-docker
basesystem# vagrant init williamyeh/ubuntu-trusty64-docker
basesystem# vagrant up
basesystem# vagrant ssh

Now you are logged into the Docker host and we are ready for the next step: to create the Docker images.

Note: I have experienced problems with the vi editor when running vagrant ssh in a Windows terminal. In case of Windows, consider to follow Appendix C of this blog post and to use putty instead.

Step 2 (recommended): Download Docker Images

This step is optional, since the download will be done automatically with each docker run command, if the image is not available on the Docker host. However, I recommend to download the images in advance, so if you run the applications, you can observe the logs and other feedback (syntax errors) immediately.

Step 2.1 Download Zookeeper

By looking at the Mesosphere Github documentation, it seems like a Zookeeper (Exhibitor) is needed always. The only tag available as of today is the tag 1.5.2. Let us download it first:

(dockerhost)$ sudo docker pull netflixoss/exhibitor:1.5.2
1.5.2: Pulling from netflixoss/exhibitor

a3ed95caeb02: Pull complete
831a6feb5ab2: Pull complete
b32559aac4de: Pull complete
5e99535a7b44: Pull complete
aa076096cff1: Pull complete
423664404a49: Pull complete
929c1efe4d14: Pull complete
387bf8857f2e: Pull complete
5efe9ea3de0d: Pull complete
a53f74fd9d17: Pull complete
78b42a885be7: Pull complete
684d8691844e: Pull complete
Digest: sha256:9b384a431d2e231f0bd3fcda5eff20d5eabd5ba1e3361764a4834d3401fbc4d4
Status: Downloaded newer image for netflixoss/exhibitor:1.5.2

Step 2.2 Download Mesos Master

It is quite confusing, how many distributions of Mesos exist. The Docker Hub distribution from Mesoscloud seems to offer most of the stars:

$ sudo docker search mesos
NAME                                DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mesoscloud/mesos-master             Mesos Master                                    50                   [OK]
mesoscloud/mesos-slave              Mesos Slave                                     31                   [OK]
...

However, if I search for mesos-master, I find another image with even more stars and downloads:

$ sudo docker search mesos-master
NAME                                         DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mesosphere/mesos-master                      Mesos-Master in Docker                          71
mesoscloud/mesos-master                      Mesos Master                                    50                   [OK]
...

Mesosphere also offers an two-in-one solution with master and slave combined in a single container: mesosphere/mesos. However, the recommended way of running Mesos is to run a master on one Docker host and slaves on other Docker hosts.

Let us download the files mesosphere/mesos-master and mesosphere/mesos-slave. Note that the “latest” tag does not exist, so we need to specify the tag explicitly. Let us try with the latest version I have found to exist for both, master and slave: i.e. 1.1.01.1.0-2.0.107.ubuntu1404.

(dockerhost)$ docker pull mesosphere/mesos-master:1.1.01.1.0-2.0.107.ubuntu1404
1.1.01.1.0-2.0.107.ubuntu1404: Pulling from mesosphere/mesos-master

bf5d46315322: Already exists
9f13e0ac480c: Already exists
e8988b5b3097: Already exists
40af181810e7: Already exists
e6f7c7e5c03e: Already exists
a3ed95caeb02: Already exists
01a862c74d96: Already exists
651b06ceb77e: Already exists
Digest: sha256:a011e002d641c6ba8361c542bd9429af721b7c7434598a9615cbd5b05511af7f
Status: Downloaded newer image for mesosphere/mesos-master:1.1.01.1.0-2.0.107.ubuntu1404

The version of the downloaded Mesos Master image can be checked with following command:

(dockerhost)$ sudo docker run -it --rm --name mesos-master mesosphere/mesos-master:1.1.01.1.0-2.0.107.ubuntu1404 --version
mesos 1.1.0

We are using version 1.1.0, currently.

Step 2.3 Download Mesos Slave

(dockerhost)$ docker pull mesosphere/mesos-slave:1.1.01.1.0-2.0.107.ubuntu1404
1.1.01.1.0-2.0.107.ubuntu1404: Pulling from mesosphere/mesos-slave

bf5d46315322: Already exists
9f13e0ac480c: Already exists
e8988b5b3097: Already exists
40af181810e7: Already exists
e6f7c7e5c03e: Already exists
a3ed95caeb02: Already exists
01a862c74d96: Already exists
651b06ceb77e: Already exists
Digest: sha256:bb75cc78c6880a2faa5307e3d8caa806105c673e9002429e60e3ae858d162999
Status: Downloaded newer image for mesosphere/mesos-slave:1.1.01.1.0-2.0.107.ubuntu1404

Step 2.4 Download Marathon

While Mesos will offer computing resources, Marathon is a framework that will ask for those resources.

(dockerhost)$ sudo docker pull mesosphere/marathon
Using default tag: latest
latest: Pulling from mesosphere/marathon

43c265008fae: Pull complete
af36d2c7a148: Pull complete
143e9d501644: Pull complete
bfc4cdbc8d81: Pull complete
38c6fc3e9968: Pull complete
0bfa8d5153bb: Pull complete
05bc8d0fffca: Pull complete
f1266a2a7ecb: Pull complete
f505e7ed4b7e: Pull complete
219f8c7fc022: Pull complete
Digest: sha256:9c881ff6f46a0da69f622a19a1677f1424a12ef37d076ec439854f15b97179fa
Status: Downloaded newer image for mesosphere/marathon:latest

Marathon does not offer a –version option or alike. The Marathon version can only be seen in the log, when running Marathon:

(dockerhost)$ sudo docker run -it --net=host -v `pwd`:/work_dir --entrypoint=bash mesosphere/marathon
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[2016-12-12 21:01:46,268] INFO Starting Marathon 1.3.6/unknown with --master local --zk zk://localhost:2181/marathon --http_port=7070 (mesosphere.marathon.Main$:main)

Step 3: Run Mesos

In this step, we will run Mesos Master interactively (with -it switch instead of -d switch) to better see, what is happening. In a productive environment, you will use the detached mode -d instead of the interactive terminal mode -it.

We have found out by analyzing the Dockerfiles of mesos-master and mesos-slave images that both are based on mesosphere/mesos with different entrypoints and commands:

  • mesosphere/mesos-master: entrypoint: mesos-master with default option --registry=in_memory
  • mesosphere/mesos-slave: entrypoint: mesos-slave with no default options

Interestingly, the Dockerfiles have no exposed ports specified. The reason is, that the Docker images are supposed to run in host network mode, and by that, they are sharing the interface including IP address(es) and Ports with the Docker host.

The usage of the docker images is documented on Github. It seems like a zookeeper is needed:

Step 3.1: Run Zookeeper (Exhibitor) interactively in a Container

In order to better see, what is happening, we will run the Zookeeper in interactive terminal (-it) mode instead of detached mode (-d), as described in the documentation. With the --nat=host option, we share the network with the Docker host, so we do not need to explicitly expose the used TCP ports:

(dockerhost)$ sudo docker run -it --net=host --name=zookeeper netflixoss/exhibitor:1.5.2
v1.0
INFO com.netflix.exhibitor.core.activity.ActivityLog Exhibitor started [main]
Dec 12, 2016 5:05:28 PM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
INFO org.mortbay.log Logging to org.slf4j.impl.Log4jLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog [main]
INFO org.mortbay.log jetty-1.0 [main]
Dec 12, 2016 5:05:29 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.9.1 09/14/2011 02:36 PM'
INFO org.mortbay.log Started SocketConnector@0.0.0.0:8080 [main]
INFO com.netflix.exhibitor.core.activity.ActivityLog State: down [ActivityQueue-0]
Dec 12, 2016 5:05:30 PM java.util.prefs.FileSystemPreferences$6 run
WARNING: Prefs file removed in background /root/.java/.userPrefs/prefs.xml
INFO com.netflix.exhibitor.core.activity.ActivityLog Attempting to stop instance [ActivityQueue-0]
INFO com.netflix.exhibitor.core.activity.ActivityLog Attempting to start/restart ZooKeeper [ActivityQueue-0]
INFO com.netflix.exhibitor.core.activity.ActivityLog jps didn't find instance - assuming ZK is not running [ActivityQueue-0]
INFO com.netflix.exhibitor.core.activity.ActivityLog Starting in standalone mode [ActivityQueue-0]
ERROR com.netflix.exhibitor.core.activity.ActivityLog ZooKeeper Server: JMX enabled by default [pool-2-thread-1]
INFO com.netflix.exhibitor.core.activity.ActivityLog Process started via: /zookeeper/bin/zkServer.sh [ActivityQueue-0]
ERROR com.netflix.exhibitor.core.activity.ActivityLog ZooKeeper Server: Using config: /zookeeper/bin/../conf/zoo.cfg [pool-2-thread-1]
INFO com.netflix.exhibitor.core.activity.ActivityLog ZooKeeper Server: Starting zookeeper ... STARTED [pool-2-thread-2]
INFO com.netflix.exhibitor.core.activity.ActivityLog State: serving [ActivityQueue-0]

In the log, we see, that the ZooKeeper is using port 8080. Therefore, we will see in Step 3.3 that the TCP port for Marathon needs to be changed in order to avoid a port resource collision.

Step 3.2: Run Master interactively in a Container

Here again, we are following the documentation of the images, but we are starting the Mesos master in interactive mode in a different terminal in order to see all logs, and we use the latest version 1.1.0 instead of 0.28.0:

(dockerhost)$ sudo docker run -it --net=host \
  --name mesos-master \
  -e MESOS_PORT=5050 \
  -e MESOS_ZK=zk://127.0.0.1:2181/mesos \
  -e MESOS_QUORUM=1 \
  -e MESOS_REGISTRY=in_memory \
  -e MESOS_LOG_DIR=/var/log/mesos \
  -e MESOS_WORK_DIR=/var/tmp/mesos \
  -v "$(pwd)/log/mesos:/var/log/mesos" \
  -v "$(pwd)/tmp/mesos:/var/tmp/mesos" \
  mesosphere/mesos-master:1.1.01.1.0-2.0.107.ubuntu1404
WARNING: Logging before InitGoogleLogging() is written to STDERR
I1212 17:10:44.898630 1 main.cpp:263] Build: 2016-11-16 01:30:23 by ubuntu
I1212 17:10:44.898900 1 main.cpp:264] Version: 1.1.0
I1212 17:10:44.898916 1 main.cpp:267] Git tag: 1.1.0
I1212 17:10:44.898927 1 main.cpp:271] Git SHA: a44b077ea0df54b77f05550979e1e97f39b15873
I1212 17:10:44.903816 1 logging.cpp:194] INFO level logging started!
I1212 17:10:44.904436 1 main.cpp:370] Using 'HierarchicalDRF' allocator
2016-12-12 17:10:44,905:1(0x7ff4a8164700):ZOO_INFO@log_env@726: Client environment:zookeeper.version=zookeeper C client 3.4.8
2016-12-12 17:10:44,905:1(0x7ff4a8164700):ZOO_INFO@log_env@730: Client environment:host.name=openshift-installer
2016-12-12 17:10:44,905:1(0x7ff4a8164700):ZOO_INFO@log_env@737: Client environment:os.name=Linux
2016-12-12 17:10:44,905:1(0x7ff4a8164700):ZOO_INFO@log_env@738: Client environment:os.arch=4.2.0-42-generic
2016-12-12 17:10:44,905:1(0x7ff4a8164700):ZOO_INFO@log_env@739: Client environment:os.version=#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016
2016-12-12 17:10:44,907:1(0x7ff4a6961700):ZOO_INFO@log_env@726: Client environment:zookeeper.version=zookeeper C client 3.4.8
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@730: Client environment:host.name=openshift-installer
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@737: Client environment:os.name=Linux
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@738: Client environment:os.arch=4.2.0-42-generic
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@739: Client environment:os.version=#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@747: Client environment:user.name=(null)
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@755: Client environment:user.home=/root
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@log_env@767: Client environment:user.dir=/
2016-12-12 17:10:44,910:1(0x7ff4a6961700):ZOO_INFO@zookeeper_init@800: Initiating client connection, host=127.0.0.1:2181 sessionTimeout=10000 watcher=0x7ff4b16c6200 sessionId=0 sessionPasswd=<null> context=0x7ff490000930 flags=0
I1212 17:10:44.909833 11 master.cpp:380] Master 917a95ab-7b77-4316-8e52-1431a8043af3 (openshift-installer-native-docker-compose) started on 127.0.0.1:5050
I1212 17:10:44.912077 11 master.cpp:382] Flags at startup: --agent_ping_timeout="15secs" --agent_reregister_timeout="10mins" --allocation_interval="1secs" --allocator="HierarchicalDRF" --authenticate_agents="false" --authenticate_frameworks="false" --authenticate_http_frameworks="false" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticators="crammd5" --authorizers="local" --framework_sorter="drf" --help="false" --hostname_lookup="true" --http_authenticators="basic" --initialize_driver_logging="true" --log_auto_initialize="true" --log_dir="/var/log/mesos" --logbufsecs="0" --logging_level="INFO" --max_agent_ping_timeouts="5" --max_completed_frameworks="50" --max_completed_tasks_per_framework="1000" --port="5050" --quiet="false" --quorum="1" --recovery_agent_removal_limit="100%" --registry="in_memory" --registry_fetch_timeout="1mins" --registry_gc_interval="15mins" --registry_max_agent_age="2weeks" --registry_max_agent_count="102400" --registry_store_timeout="20secs" --registry_strict="false" --root_submissions="true" --user_sorter="drf" --version="false" --webui_dir="/usr/share/mesos/webui" --work_dir="/var/tmp/mesos" --zk="zk://127.0.0.1:2181/mesos" --zk_session_timeout="10secs"
2016-12-12 17:10:44,909:1(0x7ff4a8164700):ZOO_INFO@log_env@747: Client environment:user.name=(null)
2016-12-12 17:10:44,913:1(0x7ff4a8164700):ZOO_INFO@log_env@755: Client environment:user.home=/root
2016-12-12 17:10:44,913:1(0x7ff4a8164700):ZOO_INFO@log_env@767: Client environment:user.dir=/
2016-12-12 17:10:44,913:1(0x7ff4a8164700):ZOO_INFO@zookeeper_init@800: Initiating client connection, host=127.0.0.1:2181 sessionTimeout=10000 watcher=0x7ff4b16c6200 sessionId=0 sessionPasswd=<null> context=0x7ff4980038a0 flags=0
W1212 17:10:44.913079 11 master.cpp:385]
**************************************************
Master bound to loopback interface! Cannot communicate with remote schedulers or agents. You might want to set '--ip' flag to a routable IP address.
**************************************************
I1212 17:10:44.914429 11 master.cpp:434] Master allowing unauthenticated frameworks to register
I1212 17:10:44.914448 11 master.cpp:448] Master allowing unauthenticated agents to register
I1212 17:10:44.914455 11 master.cpp:462] Master allowing HTTP frameworks to register without authentication
I1212 17:10:44.914474 11 master.cpp:504] Using default 'crammd5' authenticator
W1212 17:10:44.914487 11 authenticator.cpp:512] No credentials provided, authentication requests will be refused
I1212 17:10:44.914687 11 authenticator.cpp:519] Initializing server SASL
2016-12-12 17:10:44,922:1(0x7ff497fff700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
2016-12-12 17:10:44,923:1(0x7ff497fff700):ZOO_INFO@check_events@1775: session establishment complete on server [127.0.0.1:2181], sessionId=0x158f400557d0003, negotiated timeout=10000
2016-12-12 17:10:44,923:1(0x7ff4977fe700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
2016-12-12 17:10:44,924:1(0x7ff4977fe700):ZOO_INFO@check_events@1775: session establishment complete on server [127.0.0.1:2181], sessionId=0x158f400557d0002, negotiated timeout=10000
I1212 17:10:44.924991 8 group.cpp:340] Group process (zookeeper-group(2)@127.0.0.1:5050) connected to ZooKeeper
I1212 17:10:44.925303 8 group.cpp:828] Syncing group operations: queue size (joins, cancels, datas) = (0, 0, 0)
I1212 17:10:44.925424 8 group.cpp:418] Trying to create path '/mesos' in ZooKeeper
I1212 17:10:44.925204 5 group.cpp:340] Group process (zookeeper-group(1)@127.0.0.1:5050) connected to ZooKeeper
I1212 17:10:44.925606 5 group.cpp:828] Syncing group operations: queue size (joins, cancels, datas) = (0, 0, 0)
I1212 17:10:44.925617 5 group.cpp:418] Trying to create path '/mesos' in ZooKeeper
I1212 17:10:44.931725 8 contender.cpp:152] Joining the ZK group
I1212 17:10:44.932301 11 master.cpp:1951] Successfully attached file '/var/log/mesos/mesos-master.INFO'
I1212 17:10:44.936324 9 contender.cpp:268] New candidate (id='1') has entered the contest for leadership
I1212 17:10:44.937194 5 detector.cpp:152] Detected a new leader: (id='1')
I1212 17:10:44.937408 5 group.cpp:697] Trying to get '/mesos/json.info_0000000001' in ZooKeeper
I1212 17:10:44.939241 5 zookeeper.cpp:259] A new leading master (UPID=master@127.0.0.1:5050) is detected
I1212 17:10:44.939414 5 master.cpp:2017] Elected as the leading master!
I1212 17:10:44.939437 5 master.cpp:1560] Recovering from registrar
I1212 17:10:44.941402 5 registrar.cpp:362] Successfully fetched the registry (0B) in 1.7152ms
I1212 17:10:44.941573 5 registrar.cpp:461] Applied 1 operations in 5462ns; attempting to update the registry
I1212 17:10:44.946907 5 registrar.cpp:506] Successfully updated the registry in 5.135104ms
I1212 17:10:44.947170 5 registrar.cpp:392] Successfully recovered registrar
I1212 17:10:44.947314 5 master.cpp:1676] Recovered 0 agents from the registry (184B); allowing 10mins for agents to re-register
2016-12-12 17:11:11,640:1(0x7ff497fff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 14ms
2016-12-12 17:11:11,641:1(0x7ff4977fe700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 15ms
2016-12-12 17:11:35,045:1(0x7ff497fff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 50ms
2016-12-12 17:11:35,046:1(0x7ff4977fe700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 51ms

Step 3.3: Run Slave interactively in a Container

Here again, we are following the documentation of the images, but we are starting the Mesos slave in interactive mode (-it) in a third terminal in order to see all log, and we use the latest version 1.1.0 instead of 0.28.0:

(dockerhost)$ sudo docker run -it --net=host --privileged \
  -e MESOS_PORT=5051 \
  -e MESOS_MASTER=zk://127.0.0.1:2181/mesos \
  -e MESOS_SWITCH_USER=0 \
  -e MESOS_CONTAINERIZERS=docker,mesos \
  -e MESOS_LOG_DIR=/var/log/mesos \
  -e MESOS_WORK_DIR=/var/tmp/mesos \
  -v "$(pwd)/log/mesos:/var/log/mesos" \
  -v "$(pwd)/tmp/mesos:/var/tmp/mesos" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /cgroup:/cgroup \
  -v /sys:/sys \
  -v /usr/local/bin/docker:/usr/local/bin/docker \
  mesosphere/mesos-slave:1.1.01.1.0-2.0.107.ubuntu1404
WARNING: Logging before InitGoogleLogging() is written to STDERR
I1212 17:18:39.260704 1 main.cpp:243] Build: 2016-11-16 01:30:23 by ubuntu
I1212 17:18:39.261031 1 main.cpp:244] Version: 1.1.0
I1212 17:18:39.261075 1 main.cpp:247] Git tag: 1.1.0
I1212 17:18:39.261108 1 main.cpp:251] Git SHA: a44b077ea0df54b77f05550979e1e97f39b15873
I1212 17:18:39.265000 1 logging.cpp:194] INFO level logging started!
I1212 17:18:39.400902 1 containerizer.cpp:200] Using isolation: posix/cpu,posix/mem,filesystem/posix,network/cni
I1212 17:18:39.429229 1 linux_launcher.cpp:150] Using /sys/fs/cgroup/freezer as the freezer hierarchy for the Linux launcher
2016-12-12 17:18:39,438:1(0x7ff8f7601700):ZOO_INFO@log_env@726: Client environment:zookeeper.version=zookeeper C client 3.4.8
2016-12-12 17:18:39,439:1(0x7ff8f7601700):ZOO_INFO@log_env@730: Client environment:host.name=openshift-installer
2016-12-12 17:18:39,439:1(0x7ff8f7601700):ZOO_INFO@log_env@737: Client environment:os.name=Linux
2016-12-12 17:18:39,439:1(0x7ff8f7601700):ZOO_INFO@log_env@738: Client environment:os.arch=4.2.0-42-generic
2016-12-12 17:18:39,439:1(0x7ff8f7601700):ZOO_INFO@log_env@739: Client environment:os.version=#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016
I1212 17:18:39.438886 1 slave.cpp:208] Mesos agent started on (1)@127.0.0.1:5051
2016-12-12 17:18:39,439:1(0x7ff8f7601700):ZOO_INFO@log_env@747: Client environment:user.name=(null)
I1212 17:18:39.439324 1 slave.cpp:209] Flags at startup: --appc_simple_discovery_uri_prefix="http://" --appc_store_dir="/tmp/mesos/store/appc" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticatee="crammd5" --authentication_backoff_factor="1secs" --authorizer="local" --cgroups_cpu_enable_pids_and_tids_count="false" --cgroups_enable_cfs="false" --cgroups_hierarchy="/sys/fs/cgroup" --cgroups_limit_swap="false" --cgroups_root="mesos" --container_disk_watch_interval="15secs" --containerizers="docker,mesos" --default_role="*" --disk_watch_interval="1mins" --docker="docker" --docker_kill_orphans="true" --docker_registry="https://registry-1.docker.io" --docker_remove_delay="6hrs" --docker_socket="/var/run/docker.sock" --docker_stop_timeout="0ns" --docker_store_dir="/tmp/mesos/store/docker" --docker_volume_checkpoint_dir="/var/run/mesos/isolators/docker/volume" --enforce_container_disk_quota="false" --executor_registration_timeout="1mins" --executor_shutdown_grace_period="5secs" --fetcher_cache_dir="/tmp/mesos/fetch" --fetcher_cache_size="2GB" --frameworks_home="" --gc_delay="1weeks" --gc_disk_headroom="0.1" --hadoop_home="" --help="false" --hostname_lookup="true" --http_authenticators="basic" --http_command_executor="false" --image_provisioner_backend="copy" --initialize_driver_logging="true" --isolation="posix/cpu,posix/mem" --launcher="linux" --launcher_dir="/usr/libexec/mesos" --log_dir="/var/log/mesos" --logbufsecs="0" --logging_level="INFO" --master="zk://127.0.0.1:2181/mesos" --max_completed_executors_per_framework="150" --oversubscribed_resources_interval="15secs" --perf_duration="10secs" --perf_interval="1mins" --port="5051" --qos_correction_interval_min="0ns" --quiet="false" --recover="reconnect" --recovery_timeout="15mins" --registration_backoff_factor="1secs" --revocable_cpu_low_priority="true" --runtime_dir="/var/run/mesos" --sandbox_directory="/mnt/mesos/sandbox" --strict="true" --switch_user="false" --systemd_enable_support="true" --systemd_runtime_directory="/run/systemd/system" --version="false" --work_dir="/var/tmp/mesos"
2016-12-12 17:18:39,441:1(0x7ff8f7601700):ZOO_INFO@log_env@755: Client environment:user.home=/root
2016-12-12 17:18:39,442:1(0x7ff8f7601700):ZOO_INFO@log_env@767: Client environment:user.dir=/
2016-12-12 17:18:39,442:1(0x7ff8f7601700):ZOO_INFO@zookeeper_init@800: Initiating client connection, host=127.0.0.1:2181 sessionTimeout=10000 watcher=0x7ff9023a0200 sessionId=0 sessionPasswd=<null> context=0x7ff8d4001e00 flags=0
2016-12-12 17:18:39,445:1(0x7ff8f4dfc700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
2016-12-12 17:18:39,446:1(0x7ff8f4dfc700):ZOO_INFO@check_events@1775: session establishment complete on server [127.0.0.1:2181], sessionId=0x158f400557d0004, negotiated timeout=10000
W1212 17:18:39.440688 1 slave.cpp:212]
**************************************************
Agent bound to loopback interface! Cannot communicate with remote master(s). You might want to set '--ip' flag to a routable IP address.
**************************************************
I1212 17:18:39.448009 8 group.cpp:340] Group process (zookeeper-group(1)@127.0.0.1:5051) connected to ZooKeeper
I1212 17:18:39.448274 8 group.cpp:828] Syncing group operations: queue size (joins, cancels, datas) = (0, 0, 0)
I1212 17:18:39.448418 8 group.cpp:418] Trying to create path '/mesos' in ZooKeeper
I1212 17:18:39.450460 1 slave.cpp:533] Agent resources: cpus(*):2; mem(*):2928; disk(*):1902607; ports(*):[31000-32000]
I1212 17:18:39.452038 8 detector.cpp:152] Detected a new leader: (id='1')
I1212 17:18:39.452385 8 group.cpp:697] Trying to get '/mesos/json.info_0000000001' in ZooKeeper
I1212 17:18:39.452198 1 slave.cpp:541] Agent attributes: [ ]
I1212 17:18:39.454398 1 slave.cpp:546] Agent hostname: openshift-installer-native-docker-compose
I1212 17:18:39.459702 8 zookeeper.cpp:259] A new leading master (UPID=master@127.0.0.1:5050) is detected
I1212 17:18:39.462762 9 state.cpp:57] Recovering state from '/var/tmp/mesos/meta'
I1212 17:18:39.464331 9 status_update_manager.cpp:203] Recovering status update manager
I1212 17:18:39.465109 9 docker.cpp:764] Recovering Docker containers
I1212 17:18:39.465148 11 containerizer.cpp:555] Recovering containerizer
I1212 17:18:39.472216 6 provisioner.cpp:253] Provisioner recovery complete
I1212 17:18:39.917292 8 slave.cpp:5281] Finished recovery
I1212 17:18:39.938516 8 slave.cpp:915] New master detected at master@127.0.0.1:5050
I1212 17:18:39.939077 8 slave.cpp:936] No credentials provided. Attempting to register without authentication
I1212 17:18:39.939728 8 slave.cpp:947] Detecting new master
I1212 17:18:39.938575 9 status_update_manager.cpp:177] Pausing sending status updates
E1212 17:18:40.622269 8 process.cpp:2154] Failed to shutdown socket with fd 12: Transport endpoint is not connected
I1212 17:18:40.631978 8 slave.cpp:4179] Got exited event for master@127.0.0.1:5050
W1212 17:18:40.634527 8 slave.cpp:4184] Master disconnected! Waiting for a new master to be elected
E1212 17:18:40.632072 13 process.cpp:2154] Failed to shutdown socket with fd 12: Transport endpoint is not connected
E1212 17:18:42.052165 13 process.cpp:2154] Failed to shutdown socket with fd 12: Transport endpoint is not connected
I1212 17:18:42.052312 7 slave.cpp:4179] Got exited event for master@127.0.0.1:5050
W1212 17:18:42.057737 7 slave.cpp:4184] Master disconnected! Waiting for a new master to be elected
I1212 17:18:45.093793 6 slave.cpp:4179] Got exited event for master@127.0.0.1:5050
W1212 17:18:45.094339 6 slave.cpp:4184] Master disconnected! Waiting for a new master to be elected
E1212 17:18:45.093952 13 process.cpp:2154] Failed to shutdown socket with fd 12: Transport endpoint is not connected
I1212 17:18:48.748410 9 slave.cpp:4179] Got exited event for master@127.0.0.1:5050
W1212 17:18:48.748883 9 slave.cpp:4184] Master disconnected! Waiting for a new master to be elected
E1212 17:18:48.748569 13 process.cpp:2154] Failed to shutdown socket with fd 12: Transport endpoint is not connected
2016-12-12 17:18:49,470:1(0x7ff8f4dfc700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 12ms
I1212 17:18:50.030248 8 detector.cpp:152] Detected a new leader: None
I1212 17:18:50.030894 8 slave.cpp:908] Lost leading master
I1212 17:18:50.031404 8 slave.cpp:947] Detecting new master
I1212 17:18:50.031327 7 status_update_manager.cpp:177] Pausing sending status updates
2016-12-12 17:18:53,405:1(0x7ff8f4dfc700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 43ms
I1212 17:19:02.637687 7 slave.cpp:1324] Skipping registration because no master present
I1212 17:19:22.959288 8 detector.cpp:152] Detected a new leader: (id='2')
I1212 17:19:22.961132 8 group.cpp:697] Trying to get '/mesos/json.info_0000000002' in ZooKeeper
I1212 17:19:22.965332 8 zookeeper.cpp:259] A new leading master (UPID=master@127.0.0.1:5050) is detected
I1212 17:19:22.971281 8 slave.cpp:915] New master detected at master@127.0.0.1:5050
I1212 17:19:22.972019 8 slave.cpp:936] No credentials provided. Attempting to register without authentication
I1212 17:19:22.975116 8 slave.cpp:947] Detecting new master
I1212 17:19:22.971410 9 status_update_manager.cpp:177] Pausing sending status updates
I1212 17:19:23.927111 11 slave.cpp:1115] Registered with master master@127.0.0.1:5050; given agent ID a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0
I1212 17:19:23.931748 12 status_update_manager.cpp:184] Resuming sending status updates
I1212 17:19:24.781162 11 slave.cpp:1175] Forwarding total oversubscribed resources {}
I1212 17:19:39.456789 10 slave.cpp:5044] Current disk usage 62.36%. Max allowed age: 1.934608332272824days
2016-12-12 17:19:46,345:1(0x7ff8f4dfc700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 20ms
2016-12-12 17:20:19,750:1(0x7ff8f4dfc700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 41ms

Step 4: Connect to Mesos Web Portal

Mesos’ web portal is running on port 5050 per default. In my case, I am running Mesos on Docker containers, which are hosted by a VirtualBox Docker host VM. Since the VM only has a NATed virtual Ethernet interface, I need to specify a port forwarding rule in VirtualBox, so I can reach port 5050 of the Docker host:

2016-12-12-18_41_57-regel-fur-port-weiterleitung

After that, we can access the Mesos Master Portal from a Browser on the base system:

2016-12-12-18_48_01-mesos

Note: if you see the error “Failed to connect to 127.0.0.1:5050!”, try reloading (instead of retrying) the page via the browser reload function. See Appendix A.1 for details.

We can see the single Mesos slave (i.e. agent) connected to the master on the left:

2016-12-12-19_02_19-mesos

The details of the agents (slaves) can be seen by clicking on the Agents link in the menu:

2016-12-16-20_34_44-mesos

So, what is next? It looks like we need a framework like Marathon in order to start applications on Mesos. Let us start Marathon now.

Step 5: Start Marathon

Let us start Marathon in a container as described here. However, we will use port 7070 instead of 8080, because 8080 collides with a port that is used  by the ZooKeeper. In addition, we will change the master URI and let it point to the external Mesos master we have started in step 3. Moreover, we need to set the environment variable MESOS_WORK_DIR because of a Mesos bug. See Appendix B for details.

(dockerhost)$ sudo docker run -it --name marathon --rm --net=host -e MESOS_WORK_DIR=/var/lib/mesos --entrypoint=bash mesosphere/marathon
(container)# ./bin/start --master zk://127.0.0.1:2181/mesos --zk zk://localhost:2181/marathon --http_port=7070
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[2016-12-13 14:46:09,798] INFO Starting Marathon 1.3.6/unknown with --master zk://127.0.0.1:2181/mesos --zk zk://localhost:2181/marathon --http_port=7070 (mesosphere.marathon.Main$:main)
[2016-12-13 14:46:10,148] WARN Method [public javax.ws.rs.core.Response mesosphere.marathon.api.MarathonExceptionMapper.toResponse(java.lang.Throwable)] is synthetic and is being intercepted by [mesosphere.marathon.DebugModule$MetricsBehavior@985696]. This could indicate a bug. The method may be intercepted twice, or may not be intercepted at all. (com.google.inject.internal.ProxyFactory:main)
[2016-12-13 14:46:10,336] INFO Logging initialized @1841ms (org.eclipse.jetty.util.log:main)
[2016-12-13 14:46:10,849] INFO Slf4jLogger started (akka.event.slf4j.Slf4jLogger:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 14:46:11,060] INFO Started TaskTrackerUpdateStepsProcessorImpl with steps:
* continueOnError(notifyHealthCheckManager)
* continueOnError(notifyRateLimiter)
* continueOnError(notifyLaunchQueue)
* continueOnError(emitUpdate)
* continueOnError(postTaskStatusEvent)
* continueOnError(scaleApp) (mesosphere.marathon.core.task.tracker.impl.TaskTrackerUpdateStepProcessorImpl:main)
[2016-12-13 14:46:11,128] INFO Calling reviveOffers is enabled. Use --disable_revive_offers_for_new_apps to disable. (mesosphere.marathon.core.flow.FlowModule:main)
[2016-12-13 14:46:11,195] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authenticator' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 14:46:11,200] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 14:46:11,202] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authorizer' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 14:46:11,203] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 14:46:11,205] INFO Started status update processor (mesosphere.marathon.core.task.update.impl.TaskStatusUpdateProcessorImpl$$EnhancerByGuice$$ca7c928f:main)
[2016-12-13 14:46:11,321] INFO All actors suspended:
* Actor[akka://marathon/user/groupManager#1830533307]
* Actor[akka://marathon/user/launchQueue#-485770292]
* Actor[akka://marathon/user/killOverdueStagedTasks#540935184]
* Actor[akka://marathon/user/offersWantedForReconciliation#-876030651]
* Actor[akka://marathon/user/taskKillServiceActor#1912899513]
* Actor[akka://marathon/user/rateLimiter#1490654495]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-1930600924]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-405721147]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1467955826]
* Actor[akka://marathon/user/taskTracker#623538008]
* Actor[akka://marathon/user/offerMatcherManager#1760835888] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 14:46:11,417] INFO Adding HTTP support. (mesosphere.chaos.http.HttpModule:main)
[2016-12-13 14:46:11,418] INFO No HTTPS support configured. (mesosphere.chaos.http.HttpModule:main)
[2016-12-13 14:46:11,497] INFO Starting up (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 14:46:11,497] INFO Beginning run (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 14:46:11,498] INFO Will offer leadership after 500 milliseconds backoff (mesosphere.marathon.core.election.impl.CuratorElectionService:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 14:46:11,504] INFO jetty-9.3.z-SNAPSHOT (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,535] INFO Now standing by. Closing existing handles and rejecting new. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 14:46:11,704] INFO Registering com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,705] INFO Registering mesosphere.marathon.api.MarathonExceptionMapper as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.AppsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.TasksResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.EventSubscriptionsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.QueueResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.GroupsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.InfoResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.LeaderResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.DeploymentsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.ArtifactsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.SchemaResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,706] INFO Registering mesosphere.marathon.api.v2.PluginsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,710] INFO Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM' (com.sun.jersey.server.impl.application.WebApplicationImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,765] INFO Binding com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:11,782] INFO Binding mesosphere.marathon.api.MarathonExceptionMapper to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,027] INFO Using HA and therefore offering leadership (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,028] INFO Will do leader election through localhost:2181 (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,073] WARN session timeout [10000] is less than connection timeout [15000] (org.apache.curator.CuratorZookeeperClient:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,096] INFO Starting (org.apache.curator.framework.imps.CuratorFrameworkImpl:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:zookeeper.version=3.5.0-alpha-1615249, built on 08/01/2014 22:13 GMT (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:host.name=openshift-installer-native-docker-compose (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.version=1.8.0_102 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.home=/usr/lib/jvm/java-8-openjdk-amd64/jre (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.class.path=./bin/../target/marathon-assembly-1.3.6.jar (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.version=4.2.0-42-generic (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:user.dir=/marathon (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.memory.free=110MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.memory.max=880MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Client environment:os.memory.total=158MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,124] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.apache.curator.ConnectionState@3411e275 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 14:46:12,194] INFO Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 14:46:12,201] INFO Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 14:46:12,212] INFO Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x158f4c9e1f90014, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 14:46:12,217] INFO State change: CONNECTED (org.apache.curator.framework.state.ConnectionStateManager:ForkJoinPool-2-worker-13-EventThread)
[2016-12-13 14:46:12,279] INFO Elected (LeaderLatchListener Interface) (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-13 14:46:12,284] INFO As new leader running the driver (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 14:46:12,302] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=com.twitter.zk.EventBroker@5301f666 (org.apache.zookeeper.ZooKeeper:pool-1-thread-1)
[2016-12-13 14:46:12,310] INFO Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 14:46:12,310] INFO Socket connection established to localhost/127.0.0.1:2181, initiating session (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 14:46:12,323] INFO Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x158f4c9e1f90015, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 14:46:12,367] INFO Binding mesosphere.marathon.api.v2.AppsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,391] INFO Binding mesosphere.marathon.api.v2.TasksResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,398] INFO Binding mesosphere.marathon.api.v2.EventSubscriptionsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,398] INFO Event notification disabled. (mesosphere.marathon.core.event.EventModule:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,404] INFO Binding mesosphere.marathon.api.v2.QueueResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,425] INFO Binding mesosphere.marathon.api.v2.GroupsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,429] INFO Binding mesosphere.marathon.api.v2.InfoResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,431] INFO Binding mesosphere.marathon.api.v2.LeaderResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,433] INFO Binding mesosphere.marathon.api.v2.DeploymentsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,441] INFO Binding mesosphere.marathon.api.v2.ArtifactsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,443] INFO Binding mesosphere.marathon.api.v2.SchemaResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,445] INFO Binding mesosphere.marathon.api.v2.PluginsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,445] INFO Loading plugins implementing 'mesosphere.marathon.plugin.http.HttpRequestHandler' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,446] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,449] INFO Migration successfully applied for version Version(1, 3, 6) (mesosphere.marathon.state.Migration:ForkJoinPool-2-worker-5)
[2016-12-13 14:46:12,451] INFO Call preDriverStarts callbacks on EntityStoreCache(MarathonStore(app:)), EntityStoreCache(MarathonStore(group:)), EntityStoreCache(MarathonStore(deployment:)), EntityStoreCache(MarathonStore(framework:)), EntityStoreCache(MarathonStore(taskFailure:)), EntityStoreCache(MarathonStore(events:)) (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 14:46:12,468] INFO Finished preDriverStarts callbacks (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 14:46:12,469] INFO Started o.e.j.s.ServletContextHandler@65817241{/,null,AVAILABLE} (org.eclipse.jetty.server.handler.ContextHandler:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,484] INFO ExpungeOverdueLostTasksActor has started (mesosphere.marathon.core.task.jobs.impl.ExpungeOverdueLostTasksActor:marathon-akka.actor.default-dispatcher-4)
[2016-12-13 14:46:12,487] INFO TaskTrackerActor is starting. Task loading initiated. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,489] INFO started RateLimiterActor (mesosphere.marathon.core.launchqueue.impl.RateLimiterActor:marathon-akka.actor.default-dispatcher-4)
[2016-12-13 14:46:12,492] INFO no interest in offers for reservation reconciliation anymore. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 14:46:12,494] INFO Started. Will remain interested in offer reconciliation for 17500 milliseconds when needed. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 14:46:12,514] INFO All actors active:
* Actor[akka://marathon/user/groupManager#1830533307]
* Actor[akka://marathon/user/launchQueue#-485770292]
* Actor[akka://marathon/user/killOverdueStagedTasks#540935184]
* Actor[akka://marathon/user/offersWantedForReconciliation#-876030651]
* Actor[akka://marathon/user/taskKillServiceActor#1912899513]
* Actor[akka://marathon/user/rateLimiter#1490654495]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-1930600924]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-405721147]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1467955826]
* Actor[akka://marathon/user/taskTracker#623538008]
* Actor[akka://marathon/user/offerMatcherManager#1760835888] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 14:46:12,520] INFO Started ServerConnector@7fc3545e{HTTP/1.1,[http/1.1]}{0.0.0.0:7070} (org.eclipse.jetty.server.ServerConnector:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,520] INFO Started @4026ms (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 14:46:12,521] INFO All services up and running. (mesosphere.marathon.Main$:main)
[2016-12-13 14:46:12,524] INFO About to load 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-5)
[2016-12-13 14:46:12,536] INFO Loaded 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-5)
[2016-12-13 14:46:12,545] INFO Task loading complete. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 14:46:12,555] INFO interested in offers for reservation reconciliation because of becoming leader (until 2016-12-13T14:46:29.995Z) (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 14:46:12,588] INFO Received offers WANTED notification (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,589] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,589] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,589] INFO => Schedule next revive at 2016-12-13T14:46:17.586Z in 4998 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,638] INFO Create new Scheduler Driver with frameworkId: Some(value: "44a35e16-dc32-4f91-afac-33dfff498944-0000"
) and scheduler mesosphere.marathon.core.heartbeat.MesosHeartbeatMonitor$$EnhancerByGuice$$c730b9b8@15d42ccb (mesosphere.marathon.MarathonSchedulerDriver$:pool-1-thread-1)
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1213 14:46:12.777942 192 sched.cpp:1697]
**************************************************
Scheduler driver bound to loopback interface! Cannot communicate with remote master(s). You might want to set 'LIBPROCESS_IP' environment variable to use a routable IP address.
**************************************************
I1213 14:46:12.791020 196 sched.cpp:226] Version: 1.0.1
2016-12-13 14:46:12,791:134(0x7f351b0c7700):ZOO_INFO@log_env@726: Client environment:zookeeper.version=zookeeper C client 3.4.8
2016-12-13 14:46:12,791:134(0x7f351b0c7700):ZOO_INFO@log_env@730: Client environment:host.name=openshift-installer
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@737: Client environment:os.name=Linux
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@738: Client environment:os.arch=4.2.0-42-generic
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@739: Client environment:os.version=#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@747: Client environment:user.name=(null)
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@755: Client environment:user.home=/root
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@log_env@767: Client environment:user.dir=/marathon
2016-12-13 14:46:12,792:134(0x7f351b0c7700):ZOO_INFO@zookeeper_init@800: Initiating client connection, host=127.0.0.1:2181 sessionTimeout=10000 watcher=0x7f3522fb1d80 sessionId=0 sessionPasswd=<null> context=0x7f352403b5c0 flags=0
[2016-12-13 14:46:12,799] INFO Reset offerLeadership backoff (mesosphere.marathon.core.election.impl.ExponentialBackoff:pool-1-thread-1)
[2016-12-13 14:46:12,799] INFO Became active. Accepting event streaming requests. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 14:46:12,800] INFO Starting scheduler actor (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-8)
2016-12-13 14:46:12,803:134(0x7f35198c4700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
[2016-12-13 14:46:12,811] INFO Scheduler actor ready (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-6)
2016-12-13 14:46:12,826:134(0x7f35198c4700):ZOO_INFO@check_events@1775: session establishment complete on server [127.0.0.1:2181], sessionId=0x158f4c9e1f90016, negotiated timeout=10000
I1213 14:46:12.828322 205 group.cpp:349] Group process (group(1)@127.0.0.1:35047) connected to ZooKeeper
I1213 14:46:12.829164 205 group.cpp:837] Syncing group operations: queue size (joins, cancels, datas) = (0, 0, 0)
I1213 14:46:12.829583 205 group.cpp:427] Trying to create path '/mesos' in ZooKeeper
I1213 14:46:12.833498 205 detector.cpp:152] Detected a new leader: (id='1')
I1213 14:46:12.834187 205 group.cpp:706] Trying to get '/mesos/json.info_0000000001' in ZooKeeper
I1213 14:46:12.836730 205 zookeeper.cpp:259] A new leading master (UPID=master@127.0.0.1:5050) is detected
I1213 14:46:12.837736 205 sched.cpp:330] New master detected at master@127.0.0.1:5050
I1213 14:46:12.838312 205 sched.cpp:341] No credentials provided. Attempting to register without authentication
I1213 14:46:12.843353 205 sched.cpp:743] Framework registered with 44a35e16-dc32-4f91-afac-33dfff498944-0000
[2016-12-13 14:46:12,846] INFO Creating tombstone for old twitter commons leader election (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-13 14:46:12,872] INFO Registered as 44a35e16-dc32-4f91-afac-33dfff498944-0000 to master '03f81417-51c9-4055-adbe-c1fb74fc8ab4' (mesosphere.marathon.MarathonScheduler$$EnhancerByGuice$$1ef061b0:Thread-14)
[2016-12-13 14:46:12,872] INFO Store framework id: value: "44a35e16-dc32-4f91-afac-33dfff498944-0000"
 (mesosphere.util.state.FrameworkIdUtil:Thread-14)
[2016-12-13 14:46:12,895] INFO Received reviveOffers notification: SchedulerRegisteredEvent (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-13 14:46:16,658] INFO 10.0.2.2 - - [13/Dec/2016:14:46:16 +0000] "GET //localhost:7070/v2/deployments HTTP/1.1" 200 22 "http://localhost:7070/ui/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36" 14 (mesosphere.chaos.http.ChaosRequestLog$$EnhancerByGuice$$c1e74978:qtp1755811644-35)
[2016-12-13 14:46:16,660] INFO 10.0.2.2 - - [13/Dec/2016:14:46:16 +0000] "GET //localhost:7070/v2/groups?embed=group.groups&embed=group.apps&embed=group.apps.deployments&embed=group.apps.counts&embed=group.apps.readiness HTTP/1.1" 200 95 "http://localhost:7070/ui/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36" 15 (mesosphere.chaos.http.ChaosRequestLog$$EnhancerByGuice$$c1e74978:qtp1755811644-36)
[2016-12-13 14:46:16,666] INFO 10.0.2.2 - - [13/Dec/2016:14:46:16 +0000] "GET //localhost:7070/v2/queue HTTP/1.1" 200 32 "http://localhost:7070/ui/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36" 15 (mesosphere.chaos.http.ChaosRequestLog$$EnhancerByGuice$$c1e74978:qtp1755811644-34)
[2016-12-13 14:46:17,603] INFO Received TimedCheck (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 14:46:17,604] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 14:46:17,609] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 14:46:17,612] INFO => Schedule next revive at 2016-12-13T14:46:22.602Z in 4998 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-8)

Let us connect to the Marathon portal:

We have chosen Marathon to run on port 7070. In my case, the Docker host VirtualBox VM has a NATed interface only, so I need to open the Marathon port on VirtualBox:

2016-12-13-14_59_36-regel-fur-port-weiterleitung

Now we can access the Marathon dashboard:

2016-12-13-15_17_35-marathon

Let us see, whether Maraton is visible on Mesos:

2016-12-13-15_44_39-mesos

Yes, the Marathon framework can be seen on the Mesos master; perfect.

thumps_up_3

Now, our topology now looks like follows:
2016-12-14-02_14_43-mesos-marathon-architecture-google-slides

However, we have not started any Marathon application yet. Let us do so now.

Step 6: Start a “Hello World” Application via Marathon Web Portal in a Mesos Container

Let us create an application running in a Mesos container on the Marathon web portal by clicking the Create Application button.

We choose

  • ID: while-loop-hello-world
    • ID needs to consist of lowercase letters, digits, hyphens, “.”, “..”
  • CPUs: 0.1
    • If you keep the default of 1, then you might hit resource problems, if you have not 4 CPUs available for the 4 instances. In this case, one or more instances might be found in the “Waiting” state.
  • Memory: 32 MiB
    • 32 MiB is the minimum value supported
  • Disk Space: 0
  • Instances: 4
  • Command: while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
    • we have redirected the output of the script, because the STDERR/STDOUT retrieval does not work on the Marathon portal, currently (see Appendix A.5).

2016-12-18-12_46_08-marathon

After less than 5 sec, we see, that all of the 4 instances are up and running:

2016-12-18-12_46_16-marathon

On the Docker host, we can see the four instances running:

$ ps -ef | grep Hello | grep -v grep
root 14137 14095 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14138 14096 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14141 14116 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14142 14127 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log

We also can find the log files on the Docker host:

$ sudo find / -name this_is_my_output.log
/vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.927a5843-c517-11e6-ad85-02422b10e522/runs/0f079dcc-25e7-4ad6-b263-4761370a6173/this_is_my_output.log
/vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.9285a2e4-c517-11e6-ad85-02422b10e522/runs/44a5c7dd-59f3-4b59-8d94-33754a3cbdc3/this_is_my_output.log
/vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.92861815-c517-11e6-ad85-02422b10e522/runs/5400a1d9-582f-4d59-9b81-a719d21c60a1/this_is_my_output.log
/vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.9286db66-c517-11e6-ad85-02422b10e522/runs/f3145a9f-2c88-4f99-a8de-618a4157b9e8/this_is_my_output.log

And we can see the output:

$ sudo tail -F /vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.927a5843-c517-11e6-ad85-02422b10e522/runs/0f079dcc-25e7-4ad6-b263-4761370a6173/this_is_my_output.log
I am a Hello World script
I am a Hello World script
I am a Hello World script
I am a Hello World script
I am a Hello World script
...

thumps_up_3

Step 7: Test of Application Resiliency

Step 7.1: Killing a Process and Testing, whether it was restarted automatically

Now, let us see, what happens, if one of the processes dies. For that, we just will kill one of the “Hello World” processes found on the Docker host:

(dockerhost)$ ps -ef | grep Hello | grep -v grep
root 14137 14095 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14138 14096 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14141 14116 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14142 14127 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
(dockerhost)$ sudo kill -9 14137
(dockerhost)$ ps -ef | grep Hello | grep -v grep
root 14138 14096 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14141 14116 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 14142 14127 0 11:46 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log
root 19818 19807 1 12:04 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done 2>&1 1> this_is_my_output.log

We can clearly see that the process was killed successfully, and a new process was started automatically.

thumps_up_3

Step 7.2: Find Traces of the killed Process in the Logs

The output log of the old process can still be retrieved:

$ cat -F /vagrant/jenkins_home/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33
dfff498944-0000/executors/while-loop-hello-world.92861815-c517-11e6-ad85-02422b10e522/runs/5400a1d9-582f-4d59-9b81-a719d21c60a1/this_is_my_output.log
...
I am a Hello World script
I am a Hello World script
I am a Hello World script
I am a Hello World script
(EOF)

However, we cannot see any traces that something went wrong. So, how can we troubleshoot, if a process dies unexpectedly?

Here, we are: the Marathon portal is providing us with information on what happened:

2016-12-18-13_20_47-marathon

thumps_up_3

Step 8: Test: Resource Over-subsription not supported per Default?

In this test, we observe, what happens, if an application instance is exceeding the offered resource limits. For that , we will try to start four instances with 1 CPU core each, while the slave provides 2 CPUs and not the required 4 CPUs:

2016-12-16-20_52_42-marathon

We press Create Application again and see that 2 of the 4 applications are started soon:

2016-12-16-20_54_49-marathon

Two of the task instances were started successfully, and two instances are waiting for resources and are “Unscheduled”. This is the expected behavior:

2016-12-16-21_03_00-marathon

thumps_up_3

On the Mesos Dashboard, we can see that the offered 2 CPUs are used by two instances already, leaving no CPU resources for the other two instances:

2016-12-17-16_27_55-mesos

Aurora vs. Marathon: Consider a situation, where you want to run high priority production applications with low priority development applications on the same hardware. Mesosphere Marathon does not provide any good answer to such situations. In case you hit such a situation, consider to using Apache Aurora instead of Mesosphere Marathon. Apache Aurora allows high priority application to preempt low priority applications.

Mesos: about hard-limit of CPU resources: Mesos’ CPU reservation feels similar to a hard assignment of resources (since over-subscription is not supported per default, as we have seen above), but under the hood, Mesos does not apply hard limits on the CPU usage, unless the Mesos slave has --cgroups_enable_cfs  (CFS = Completely Fair Scheduler) enabled. See also the second answer on this StackOverflow question. For more information on over-subscription by Mesos, see this Apache Mesos Documentation page.

Conclusion: Per default, resource over-subscription is not allowed by Mesos. See this Apache Mesos Documentation page on more information about over-subscription.

Step 9: Start a “Hello World” Application via Marathon Web Portal in a Docker Container

In this step we learn how to run an application in a Docker container instead of a Mesos container. We will perform similar steps as in Step 6.

We choose

  • ID: while-loop-hello-world-container-small
    • ID needs to consist of lowercase letters, digits, hyphens, “.”, “..”
  • CPUs: 0.1
    • If you keep the default of 1, then you might hit resource problems, if you have not 4 CPUs available for the 4 instances. In this case, one or more instances might be found in the “Waiting” state.
  • Memory: 32 MiB
    • 32 MiB is the minimum value supported
  • Disk Space: 0
  • Instances: 4
  • Command: while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
    • we have redirected the output of the script, because the STDERR/STDOUT retrieval does not work on the Marathon portal, currently (see Appendix A.5).
  • Docker: ubuntu:latest

We click “Create Application”

2016-12-17-16_40_36-marathon

Choose a low number of CPUs (0.1 CPUs in my case), the lowest number of Memory and four instances, together with a while loop as command:

2016-12-18-15_39_21-marathon

In the Docker Container tab, we choose an Ubuntu image.

2016-12-17-16_51_26-marathon

First, we see “waiting”,

2016-12-17-16_51_48-marathon

then we see that all four instances are “running”:

2016-12-18-09_17_33-marathon

2016-12-18-15_43_26-marathon

On the Docker host, we can see the four Docker containers that have been started:

$ docker ps
CONTAINER ID        IMAGE                                                   COMMAND                  CREATED             STATUS              PORTS               NAMES
78e346ddb3eb        ubuntu:latest                                           "/bin/sh -c 'while tr"   About an hour ago   Up About an hour                        mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.13aeacaa-20d5-4628-8e65-f82a0fc71724
809ad6513236        ubuntu:latest                                           "/bin/sh -c 'while tr"   About an hour ago   Up About an hour                        mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.c42d9e0c-f66e-42be-ac0e-46bc8f44e47b
de7523c00d41        ubuntu:latest                                           "/bin/sh -c 'while tr"   About an hour ago   Up About an hour                        mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e7fcebfb-f301-4369-83eb-2782832d83a9
d3729dad1bed        ubuntu:latest                                           "/bin/sh -c 'while tr"   About an hour ago   Up About an hour                        mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e924e32b-521b-4708-b538-bc2973094718

The processes are:

$ ps -ef | grep Hello | grep -v grep
root     19306 19258  0 14:40 ?        00:00:00 docker -H unix:///var/run/docker.sock run --cpu-shares 102 --memory 33554432 -e MARATHON_APP_VERSION=2016-12-18T14:40:40.292Z -e HOST=openshift-installer-native-docker-compose -e MARATHON_APP_RESOURCE_CPUS=0.1 -e MARATHON_APP_RESOURCE_GPUS=0 -e MARATHON_APP_DOCKER_IMAGE=ubuntu:latest -e PORT_10000=31730 -e MESOS_TASK_ID=while-loop-hello-world-container-small.f27ecd8a-c52f-11e6-ad85-02422b10e522 -e PORT=31730 -e MARATHON_APP_RESOURCE_MEM=32.0 -e PORTS=31730 -e MARATHON_APP_RESOURCE_DISK=0.0 -e MARATHON_APP_LABELS= -e MARATHON_APP_ID=/while-loop-hello-world-container-small -e PORT0=31730 -e MESOS_SANDBOX=/mnt/mesos/sandbox -e MESOS_CONTAINER_NAME=mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e924e32b-521b-4708-b538-bc2973094718 -v /var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world-container-small.f27ecd8a-c52f-11e6-ad85-02422b10e522/runs/e924e32b-521b-4708-b538-bc2973094718:/mnt/mesos/sandbox --net host --entrypoint /bin/sh --name mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e924e32b-521b-4708-b538-bc2973094718 ubuntu:latest -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19319 19280  0 14:40 ?        00:00:00 docker -H unix:///var/run/docker.sock run --cpu-shares 102 --memory 33554432 -e MARATHON_APP_VERSION=2016-12-18T14:40:40.292Z -e HOST=openshift-installer-native-docker-compose -e MARATHON_APP_RESOURCE_CPUS=0.1 -e MARATHON_APP_RESOURCE_GPUS=0 -e MARATHON_APP_DOCKER_IMAGE=ubuntu:latest -e PORT_10000=31873 -e MESOS_TASK_ID=while-loop-hello-world-container-small.f27e5859-c52f-11e6-ad85-02422b10e522 -e PORT=31873 -e MARATHON_APP_RESOURCE_MEM=32.0 -e PORTS=31873 -e MARATHON_APP_RESOURCE_DISK=0.0 -e MARATHON_APP_LABELS= -e MARATHON_APP_ID=/while-loop-hello-world-container-small -e PORT0=31873 -e MESOS_SANDBOX=/mnt/mesos/sandbox -e MESOS_CONTAINER_NAME=mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.c42d9e0c-f66e-42be-ac0e-46bc8f44e47b -v /var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world-container-small.f27e5859-c52f-11e6-ad85-02422b10e522/runs/c42d9e0c-f66e-42be-ac0e-46bc8f44e47b:/mnt/mesos/sandbox --net host --entrypoint /bin/sh --name mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.c42d9e0c-f66e-42be-ac0e-46bc8f44e47b ubuntu:latest -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19320 19281  0 14:40 ?        00:00:00 docker -H unix:///var/run/docker.sock run --cpu-shares 102 --memory 33554432 -e MARATHON_APP_VERSION=2016-12-18T14:40:40.292Z -e HOST=openshift-installer-native-docker-compose -e MARATHON_APP_RESOURCE_CPUS=0.1 -e MARATHON_APP_RESOURCE_GPUS=0 -e MARATHON_APP_DOCKER_IMAGE=ubuntu:latest -e PORT_10000=31245 -e MESOS_TASK_ID=while-loop-hello-world-container-small.f2792838-c52f-11e6-ad85-02422b10e522 -e PORT=31245 -e MARATHON_APP_RESOURCE_MEM=32.0 -e PORTS=31245 -e MARATHON_APP_RESOURCE_DISK=0.0 -e MARATHON_APP_LABELS= -e MARATHON_APP_ID=/while-loop-hello-world-container-small -e PORT0=31245 -e MESOS_SANDBOX=/mnt/mesos/sandbox -e MESOS_CONTAINER_NAME=mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e7fcebfb-f301-4369-83eb-2782832d83a9 -v /var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world-container-small.f2792838-c52f-11e6-ad85-02422b10e522/runs/e7fcebfb-f301-4369-83eb-2782832d83a9:/mnt/mesos/sandbox --net host --entrypoint /bin/sh --name mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.e7fcebfb-f301-4369-83eb-2782832d83a9 ubuntu:latest -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19368 19352  0 14:40 ?        00:00:01 /bin/sh -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19379 19334  0 14:40 ?        00:00:00 docker -H unix:///var/run/docker.sock run --cpu-shares 102 --memory 33554432 -e MARATHON_APP_VERSION=2016-12-18T14:40:40.292Z -e HOST=openshift-installer-native-docker-compose -e MARATHON_APP_RESOURCE_CPUS=0.1 -e MARATHON_APP_RESOURCE_GPUS=0 -e MARATHON_APP_DOCKER_IMAGE=ubuntu:latest -e PORT_10000=31928 -e MESOS_TASK_ID=while-loop-hello-world-container-small.f27f90db-c52f-11e6-ad85-02422b10e522 -e PORT=31928 -e MARATHON_APP_RESOURCE_MEM=32.0 -e PORTS=31928 -e MARATHON_APP_RESOURCE_DISK=0.0 -e MARATHON_APP_LABELS= -e MARATHON_APP_ID=/while-loop-hello-world-container-small -e PORT0=31928 -e MESOS_SANDBOX=/mnt/mesos/sandbox -e MESOS_CONTAINER_NAME=mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.13aeacaa-20d5-4628-8e65-f82a0fc71724 -v /var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world-container-small.f27f90db-c52f-11e6-ad85-02422b10e522/runs/13aeacaa-20d5-4628-8e65-f82a0fc71724:/mnt/mesos/sandbox --net host --entrypoint /bin/sh --name mesos-a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0.13aeacaa-20d5-4628-8e65-f82a0fc71724 ubuntu:latest -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19422 19406  0 14:40 ?        00:00:01 /bin/sh -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19443 19427  0 14:40 ?        00:00:01 /bin/sh -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log
root     19473 19457  0 14:40 ?        00:00:01 /bin/sh -c while true; do echo "I am a Hello World script in a Docker container"; sleep 1; done 2>&1 1> this_is_my_container_output.log

We can see that there are four docker run commands and four while loops running. We had assigned 0.1 CPUs to each application instance. This has been translated into a CPU share of 1024/10 = ~102.

Note, that Docker does not allow to hard-limit the used CPU per default, if --cgroups_enable_cfs (CFS) is not set on the Docker run command. Instead, CPU shares are configured for the Docker container.

Appendix A: Errors & Caveats

Appendix A.1: Mesos Portal Error: Failed to connect to 127.0.0.1:5050!

Problem:

After starting the Mesos Portal in a Browser, we see following symptom:

2016-12-12-18_49_20-mesos

After clicking “Try now”, the problem shows up immediately again. After clicking the Browser’s page reload button, it looks better, but the problem will show up soon again.

Status: Open

I have not found any solution yet. I have not yet tested any older version.

Appendix A.2: Critical Error: Mesos Master: Lost leadership… committing suicide!

  • Mesos master 1.1.0 run in a Docker container (image mesosphere/mesos-master:1.1.01.1.0-2.0.107.ubuntu1404)
  • ZooKeeper 1.5.2 run in a Docker container (image netflixoss/exhibitor:1.5.2)

Symptoms:

From time to time, we get following critical error log of the Mesos Master:

...
2016-12-18 08:15:59,593:22(0x7f18037fe700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 31198753ms
2016-12-18 08:15:59,595:22(0x7f1820ef8700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 31198755ms
2016-12-18 08:15:59,597:22(0x7f1820ef8700):ZOO_ERROR@handle_socket_error_msg@1735: Socket [127.0.0.1:2181] zk retcode=-4, errno=32(Broken pipe): failed while flushing send queue
2016-12-18 08:15:59,597:22(0x7f18037fe700):ZOO_ERROR@handle_socket_error_msg@1746: Socket [127.0.0.1:2181] zk retcode=-4, errno=112(Host is down): failed while receiving a server response
2016-12-18 08:15:59,599:22(0x7f1820ef8700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
I1218 08:15:59.601364 25 group.cpp:451] Lost connection to ZooKeeper, attempting to reconnect ...
I1218 08:15:59.602128 26 group.cpp:451] Lost connection to ZooKeeper, attempting to reconnect ...
2016-12-18 08:15:59,604:22(0x7f1820ef8700):ZOO_ERROR@handle_socket_error_msg@1764: Socket [127.0.0.1:2181] zk retcode=-112, errno=116(Stale file handle): sessionId=0x158f4c9e1f90035 has expired.
I1218 08:15:59.605609 28 group.cpp:510] ZooKeeper session expired
I1218 08:15:59.606210 29 contender.cpp:217] Membership cancelled: 4
2016-12-18 08:15:59,606:22(0x7f1823737700):ZOO_INFO@zookeeper_close@2543: Freeing zookeeper resources for sessionId=0x158f4c9e1f90035

Lost leadership... committing suicide!
2016-12-18 08:15:59,607:22(0x7f182573b700):ZOO_INFO@log_env@726: Client environment:zookeeper.version=zookeeper C client 3.4.8
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@730: Client environment:host.name=openshift-installer
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@737: Client environment:os.name=Linux
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@738: Client environment:os.arch=4.2.0-42-generic
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@739: Client environment:os.version=#49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@747: Client environment:user.name=(null)
2016-12-18 08:15:59,608:22(0x7f182573b700):ZOO_INFO@log_env@755: Client environment:user.home=/root
2016-12-18 08:15:59,609:22(0x7f182573b700):ZOO_INFO@log_env@767: Client environment:user.dir=/
2016-12-18 08:15:59,609:22(0x7f182573b700):ZOO_INFO@zookeeper_init@800: Initiating client connection, host=127.0.0.1:2181 sessionTimeout=10000 watcher=0x7f182e49c200 sessionId=0 sessionPasswd=<null> context=0x7f1810008470 flags=0
2016-12-18 08:15:59,609:22(0x7f1803fff700):ZOO_INFO@check_events@1728: initiated connection to server [127.0.0.1:2181]
(container)#

Resolution: None

I have found a similar issue for Marathon here. Both problems seem to be caused by ZooKeeper problems, but it is not clear, how to resolve the issue.

Appendix A.3: ZooKeeper: continuous warnings ‘Exceeded deadline’ and ‘Current disk usage’

After starting the ZooKeeper, I continuously see log messages like follows:

2016-12-18 10:24:14,664:1(0x7fb7abfff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 77ms
I1218 10:24:58.446185 15 slave.cpp:5044] Current disk usage 62.33%. Max allowed age: 1.936647380411088days
I1218 10:25:58.450482 14 slave.cpp:5044] Current disk usage 62.33%. Max allowed age: 1.936647380411088days
2016-12-18 10:26:21,523:1(0x7fb7abfff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 26ms
I1218 10:26:58.454617 9 slave.cpp:5044] Current disk usage 62.33%. Max allowed age: 1.936647380411088days
2016-12-18 10:27:58,326:1(0x7fb7abfff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 15ms
I1218 10:27:58.458858 12 slave.cpp:5044] Current disk usage 62.33%. Max allowed age: 1.936647380411088days
2016-12-18 10:28:01,681:1(0x7fb7abfff700):ZOO_WARN@zookeeper_interest@1570: Exceeded deadline by 20ms

Resolution: None

Since the warnings do not seem to be critical, I have not yet dug into the problem.

Appendix A.4: Marathon Portal Error: no Reaction upon Restart Request

Symptoms:

If we try to restart an application, there is no reaction whatsoever:

2016-12-17-16_38_48-marathon

2016-12-16-21_07_20-marathon

2016-12-16-21_08_33-marathon

Running ps -ef on the Docker host yields the same process numbers before and after pressing the Restart button:

(dockerhost)$ ps -ef | grep while | grep -v grep
root 13142 29300 0 19:54 ? 00:00:00 mesos-containerizer launch --command={"arguments":["mesos-executor","--launcher_dir=\/usr\/libexec\/mesos"],"shell":false,"value":"\/usr\/libexec\/mesos\/mesos-executor"} --environment={"HOST":"openshift-installer-native-docker-compose","LIBPROCESS_PORT":"0","MARATHON_APP_ID":"\/while-loop-hello-world","MARATHON_APP_LABELS":"","MARATHON_APP_RESOURCE_CPUS":"1.0","MARATHON_APP_RESOURCE_DISK":"0.0","MARATHON_APP_RESOURCE_GPUS":"0","MARATHON_APP_RESOURCE_MEM":"32.0","MARATHON_APP_VERSION":"2016-12-16T19:54:30.939Z","MESOS_AGENT_ENDPOINT":"127.0.0.1:5051","MESOS_CHECKPOINT":"1","MESOS_DIRECTORY":"\/var\/tmp\/mesos\/slaves\/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0\/frameworks\/44a35e16-dc32-4f91-afac-33dfff498944-0000\/executors\/while-loop-hello-world.75d64c28-c3c9-11e6-9f91-02422b10e522\/runs\/a67b861b-c20c-4d94-8db5-e956b3dea8ab","MESOS_EXECUTOR_ID":"while-loop-hello-world.75d64c28-c3c9-11e6-9f91-02422b10e522","MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD":"5secs","MESOS_FRAMEWORK_ID":"44a35e16-dc32-4f91-afac-33dfff498944-0000","MESOS_HTTP_COMMAND_EXECUTOR":"0","MESOS_NATIVE_JAVA_LIBRARY":"\/usr\/lib\/libmesos-1.1.0.so","MESOS_NATIVE_LIBRARY":"\/usr\/lib\/libmesos-1.1.0.so","MESOS_RECOVERY_TIMEOUT":"15mins","MESOS_SANDBOX":"\/var\/tmp\/mesos\/slaves\/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0\/frameworks\/44a35e16-dc32-4f91-afac-33dfff498944-0000\/executors\/while-loop-hello-world.75d64c28-c3c9-11e6-9f91-02422b10e522\/runs\/a67b861b-c20c-4d94-8db5-e956b3dea8ab","MESOS_SLAVE_ID":"a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0","MESOS_SLAVE_PID":"slave(1)@127.0.0.1:5051","MESOS_SUBSCRIPTION_BACKOFF_MAX":"2secs","MESOS_TASK_ID":"while-loop-hello-world.75d64c28-c3c9-11e6-9f91-02422b10e522","PATH":"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin","PORT":"31690","PORT0":"31690","PORTS":"31690","PORT_10000":"31690"} --help=false --pipe_read=15 --pipe_write=16 --pre_exec_commands=[] --runtime_directory=/var/run/mesos/containers/a67b861b-c20c-4d94-8db5-e956b3dea8ab --unshare_namespace_mnt=false --working_directory=/var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.75d64c28-c3c9-11e6-9f91-02422b10e522/runs/a67b861b-c20c-4d94-8db5-e956b3dea8ab
root 13144 29300 0 19:54 ? 00:00:00 mesos-containerizer launch --command={"arguments":["mesos-executor","--launcher_dir=\/usr\/libexec\/mesos"],"shell":false,"value":"\/usr\/libexec\/mesos\/mesos-executor"} --environment={"HOST":"openshift-installer-native-docker-compose","LIBPROCESS_PORT":"0","MARATHON_APP_ID":"\/while-loop-hello-world","MARATHON_APP_LABELS":"","MARATHON_APP_RESOURCE_CPUS":"1.0","MARATHON_APP_RESOURCE_DISK":"0.0","MARATHON_APP_RESOURCE_GPUS":"0","MARATHON_APP_RESOURCE_MEM":"32.0","MARATHON_APP_VERSION":"2016-12-16T19:54:30.939Z","MESOS_AGENT_ENDPOINT":"127.0.0.1:5051","MESOS_CHECKPOINT":"1","MESOS_DIRECTORY":"\/var\/tmp\/mesos\/slaves\/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0\/frameworks\/44a35e16-dc32-4f91-afac-33dfff498944-0000\/executors\/while-loop-hello-world.75cab367-c3c9-11e6-9f91-02422b10e522\/runs\/cb6ec83f-a228-47f5-ad06-ee6675134bb0","MESOS_EXECUTOR_ID":"while-loop-hello-world.75cab367-c3c9-11e6-9f91-02422b10e522","MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD":"5secs","MESOS_FRAMEWORK_ID":"44a35e16-dc32-4f91-afac-33dfff498944-0000","MESOS_HTTP_COMMAND_EXECUTOR":"0","MESOS_NATIVE_JAVA_LIBRARY":"\/usr\/lib\/libmesos-1.1.0.so","MESOS_NATIVE_LIBRARY":"\/usr\/lib\/libmesos-1.1.0.so","MESOS_RECOVERY_TIMEOUT":"15mins","MESOS_SANDBOX":"\/var\/tmp\/mesos\/slaves\/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0\/frameworks\/44a35e16-dc32-4f91-afac-33dfff498944-0000\/executors\/while-loop-hello-world.75cab367-c3c9-11e6-9f91-02422b10e522\/runs\/cb6ec83f-a228-47f5-ad06-ee6675134bb0","MESOS_SLAVE_ID":"a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0","MESOS_SLAVE_PID":"slave(1)@127.0.0.1:5051","MESOS_SUBSCRIPTION_BACKOFF_MAX":"2secs","MESOS_TASK_ID":"while-loop-hello-world.75cab367-c3c9-11e6-9f91-02422b10e522","PATH":"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin","PORT":"31996","PORT0":"31996","PORTS":"31996","PORT_10000":"31996"} --help=false --pipe_read=15 --pipe_write=16 --pre_exec_commands=[] --runtime_directory=/var/run/mesos/containers/cb6ec83f-a228-47f5-ad06-ee6675134bb0 --unshare_namespace_mnt=false --working_directory=/var/tmp/mesos/slaves/a06268a0-4cfd-4d76-94c7-fbdf053be0ba-S0/frameworks/44a35e16-dc32-4f91-afac-33dfff498944-0000/executors/while-loop-hello-world.75cab367-c3c9-11e6-9f91-02422b10e522/runs/cb6ec83f-a228-47f5-ad06-ee6675134bb0
root 13164 13143 0 19:54 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done
root 13165 13154 0 19:54 ? 00:00:00 sh -c while true; do echo "I am a Hello World script"; sleep 1; done

Status: Workaround given

The workaround is to destroy the application and run a new application with the exact same parameters.

Appendix A.5: Marathon Portal Error: Retrieval of STDERR and STDOUT fails

Seen on Marathon 1.3.6 with both, a shell script on Mesos container as well as with a shell script on a Docker container.

Symptoms:

If you try to retrieve the error log of output of a hello world application on the Marathon portal, we get the error message “Sorry, there was a problem retrieving file. Click to retry.” Retrying does not help.

2016-12-16-21_04_29-marathon

Status: Open (idea for a workaround given below)

A possible workaround is to run the script with redirection into a file you can retrieve later, E.g. we could define a script like

while true; do echo "I am a Hello World script" 2>&1 1> this_is_my_output.log

After having found the working directory of Mesos-started scripts, you can retrieve the log file from the slave’s file system.

Appendix A.6: Critical Marathon Error: Flag 'work_dir' is required, but it was not provided

Marathon 1.3.6 run as Docker container (mesosphere/marathon:latest; image ID 9d03a8fd0fdd)

Symptoms

When we try to start Marathon as seen below, the attempt fails with the exception:

Failed to start a local cluster while loading agent flags from the environment: Flag 'work_dir' is required, but it was not provided

Full log:

(dockerhost)$ sudo docker run -it --net=host -v `pwd`:/work_dir --entrypoint=bash mesosphere/marathon
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[2016-12-12 21:01:46,268] INFO Starting Marathon 1.3.6/unknown with --master local --zk zk://localhost:2181/marathon --http_port=7070 (mesosphere.marathon.Main$:main)
[2016-12-12 21:01:46,588] WARN Method [public javax.ws.rs.core.Response mesosphere.marathon.api.MarathonExceptionMapper.toResponse(java.lang.Throwable)] is synthetic and is being intercepted by [mesosphere.marathon.DebugModule$MetricsBehavior@985696]. This could indicate a bug. The method may be intercepted twice, or may not be intercepted at all. (com.google.inject.internal.ProxyFactory:main)
[2016-12-12 21:01:46,899] INFO Logging initialized @1979ms (org.eclipse.jetty.util.log:main)
[2016-12-12 21:01:47,322] INFO Slf4jLogger started (akka.event.slf4j.Slf4jLogger:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:01:47,517] INFO Started TaskTrackerUpdateStepsProcessorImpl with steps:
* continueOnError(notifyHealthCheckManager)
* continueOnError(notifyRateLimiter)
* continueOnError(notifyLaunchQueue)
* continueOnError(emitUpdate)
* continueOnError(postTaskStatusEvent)
* continueOnError(scaleApp) (mesosphere.marathon.core.task.tracker.impl.TaskTrackerUpdateStepProcessorImpl:main)
[2016-12-12 21:01:47,579] INFO Calling reviveOffers is enabled. Use --disable_revive_offers_for_new_apps to disable. (mesosphere.marathon.core.flow.FlowModule:main)
[2016-12-12 21:01:47,657] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authenticator' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:01:47,662] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:01:47,665] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authorizer' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:01:47,666] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:01:47,668] INFO Started status update processor (mesosphere.marathon.core.task.update.impl.TaskStatusUpdateProcessorImpl$$EnhancerByGuice$$ca7c928f:main)
[2016-12-12 21:01:47,779] INFO All actors suspended:
* Actor[akka://marathon/user/expungeOverdueLostTasks#1718670650]
* Actor[akka://marathon/user/rateLimiter#1278378489]
* Actor[akka://marathon/user/groupManager#890512610]
* Actor[akka://marathon/user/taskTracker#-11699813]
* Actor[akka://marathon/user/launchQueue#1496971565]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-557182315]
* Actor[akka://marathon/user/killOverdueStagedTasks#-1648400379]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1003103868]
* Actor[akka://marathon/user/offerMatcherManager#219115497]
* Actor[akka://marathon/user/offersWantedForReconciliation#-1104494480]
* Actor[akka://marathon/user/taskKillServiceActor#-521724399] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-12 21:01:47,891] INFO Adding HTTP support. (mesosphere.chaos.http.HttpModule:main)
[2016-12-12 21:01:47,892] INFO No HTTPS support configured. (mesosphere.chaos.http.HttpModule:main)
[2016-12-12 21:01:47,971] INFO Starting up (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:01:47,972] INFO Beginning run (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:01:47,974] INFO Will offer leadership after 500 milliseconds backoff (mesosphere.marathon.core.election.impl.CuratorElectionService:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:01:47,983] INFO jetty-9.3.z-SNAPSHOT (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,018] INFO Now standing by. Closing existing handles and rejecting new. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-12 21:01:48,229] INFO Registering com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,233] INFO Registering mesosphere.marathon.api.MarathonExceptionMapper as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,233] INFO Registering mesosphere.marathon.api.v2.AppsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,233] INFO Registering mesosphere.marathon.api.v2.TasksResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,233] INFO Registering mesosphere.marathon.api.v2.EventSubscriptionsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,233] INFO Registering mesosphere.marathon.api.v2.QueueResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.GroupsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.InfoResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.LeaderResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.DeploymentsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.ArtifactsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.SchemaResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,234] INFO Registering mesosphere.marathon.api.v2.PluginsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,238] INFO Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM' (com.sun.jersey.server.impl.application.WebApplicationImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,311] INFO Binding com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,328] INFO Binding mesosphere.marathon.api.MarathonExceptionMapper to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:01:48,527] INFO Using HA and therefore offering leadership (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,528] INFO Will do leader election through localhost:2181 (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,553] WARN session timeout [10000] is less than connection timeout [15000] (org.apache.curator.CuratorZookeeperClient:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,565] INFO Starting (org.apache.curator.framework.imps.CuratorFrameworkImpl:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:zookeeper.version=3.5.0-alpha-1615249, built on 08/01/2014 22:13 GMT (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:host.name=openshift-installer-native-docker-compose (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.version=1.8.0_102 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.home=/usr/lib/jvm/java-8-openjdk-amd64/jre (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.class.path=./bin/../target/marathon-assembly-1.3.6.jar (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,576] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,577] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,577] INFO Client environment:os.version=4.2.0-42-generic (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,577] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,577] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,577] INFO Client environment:user.dir=/marathon (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,578] INFO Client environment:os.memory.free=121MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,578] INFO Client environment:os.memory.max=880MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,578] INFO Client environment:os.memory.total=157MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,578] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.apache.curator.ConnectionState@7531678e (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:01:48,623] INFO Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:01:48,633] INFO Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:01:48,653] INFO Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x158f4c9e1f90004, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:01:48,661] INFO State change: CONNECTED (org.apache.curator.framework.state.ConnectionStateManager:ForkJoinPool-2-worker-13-EventThread)
[2016-12-12 21:01:48,722] INFO Elected (LeaderLatchListener Interface) (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-12 21:01:48,723] INFO As new leader running the driver (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:01:48,734] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=com.twitter.zk.EventBroker@5ca52bc0 (org.apache.zookeeper.ZooKeeper:pool-1-thread-1)
[2016-12-12 21:01:48,748] INFO Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:01:48,749] INFO Socket connection established to localhost/127.0.0.1:2181, initiating session (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:01:48,755] INFO Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x158f4c9e1f90005, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:01:48,854] INFO Migration successfully applied for version Version(1, 3, 6) (mesosphere.marathon.state.Migration:ForkJoinPool-2-worker-7)
[2016-12-12 21:01:48,854] INFO Call preDriverStarts callbacks on EntityStoreCache(MarathonStore(app:)), EntityStoreCache(MarathonStore(group:)), EntityStoreCache(MarathonStore(deployment:)), EntityStoreCache(MarathonStore(framework:)), EntityStoreCache(MarathonStore(taskFailure:)), EntityStoreCache(MarathonStore(events:)) (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:01:48,868] INFO Finished preDriverStarts callbacks (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:01:48,885] INFO TaskTrackerActor is starting. Task loading initiated. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-12 21:01:48,893] INFO no interest in offers for reservation reconciliation anymore. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:01:48,897] INFO ExpungeOverdueLostTasksActor has started (mesosphere.marathon.core.task.jobs.impl.ExpungeOverdueLostTasksActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-12 21:01:48,900] INFO About to load 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-3)
[2016-12-12 21:01:48,901] INFO Loaded 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-3)
[2016-12-12 21:01:48,902] INFO Started. Will remain interested in offer reconciliation for 17500 milliseconds when needed. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:01:48,911] INFO Task loading complete. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-7)
[2016-12-12 21:01:48,914] INFO Create new Scheduler Driver with frameworkId: None and scheduler mesosphere.marathon.core.heartbeat.MesosHeartbeatMonitor$$EnhancerByGuice$$c730b9b8@15d42ccb (mesosphere.marathon.MarathonSchedulerDriver$:pool-1-thread-1)
[2016-12-12 21:01:48,924] INFO started RateLimiterActor (mesosphere.marathon.core.launchqueue.impl.RateLimiterActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-12 21:01:48,925] INFO All actors active:
* Actor[akka://marathon/user/expungeOverdueLostTasks#1718670650]
* Actor[akka://marathon/user/rateLimiter#1278378489]
* Actor[akka://marathon/user/groupManager#890512610]
* Actor[akka://marathon/user/taskTracker#-11699813]
* Actor[akka://marathon/user/launchQueue#1496971565]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-557182315]
* Actor[akka://marathon/user/killOverdueStagedTasks#-1648400379]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1003103868]
* Actor[akka://marathon/user/offerMatcherManager#219115497]
* Actor[akka://marathon/user/offersWantedForReconciliation#-1104494480]
* Actor[akka://marathon/user/taskKillServiceActor#-521724399] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-12 21:01:48,994] INFO Received offers WANTED notification (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-7)
[2016-12-12 21:01:48,994] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-7)
[2016-12-12 21:01:48,995] INFO interested in offers for reservation reconciliation because of becoming leader (until 2016-12-12T21:02:06.407Z) (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:01:49,008] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-12 21:01:49,008] INFO => Schedule next revive at 2016-12-12T21:01:53.993Z in 4986 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1212 21:01:49.134382 63 sched.cpp:1697]
**************************************************
Scheduler driver bound to loopback interface! Cannot communicate with remote master(s). You might want to set 'LIBPROCESS_IP' environment variable to use a routable IP address.
**************************************************
I1212 21:01:49.179211 63 leveldb.cpp:174] Opened db in 40.639535ms
I1212 21:01:49.188115 63 leveldb.cpp:181] Compacted db in 8.801601ms
I1212 21:01:49.188176 63 leveldb.cpp:196] Created db iterator in 11072ns
I1212 21:01:49.188189 63 leveldb.cpp:202] Seeked to beginning of db in 758ns
I1212 21:01:49.188194 63 leveldb.cpp:271] Iterated through 0 keys in the db in 202ns
I1212 21:01:49.188232 63 replica.cpp:779] Replica recovered with log positions 0 -> 0 with 1 holes and 0 unlearned
I1212 21:01:49.189082 70 recover.cpp:451] Starting replica recovery
I1212 21:01:49.189720 70 recover.cpp:477] Replica is in EMPTY status
I1212 21:01:49.189486 73 master.cpp:375] Master 8be08601-c962-42fa-9f78-7beda337b644 (openshift-installer-native-docker-compose) started on 127.0.0.1:35322
I1212 21:01:49.190399 73 master.cpp:377] Flags at startup: --agent_ping_timeout="15secs" --agent_reregister_timeout="10mins" --allocation_interval="1secs" --allocator="HierarchicalDRF" --authenticate_agents="false" --authenticate_frameworks="false" --authenticate_http_frameworks="false" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticators="crammd5" --authorizers="local" --framework_sorter="drf" --help="false" --hostname_lookup="true" --http_authenticators="basic" --initialize_driver_logging="true" --log_auto_initialize="true" --logbufsecs="0" --logging_level="INFO" --max_agent_ping_timeouts="5" --max_completed_frameworks="50" --max_completed_tasks_per_framework="1000" --quiet="false" --recovery_agent_removal_limit="100%" --registry="replicated_log" --registry_fetch_timeout="1mins" --registry_store_timeout="20secs" --registry_strict="false" --root_submissions="true" --user_sorter="drf" --version="false" --webui_dir="/usr/share/mesos/webui" --work_dir="/tmp/mesos/local/9Y1S6q" --zk_session_timeout="10secs"
W1212 21:01:49.190558 73 master.cpp:380]
**************************************************
Master bound to loopback interface! Cannot communicate with remote schedulers or agents. You might want to set '--ip' flag to a routable IP address.
**************************************************
I1212 21:01:49.190712 73 master.cpp:429] Master allowing unauthenticated frameworks to register
I1212 21:01:49.191285 73 master.cpp:443] Master allowing unauthenticated agents to register
I1212 21:01:49.191337 73 master.cpp:457] Master allowing HTTP frameworks to register without authentication
I1212 21:01:49.191366 73 master.cpp:499] Using default 'crammd5' authenticator
Failed to start a local cluster while loading agent flags from the environment: Flag 'work_dir' is required, but it was not provided
W1212 21:01:49.192327 73 authenticator.cpp:512] No credentials provided, authentication requests will be refused
I1212 21:01:49.192360 73 authenticator.cpp:519] Initializing server SASL
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070 --work_dir
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[scallop] Error: Unknown option 'work_dir'
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070 -work_dir=/work_dir
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[scallop] Error: Unknown option 'w'
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070 --work_dir=/work_dir
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[scallop] Error: Unknown option 'work_dir=/work_dir'
root@openshift-installer:/marathon# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[2016-12-12 21:05:35,546] INFO Starting Marathon 1.3.6/unknown with --master local --zk zk://localhost:2181/marathon --http_port=7070 (mesosphere.marathon.Main$:main)
[2016-12-12 21:05:35,823] WARN Method [public javax.ws.rs.core.Response mesosphere.marathon.api.MarathonExceptionMapper.toResponse(java.lang.Throwable)] is synthetic and is being intercepted by [mesosphere.marathon.DebugModule$MetricsBehavior@985696]. This could indicate a bug. The method may be intercepted twice, or may not be intercepted at all. (com.google.inject.internal.ProxyFactory:main)
[2016-12-12 21:05:36,115] INFO Logging initialized @1856ms (org.eclipse.jetty.util.log:main)
[2016-12-12 21:05:36,621] INFO Slf4jLogger started (akka.event.slf4j.Slf4jLogger:marathon-akka.actor.default-dispatcher-4)
[2016-12-12 21:05:36,800] INFO Started TaskTrackerUpdateStepsProcessorImpl with steps:
* continueOnError(notifyHealthCheckManager)
* continueOnError(notifyRateLimiter)
* continueOnError(notifyLaunchQueue)
* continueOnError(emitUpdate)
* continueOnError(postTaskStatusEvent)
* continueOnError(scaleApp) (mesosphere.marathon.core.task.tracker.impl.TaskTrackerUpdateStepProcessorImpl:main)
[2016-12-12 21:05:36,864] INFO Calling reviveOffers is enabled. Use --disable_revive_offers_for_new_apps to disable. (mesosphere.marathon.core.flow.FlowModule:main)
[2016-12-12 21:05:36,930] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authenticator' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:05:36,936] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:05:36,940] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authorizer' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:05:36,940] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-12 21:05:36,942] INFO Started status update processor (mesosphere.marathon.core.task.update.impl.TaskStatusUpdateProcessorImpl$$EnhancerByGuice$$ca7c928f:main)
[2016-12-12 21:05:37,047] INFO All actors suspended:
* Actor[akka://marathon/user/taskKillServiceActor#-984511042]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#671912224]
* Actor[akka://marathon/user/killOverdueStagedTasks#-698941106]
* Actor[akka://marathon/user/groupManager#-958454684]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1917290502]
* Actor[akka://marathon/user/offerMatcherManager#2056148696]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-308686880]
* Actor[akka://marathon/user/rateLimiter#-1808696027]
* Actor[akka://marathon/user/offersWantedForReconciliation#362759878]
* Actor[akka://marathon/user/launchQueue#-1787605975]
* Actor[akka://marathon/user/taskTracker#1265821735] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-12 21:05:37,115] INFO Adding HTTP support. (mesosphere.chaos.http.HttpModule:main)
[2016-12-12 21:05:37,116] INFO No HTTPS support configured. (mesosphere.chaos.http.HttpModule:main)
[2016-12-12 21:05:37,174] INFO Starting up (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:05:37,181] INFO jetty-9.3.z-SNAPSHOT (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,185] INFO Beginning run (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:05:37,188] INFO Will offer leadership after 500 milliseconds backoff (mesosphere.marathon.core.election.impl.CuratorElectionService:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-12 21:05:37,219] INFO Now standing by. Closing existing handles and rejecting new. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:05:37,416] INFO Registering com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,425] INFO Registering mesosphere.marathon.api.MarathonExceptionMapper as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,425] INFO Registering mesosphere.marathon.api.v2.AppsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,426] INFO Registering mesosphere.marathon.api.v2.TasksResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,428] INFO Registering mesosphere.marathon.api.v2.EventSubscriptionsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,429] INFO Registering mesosphere.marathon.api.v2.QueueResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,430] INFO Registering mesosphere.marathon.api.v2.GroupsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,431] INFO Registering mesosphere.marathon.api.v2.InfoResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,432] INFO Registering mesosphere.marathon.api.v2.LeaderResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,432] INFO Registering mesosphere.marathon.api.v2.DeploymentsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,433] INFO Registering mesosphere.marathon.api.v2.ArtifactsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,433] INFO Registering mesosphere.marathon.api.v2.SchemaResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,434] INFO Registering mesosphere.marathon.api.v2.PluginsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,437] INFO Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM' (com.sun.jersey.server.impl.application.WebApplicationImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,491] INFO Binding com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,508] INFO Binding mesosphere.marathon.api.MarathonExceptionMapper to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:37,717] INFO Using HA and therefore offering leadership (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,719] INFO Will do leader election through localhost:2181 (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,775] WARN session timeout [10000] is less than connection timeout [15000] (org.apache.curator.CuratorZookeeperClient:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,840] INFO Starting (org.apache.curator.framework.imps.CuratorFrameworkImpl:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,857] INFO Client environment:zookeeper.version=3.5.0-alpha-1615249, built on 08/01/2014 22:13 GMT (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,863] INFO Client environment:host.name=openshift-installer-native-docker-compose (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,864] INFO Client environment:java.version=1.8.0_102 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,864] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,865] INFO Client environment:java.home=/usr/lib/jvm/java-8-openjdk-amd64/jre (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,866] INFO Client environment:java.class.path=./bin/../target/marathon-assembly-1.3.6.jar (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,866] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,867] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,867] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,868] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,868] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,869] INFO Client environment:os.version=4.2.0-42-generic (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,869] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,870] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,870] INFO Client environment:user.dir=/marathon (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,870] INFO Client environment:os.memory.free=128MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,871] INFO Client environment:os.memory.max=880MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,871] INFO Client environment:os.memory.total=165MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,872] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.apache.curator.ConnectionState@2fba82d1 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-12 21:05:37,922] INFO Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:05:37,939] INFO Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:05:37,971] INFO Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x158f4c9e1f90006, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-12 21:05:37,978] INFO State change: CONNECTED (org.apache.curator.framework.state.ConnectionStateManager:ForkJoinPool-2-worker-13-EventThread)
[2016-12-12 21:05:38,049] INFO Elected (LeaderLatchListener Interface) (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-12 21:05:38,052] INFO As new leader running the driver (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:05:38,075] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=com.twitter.zk.EventBroker@2c6c37f7 (org.apache.zookeeper.ZooKeeper:pool-1-thread-1)
[2016-12-12 21:05:38,082] INFO Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:05:38,084] INFO Socket connection established to localhost/127.0.0.1:2181, initiating session (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:05:38,088] INFO Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x158f4c9e1f90007, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-12 21:05:38,174] INFO Migration successfully applied for version Version(1, 3, 6) (mesosphere.marathon.state.Migration:ForkJoinPool-2-worker-7)
[2016-12-12 21:05:38,176] INFO Call preDriverStarts callbacks on EntityStoreCache(MarathonStore(app:)), EntityStoreCache(MarathonStore(group:)), EntityStoreCache(MarathonStore(deployment:)), EntityStoreCache(MarathonStore(framework:)), EntityStoreCache(MarathonStore(taskFailure:)), EntityStoreCache(MarathonStore(events:)) (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:05:38,188] INFO Finished preDriverStarts callbacks (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-12 21:05:38,195] INFO no interest in offers for reservation reconciliation anymore. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-12 21:05:38,200] INFO Started. Will remain interested in offer reconciliation for 17500 milliseconds when needed. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-12 21:05:38,208] INFO started RateLimiterActor (mesosphere.marathon.core.launchqueue.impl.RateLimiterActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:05:38,209] INFO ExpungeOverdueLostTasksActor has started (mesosphere.marathon.core.task.jobs.impl.ExpungeOverdueLostTasksActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-12 21:05:38,216] INFO TaskTrackerActor is starting. Task loading initiated. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,222] INFO Create new Scheduler Driver with frameworkId: None and scheduler mesosphere.marathon.core.heartbeat.MesosHeartbeatMonitor$$EnhancerByGuice$$c730b9b8@46383a78 (mesosphere.marathon.MarathonSchedulerDriver$:pool-1-thread-1)
[2016-12-12 21:05:38,224] INFO All actors active:
* Actor[akka://marathon/user/taskKillServiceActor#-984511042]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#671912224]
* Actor[akka://marathon/user/killOverdueStagedTasks#-698941106]
* Actor[akka://marathon/user/groupManager#-958454684]
* Actor[akka://marathon/user/reviveOffersWhenWanted#1917290502]
* Actor[akka://marathon/user/offerMatcherManager#2056148696]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-308686880]
* Actor[akka://marathon/user/rateLimiter#-1808696027]
* Actor[akka://marathon/user/offersWantedForReconciliation#362759878]
* Actor[akka://marathon/user/launchQueue#-1787605975]
* Actor[akka://marathon/user/taskTracker#1265821735] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-4)
[2016-12-12 21:05:38,230] INFO About to load 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-5)
[2016-12-12 21:05:38,239] INFO Loaded 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-5)
[2016-12-12 21:05:38,257] INFO Task loading complete. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,284] INFO interested in offers for reservation reconciliation because of becoming leader (until 2016-12-12T21:05:55.712Z) (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-12 21:05:38,322] INFO Binding mesosphere.marathon.api.v2.AppsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,333] INFO Received offers WANTED notification (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,335] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,338] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,339] INFO => Schedule next revive at 2016-12-12T21:05:43.333Z in 4995 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,341] INFO Received offers WANTED notification (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-3)
[2016-12-12 21:05:38,356] INFO Binding mesosphere.marathon.api.v2.TasksResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,359] INFO Binding mesosphere.marathon.api.v2.EventSubscriptionsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,361] INFO Event notification disabled. (mesosphere.marathon.core.event.EventModule:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,375] INFO Binding mesosphere.marathon.api.v2.QueueResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,385] INFO Binding mesosphere.marathon.api.v2.GroupsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,390] INFO Binding mesosphere.marathon.api.v2.InfoResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,396] INFO Binding mesosphere.marathon.api.v2.LeaderResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,400] INFO Binding mesosphere.marathon.api.v2.DeploymentsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,418] INFO Binding mesosphere.marathon.api.v2.ArtifactsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,423] INFO Binding mesosphere.marathon.api.v2.SchemaResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,428] INFO Binding mesosphere.marathon.api.v2.PluginsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,429] INFO Loading plugins implementing 'mesosphere.marathon.plugin.http.HttpRequestHandler' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,431] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,452] INFO Started o.e.j.s.ServletContextHandler@33ffb91e{/,null,AVAILABLE} (org.eclipse.jetty.server.handler.ContextHandler:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1212 21:05:38.488497 223 sched.cpp:1697]
**************************************************
Scheduler driver bound to loopback interface! Cannot communicate with remote master(s). You might want to set 'LIBPROCESS_IP' environment variable to use a routable IP address.
**************************************************
[2016-12-12 21:05:38,494] INFO Started ServerConnector@23580056{HTTP/1.1,[http/1.1]}{0.0.0.0:7070} (org.eclipse.jetty.server.ServerConnector:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,496] INFO Started @4237ms (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-12 21:05:38,497] INFO All services up and running. (mesosphere.marathon.Main$:main)
I1212 21:05:38.524034 223 leveldb.cpp:174] Opened db in 33.764878ms
I1212 21:05:38.525073 223 leveldb.cpp:181] Compacted db in 985356ns
I1212 21:05:38.525146 223 leveldb.cpp:196] Created db iterator in 9599ns
I1212 21:05:38.525156 223 leveldb.cpp:202] Seeked to beginning of db in 501ns
I1212 21:05:38.525161 223 leveldb.cpp:271] Iterated through 0 keys in the db in 202ns
I1212 21:05:38.525203 223 replica.cpp:779] Replica recovered with log positions 0 -> 0 with 1 holes and 0 unlearned
I1212 21:05:38.526582 229 recover.cpp:451] Starting replica recovery
I1212 21:05:38.527250 229 recover.cpp:477] Replica is in EMPTY status
I1212 21:05:38.528532 229 replica.cpp:673] Replica in EMPTY status received a broadcasted recover request from (4)@127.0.0.1:33899
I1212 21:05:38.528669 229 recover.cpp:197] Received a recover response from a replica in EMPTY status
I1212 21:05:38.528774 229 recover.cpp:568] Updating replica status to STARTING
I1212 21:05:38.529911 232 master.cpp:375] Master e999af40-d59e-4d95-a77a-05403042ca4f (openshift-installer-native-docker-compose) started on 127.0.0.1:33899
I1212 21:05:38.530508 232 master.cpp:377] Flags at startup: --agent_ping_timeout="15secs" --agent_reregister_timeout="10mins" --allocation_interval="1secs" --allocator="HierarchicalDRF" --authenticate_agents="false" --authenticate_frameworks="false" --authenticate_http_frameworks="false" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticators="crammd5" --authorizers="local" --framework_sorter="drf" --help="false" --hostname_lookup="true" --http_authenticators="basic" --initialize_driver_logging="true" --log_auto_initialize="true" --logbufsecs="0" --logging_level="INFO" --max_agent_ping_timeouts="5" --max_completed_frameworks="50" --max_completed_tasks_per_framework="1000" --quiet="false" --recovery_agent_removal_limit="100%" --registry="replicated_log" --registry_fetch_timeout="1mins" --registry_store_timeout="20secs" --registry_strict="false" --root_submissions="true" --user_sorter="drf" --version="false" --webui_dir="/usr/share/mesos/webui" --work_dir="/tmp/mesos/local/X38lNg" --zk_session_timeout="10secs"
W1212 21:05:38.531312 232 master.cpp:380]
**************************************************
Master bound to loopback interface! Cannot communicate with remote schedulers or agents. You might want to set '--ip' flag to a routable IP address.
**************************************************
I1212 21:05:38.532498 232 master.cpp:429] Master allowing unauthenticated frameworks to register
I1212 21:05:38.532708 232 master.cpp:443] Master allowing unauthenticated agents to register
I1212 21:05:38.532913 232 master.cpp:457] Master allowing HTTP frameworks to register without authentication
I1212 21:05:38.533169 232 master.cpp:499] Using default 'crammd5' authenticator
W1212 21:05:38.533359 232 authenticator.cpp:512] No credentials provided, authentication requests will be refused
I1212 21:05:38.533457 232 authenticator.cpp:519] Initializing server SASL
I1212 21:05:38.532569 229 leveldb.cpp:304] Persisting metadata (8 bytes) to leveldb took 3.159782ms
I1212 21:05:38.534039 229 replica.cpp:320] Persisted replica status to STARTING
I1212 21:05:38.534257 229 recover.cpp:477] Replica is in STARTING status
I1212 21:05:38.534668 229 replica.cpp:673] Replica in STARTING status received a broadcasted recover request from (5)@127.0.0.1:33899
I1212 21:05:38.535151 229 recover.cpp:197] Received a recover response from a replica in STARTING status
I1212 21:05:38.540293 229 recover.cpp:568] Updating replica status to VOTING
Failed to start a local cluster while loading agent flags from the environment: Flag 'work_dir' is required, but it was not provided
(container):/marathon#

 

This error message is described in the documentation of the used Docker image as follows:

“Note: Currently the Docker container fails due to strange behavior from the latest Mesos version. There will be an error about work_dir that is still unresolved”

Unfortunately they did not provide any workaround or solution for the problem.

Resolution (Workaround):

I have found a workaround here: “It seems like explicitly setting the Mesos work directory by adding ENV MESOS_WORK_DIR /var/lib/mesos to the Dockerfile resolves the issue.”

I.e., we need to set the MESOS_WORK_DIR variable:

(dockerhost)$ sudo docker run -it --name marathon --rm --net=host -e MESOS_WORK_DIR=/var/lib/mesos --entrypoint=bash mesosphere/marathon
(container)# ./bin/start --master local --zk zk://localhost:2181/marathon --http_port=7070
MESOS_NATIVE_JAVA_LIBRARY is not set. Searching in /usr/lib /usr/local/lib.
MESOS_NATIVE_LIBRARY, MESOS_NATIVE_JAVA_LIBRARY set to '/usr/lib/libmesos.so'
No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.
[2016-12-13 13:55:36,831] INFO Starting Marathon 1.3.6/unknown with --master local --zk zk://localhost:2181/marathon --http_port=7070 (mesosphere.marathon.Main$:main)
[2016-12-13 13:55:37,118] WARN Method [public javax.ws.rs.core.Response mesosphere.marathon.api.MarathonExceptionMapper.toResponse(java.lang.Throwable)] is synthetic and is being intercepted by [mesosphere.marathon.DebugModule$MetricsBehavior@985696]. This could indicate a bug. The method may be intercepted twice, or may not be intercepted at all. (com.google.inject.internal.ProxyFactory:main)
[2016-12-13 13:55:37,371] INFO Logging initialized @1806ms (org.eclipse.jetty.util.log:main)
[2016-12-13 13:55:37,864] INFO Slf4jLogger started (akka.event.slf4j.Slf4jLogger:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:38,059] INFO Started TaskTrackerUpdateStepsProcessorImpl with steps:
* continueOnError(notifyHealthCheckManager)
* continueOnError(notifyRateLimiter)
* continueOnError(notifyLaunchQueue)
* continueOnError(emitUpdate)
* continueOnError(postTaskStatusEvent)
* continueOnError(scaleApp) (mesosphere.marathon.core.task.tracker.impl.TaskTrackerUpdateStepProcessorImpl:main)
[2016-12-13 13:55:38,119] INFO Calling reviveOffers is enabled. Use --disable_revive_offers_for_new_apps to disable. (mesosphere.marathon.core.flow.FlowModule:main)
[2016-12-13 13:55:38,196] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authenticator' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 13:55:38,200] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 13:55:38,204] INFO Loading plugins implementing 'mesosphere.marathon.plugin.auth.Authorizer' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 13:55:38,204] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:main)
[2016-12-13 13:55:38,208] INFO Started status update processor (mesosphere.marathon.core.task.update.impl.TaskStatusUpdateProcessorImpl$$EnhancerByGuice$$ca7c928f:main)
[2016-12-13 13:55:38,361] INFO All actors suspended:
* Actor[akka://marathon/user/launchQueue#872625406]
* Actor[akka://marathon/user/offerMatcherManager#1742672554]
* Actor[akka://marathon/user/reviveOffersWhenWanted#-965567836]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-1682888773]
* Actor[akka://marathon/user/offersWantedForReconciliation#-1611878367]
* Actor[akka://marathon/user/killOverdueStagedTasks#-1736387483]
* Actor[akka://marathon/user/taskTracker#-1718074132]
* Actor[akka://marathon/user/groupManager#1707955637]
* Actor[akka://marathon/user/taskKillServiceActor#-2061381059]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-786726035]
* Actor[akka://marathon/user/rateLimiter#-27927539] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 13:55:38,466] INFO Adding HTTP support. (mesosphere.chaos.http.HttpModule:main)
[2016-12-13 13:55:38,466] INFO No HTTPS support configured. (mesosphere.chaos.http.HttpModule:main)
[2016-12-13 13:55:38,518] INFO Starting up (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 13:55:38,519] INFO Beginning run (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 13:55:38,522] INFO Will offer leadership after 500 milliseconds backoff (mesosphere.marathon.core.election.impl.CuratorElectionService:MarathonSchedulerService$$EnhancerByGuice$$4bb98838)
[2016-12-13 13:55:38,525] INFO jetty-9.3.z-SNAPSHOT (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,555] INFO Now standing by. Closing existing handles and rejecting new. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-4)
[2016-12-13 13:55:38,727] INFO Registering com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,730] INFO Registering mesosphere.marathon.api.MarathonExceptionMapper as a provider class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,730] INFO Registering mesosphere.marathon.api.v2.AppsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,730] INFO Registering mesosphere.marathon.api.v2.TasksResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,730] INFO Registering mesosphere.marathon.api.v2.EventSubscriptionsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,730] INFO Registering mesosphere.marathon.api.v2.QueueResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.GroupsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.InfoResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.LeaderResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.DeploymentsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.ArtifactsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,731] INFO Registering mesosphere.marathon.api.v2.SchemaResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,733] INFO Registering mesosphere.marathon.api.v2.PluginsResource as a root resource class (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,737] INFO Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM' (com.sun.jersey.server.impl.application.WebApplicationImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,785] INFO Binding com.codahale.metrics.jersey.InstrumentedResourceMethodDispatchAdapter to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:38,802] INFO Binding mesosphere.marathon.api.MarathonExceptionMapper to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,057] INFO Using HA and therefore offering leadership (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,060] INFO Will do leader election through localhost:2181 (mesosphere.marathon.core.election.impl.CuratorElectionService:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,119] WARN session timeout [10000] is less than connection timeout [15000] (org.apache.curator.CuratorZookeeperClient:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,136] INFO Starting (org.apache.curator.framework.imps.CuratorFrameworkImpl:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,153] INFO Client environment:zookeeper.version=3.5.0-alpha-1615249, built on 08/01/2014 22:13 GMT (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:host.name=openshift-installer-native-docker-compose (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.version=1.8.0_102 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.home=/usr/lib/jvm/java-8-openjdk-amd64/jre (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.class.path=./bin/../target/marathon-assembly-1.3.6.jar (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.version=4.2.0-42-generic (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:user.dir=/marathon (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.memory.free=118MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.memory.max=880MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Client environment:os.memory.total=159MB (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,154] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=org.apache.curator.ConnectionState@3da7f0be (org.apache.zookeeper.ZooKeeper:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,183] INFO Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 13:55:39,195] INFO Socket connection established to localhost/127.0.0.1:2181, initiating session (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 13:55:39,230] INFO Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x158f4c9e1f9000d, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:ForkJoinPool-2-worker-13-SendThread(localhost:2181))
[2016-12-13 13:55:39,236] INFO State change: CONNECTED (org.apache.curator.framework.state.ConnectionStateManager:ForkJoinPool-2-worker-13-EventThread)
[2016-12-13 13:55:39,309] INFO Binding mesosphere.marathon.api.v2.AppsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,328] INFO Binding mesosphere.marathon.api.v2.TasksResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,331] INFO Binding mesosphere.marathon.api.v2.EventSubscriptionsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,331] INFO Event notification disabled. (mesosphere.marathon.core.event.EventModule:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,334] INFO Elected (LeaderLatchListener Interface) (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-13 13:55:39,338] INFO As new leader running the driver (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 13:55:39,341] INFO Binding mesosphere.marathon.api.v2.QueueResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,351] INFO Binding mesosphere.marathon.api.v2.GroupsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,356] INFO Initiating client connection, connectString=localhost:2181 sessionTimeout=10000 watcher=com.twitter.zk.EventBroker@44a67b18 (org.apache.zookeeper.ZooKeeper:pool-1-thread-1)
[2016-12-13 13:55:39,357] INFO Binding mesosphere.marathon.api.v2.InfoResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,360] INFO Binding mesosphere.marathon.api.v2.LeaderResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,364] INFO Binding mesosphere.marathon.api.v2.DeploymentsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,369] INFO Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 13:55:39,369] INFO Socket connection established to localhost/127.0.0.1:2181, initiating session (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 13:55:39,374] INFO Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x158f4c9e1f9000e, negotiated timeout = 10000 (org.apache.zookeeper.ClientCnxn:pool-1-thread-1-SendThread(localhost:2181))
[2016-12-13 13:55:39,378] INFO Binding mesosphere.marathon.api.v2.ArtifactsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,380] INFO Binding mesosphere.marathon.api.v2.SchemaResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,391] INFO Binding mesosphere.marathon.api.v2.PluginsResource to GuiceManagedComponentProvider with the scope "Singleton" (com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,392] INFO Loading plugins implementing 'mesosphere.marathon.plugin.http.HttpRequestHandler' from these urls: [] (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,392] INFO Found 0 plugins. (mesosphere.marathon.core.plugin.impl.PluginManagerImpl:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,407] INFO Started o.e.j.s.ServletContextHandler@72f0fd27{/,null,AVAILABLE} (org.eclipse.jetty.server.handler.ContextHandler:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,419] INFO Started ServerConnector@3c2f8cd8{HTTP/1.1,[http/1.1]}{0.0.0.0:7070} (org.eclipse.jetty.server.ServerConnector:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,419] INFO Started @3855ms (org.eclipse.jetty.server.Server:HttpService$$EnhancerByGuice$$1fd57a30 STARTING)
[2016-12-13 13:55:39,420] INFO All services up and running. (mesosphere.marathon.Main$:main)
[2016-12-13 13:55:39,464] INFO Migration successfully applied for version Version(1, 3, 6) (mesosphere.marathon.state.Migration:ForkJoinPool-2-worker-5)
[2016-12-13 13:55:39,464] INFO Call preDriverStarts callbacks on EntityStoreCache(MarathonStore(app:)), EntityStoreCache(MarathonStore(group:)), EntityStoreCache(MarathonStore(deployment:)), EntityStoreCache(MarathonStore(framework:)), EntityStoreCache(MarathonStore(taskFailure:)), EntityStoreCache(MarathonStore(events:)) (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 13:55:39,482] INFO Finished preDriverStarts callbacks (mesosphere.marathon.MarathonSchedulerService$$EnhancerByGuice$$4bb98838:pool-1-thread-1)
[2016-12-13 13:55:39,485] INFO no interest in offers for reservation reconciliation anymore. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:39,487] INFO Started. Will remain interested in offer reconciliation for 17500 milliseconds when needed. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:39,498] INFO started RateLimiterActor (mesosphere.marathon.core.launchqueue.impl.RateLimiterActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 13:55:39,501] INFO ExpungeOverdueLostTasksActor has started (mesosphere.marathon.core.task.jobs.impl.ExpungeOverdueLostTasksActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 13:55:39,506] INFO All actors active:
* Actor[akka://marathon/user/launchQueue#872625406]
* Actor[akka://marathon/user/offerMatcherManager#1742672554]
* Actor[akka://marathon/user/reviveOffersWhenWanted#-965567836]
* Actor[akka://marathon/user/expungeOverdueLostTasks#-1682888773]
* Actor[akka://marathon/user/offersWantedForReconciliation#-1611878367]
* Actor[akka://marathon/user/killOverdueStagedTasks#-1736387483]
* Actor[akka://marathon/user/taskTracker#-1718074132]
* Actor[akka://marathon/user/groupManager#1707955637]
* Actor[akka://marathon/user/taskKillServiceActor#-2061381059]
* Actor[akka://marathon/user/offerMatcherLaunchTokens#-786726035]
* Actor[akka://marathon/user/rateLimiter#-27927539] (mesosphere.marathon.core.leadership.impl.LeadershipCoordinatorActor:marathon-akka.actor.default-dispatcher-8)
[2016-12-13 13:55:39,509] INFO TaskTrackerActor is starting. Task loading initiated. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 13:55:39,522] INFO About to load 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-13)
[2016-12-13 13:55:39,528] INFO Loaded 0 tasks (mesosphere.marathon.core.task.tracker.impl.TaskLoaderImpl:ForkJoinPool-2-worker-5)
[2016-12-13 13:55:39,537] INFO Task loading complete. (mesosphere.marathon.core.task.tracker.impl.TaskTrackerActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,568] INFO interested in offers for reservation reconciliation because of becoming leader (until 2016-12-13T13:55:57.005Z) (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:39,589] INFO Received offers WANTED notification (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,589] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,596] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,597] INFO => Schedule next revive at 2016-12-13T13:55:44.589Z in 4993 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,655] INFO Create new Scheduler Driver with frameworkId: Some(value: "44a35e16-dc32-4f91-afac-33dfff498944-0000"
) and scheduler mesosphere.marathon.core.heartbeat.MesosHeartbeatMonitor$$EnhancerByGuice$$c730b9b8@4eb166a1 (mesosphere.marathon.MarathonSchedulerDriver$:pool-1-thread-1)
WARNING: Logging before InitGoogleLogging() is written to STDERR
W1213 13:55:39.779234 64 sched.cpp:1697]
**************************************************
Scheduler driver bound to loopback interface! Cannot communicate with remote master(s). You might want to set 'LIBPROCESS_IP' environment variable to use a routable IP address.
**************************************************
I1213 13:55:39.809289 64 leveldb.cpp:174] Opened db in 28.534471ms
I1213 13:55:39.811184 64 leveldb.cpp:181] Compacted db in 1.79725ms
I1213 13:55:39.811257 64 leveldb.cpp:196] Created db iterator in 11125ns
I1213 13:55:39.811283 64 leveldb.cpp:202] Seeked to beginning of db in 670ns
I1213 13:55:39.811290 64 leveldb.cpp:271] Iterated through 0 keys in the db in 197ns
I1213 13:55:39.811357 64 replica.cpp:779] Replica recovered with log positions 0 -> 0 with 1 holes and 0 unlearned
I1213 13:55:39.812511 77 recover.cpp:451] Starting replica recovery
I1213 13:55:39.812706 77 recover.cpp:477] Replica is in EMPTY status
I1213 13:55:39.813297 77 replica.cpp:673] Replica in EMPTY status received a broadcasted recover request from (3)@127.0.0.1:40102
I1213 13:55:39.813491 77 recover.cpp:197] Received a recover response from a replica in EMPTY status
I1213 13:55:39.813727 77 recover.cpp:568] Updating replica status to STARTING
I1213 13:55:39.815317 73 master.cpp:375] Master d4536c66-4886-4c88-9a02-7dac4b5f2e6d (openshift-installer-native-docker-compose) started on 127.0.0.1:40102
I1213 13:55:39.815476 73 master.cpp:377] Flags at startup: --agent_ping_timeout="15secs" --agent_reregister_timeout="10mins" --allocation_interval="1secs" --allocator="HierarchicalDRF" --authenticate_agents="false" --authenticate_frameworks="false" --authenticate_http_frameworks="false" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticators="crammd5" --authorizers="local" --framework_sorter="drf" --help="false" --hostname_lookup="true" --http_authenticators="basic" --initialize_driver_logging="true" --log_auto_initialize="true" --logbufsecs="0" --logging_level="INFO" --max_agent_ping_timeouts="5" --max_completed_frameworks="50" --max_completed_tasks_per_framework="1000" --quiet="false" --recovery_agent_removal_limit="100%" --registry="replicated_log" --registry_fetch_timeout="1mins" --registry_store_timeout="20secs" --registry_strict="false" --root_submissions="true" --user_sorter="drf" --version="false" --webui_dir="/usr/share/mesos/webui" --work_dir="/var/lib/mesos" --zk_session_timeout="10secs"
W1213 13:55:39.815767 73 master.cpp:380]
**************************************************
Master bound to loopback interface! Cannot communicate with remote schedulers or agents. You might want to set '--ip' flag to a routable IP address.
**************************************************
I1213 13:55:39.815810 73 master.cpp:429] Master allowing unauthenticated frameworks to register
I1213 13:55:39.815817 73 master.cpp:443] Master allowing unauthenticated agents to register
I1213 13:55:39.815824 73 master.cpp:457] Master allowing HTTP frameworks to register without authentication
I1213 13:55:39.815835 73 master.cpp:499] Using default 'crammd5' authenticator
W1213 13:55:39.815845 73 authenticator.cpp:512] No credentials provided, authentication requests will be refused
I1213 13:55:39.815851 73 authenticator.cpp:519] Initializing server SASL
I1213 13:55:39.817608 77 leveldb.cpp:304] Persisting metadata (8 bytes) to leveldb took 3.763381ms
I1213 13:55:39.817780 77 replica.cpp:320] Persisted replica status to STARTING
I1213 13:55:39.817886 77 recover.cpp:477] Replica is in STARTING status
I1213 13:55:39.818063 77 replica.cpp:673] Replica in STARTING status received a broadcasted recover request from (7)@127.0.0.1:40102
I1213 13:55:39.818200 77 recover.cpp:197] Received a recover response from a replica in STARTING status
I1213 13:55:39.818279 77 recover.cpp:568] Updating replica status to VOTING
I1213 13:55:39.819156 77 leveldb.cpp:304] Persisting metadata (8 bytes) to leveldb took 782170ns
I1213 13:55:39.819229 77 replica.cpp:320] Persisted replica status to VOTING
I1213 13:55:39.819284 77 recover.cpp:582] Successfully joined the Paxos group
I1213 13:55:39.819321 77 recover.cpp:466] Recover process terminated
I1213 13:55:39.820673 64 containerizer.cpp:196] Using isolation: posix/cpu,posix/mem,filesystem/posix,network/cni
I1213 13:55:39.823923 73 master.cpp:1847] The newly elected leader is master@127.0.0.1:40102 with id d4536c66-4886-4c88-9a02-7dac4b5f2e6d
I1213 13:55:39.823953 73 master.cpp:1860] Elected as the leading master!
I1213 13:55:39.823961 73 master.cpp:1547] Recovering from registrar
I1213 13:55:39.824046 73 registrar.cpp:332] Recovering registrar
I1213 13:55:39.824394 73 log.cpp:553] Attempting to start the writer
I1213 13:55:39.824522 73 slave.cpp:198] Agent started on 1)@127.0.0.1:40102
I1213 13:55:39.824532 73 slave.cpp:199] Flags at startup: --appc_simple_discovery_uri_prefix="http://" --appc_store_dir="/tmp/mesos/store/appc" --authenticate_http_readonly="false" --authenticate_http_readwrite="false" --authenticatee="crammd5" --authentication_backoff_factor="1secs" --authorizer="local" --cgroups_cpu_enable_pids_and_tids_count="false" --cgroups_enable_cfs="false" --cgroups_hierarchy="/sys/fs/cgroup" --cgroups_limit_swap="false" --cgroups_root="mesos" --container_disk_watch_interval="15secs" --containerizers="mesos" --default_role="*" --disk_watch_interval="1mins" --docker="docker" --docker_kill_orphans="true" --docker_registry="https://registry-1.docker.io" --docker_remove_delay="6hrs" --docker_socket="/var/run/docker.sock" --docker_stop_timeout="0ns" --docker_store_dir="/tmp/mesos/store/docker" --docker_volume_checkpoint_dir="/var/run/mesos/isolators/docker/volume" --enforce_container_disk_quota="false" --executor_registration_timeout="1mins" --executor_shutdown_grace_period="5secs" --fetcher_cache_dir="/tmp/mesos/fetch" --fetcher_cache_size="2GB" --frameworks_home="" --gc_delay="1weeks" --gc_disk_headroom="0.1" --hadoop_home="" --help="true" --hostname_lookup="true" --http_authenticators="basic" --http_command_executor="false" --image_provisioner_backend="copy" --initialize_driver_logging="true" --isolation="posix/cpu,posix/mem" --launcher="posix" --launcher_dir="/usr/libexec/mesos" --logbufsecs="0" --logging_level="INFO" --oversubscribed_resources_interval="15secs" --perf_duration="10secs" --perf_interval="1mins" --qos_correction_interval_min="0ns" --quiet="false" --recover="reconnect" --recovery_timeout="15mins" --registration_backoff_factor="1secs" --revocable_cpu_low_priority="true" --sandbox_directory="/mnt/mesos/sandbox" --strict="true" --switch_user="true" --systemd_enable_support="true" --systemd_runtime_directory="/run/systemd/system" --version="false" --work_dir="/var/lib/mesos/0"
W1213 13:55:39.824811 73 slave.cpp:202]
**************************************************
Agent bound to loopback interface! Cannot communicate with remote master(s). You might want to set '--ip' flag to a routable IP address.
**************************************************
I1213 13:55:39.825176 73 slave.cpp:519] Agent resources: cpus(*):2; mem(*):2928; disk(*):34068; ports(*):[31000-32000]
I1213 13:55:39.825285 73 slave.cpp:527] Agent attributes: [ ]
I1213 13:55:39.825294 73 slave.cpp:532] Agent hostname: openshift-installer-native-docker-compose
I1213 13:55:39.825721 73 state.cpp:57] Recovering state from '/var/lib/mesos/0/meta'
I1213 13:55:39.826089 73 status_update_manager.cpp:200] Recovering status update manager
I1213 13:55:39.826179 73 containerizer.cpp:522] Recovering containerizer
I1213 13:55:39.826676 72 replica.cpp:493] Replica received implicit promise request from (21)@127.0.0.1:40102 with proposal 1
I1213 13:55:39.826875 74 provisioner.cpp:253] Provisioner recovery complete
I1213 13:55:39.828560 74 slave.cpp:4782] Finished recovery
I1213 13:55:39.829459 74 slave.cpp:895] New master detected at master@127.0.0.1:40102
I1213 13:55:39.829998 74 slave.cpp:916] No credentials provided. Attempting to register without authentication
I1213 13:55:39.829576 72 leveldb.cpp:304] Persisting metadata (8 bytes) to leveldb took 1.862869ms
I1213 13:55:39.830559 72 replica.cpp:342] Persisted promised to 1
I1213 13:55:39.830961 72 coordinator.cpp:238] Coordinator attempting to fill missing positions
I1213 13:55:39.829550 75 status_update_manager.cpp:174] Pausing sending status updates
I1213 13:55:39.830510 74 slave.cpp:927] Detecting new master
I1213 13:55:39.831506 77 replica.cpp:388] Replica received explicit promise request from (23)@127.0.0.1:40102 for position 0 with proposal 2
I1213 13:55:39.832626 77 leveldb.cpp:341] Persisting action (8 bytes) to leveldb took 920616ns
I1213 13:55:39.832670 77 replica.cpp:712] Persisted action at 0
I1213 13:55:39.833004 75 replica.cpp:537] Replica received write request for position 0 from (24)@127.0.0.1:40102
I1213 13:55:39.834054 75 leveldb.cpp:436] Reading position from leveldb took 40734ns
I1213 13:55:39.835325 75 leveldb.cpp:341] Persisting action (14 bytes) to leveldb took 722995ns
I1213 13:55:39.835367 75 replica.cpp:712] Persisted action at 0
I1213 13:55:39.835605 75 replica.cpp:691] Replica received learned notice for position 0 from @0.0.0.0:0
I1213 13:55:39.836382 75 leveldb.cpp:341] Persisting action (16 bytes) to leveldb took 699339ns
I1213 13:55:39.836410 75 replica.cpp:712] Persisted action at 0
I1213 13:55:39.836419 75 replica.cpp:697] Replica learned NOP action at position 0
I1213 13:55:39.836597 75 log.cpp:569] Writer started with ending position 0
I1213 13:55:39.836915 75 leveldb.cpp:436] Reading position from leveldb took 12450ns
I1213 13:55:39.838395 77 registrar.cpp:365] Successfully fetched the registry (0B) in 14.328064ms
I1213 13:55:39.838459 77 registrar.cpp:464] Applied 1 operations in 4626ns; attempting to update the 'registry'
I1213 13:55:39.840064 77 log.cpp:577] Attempting to append 226 bytes to the log
I1213 13:55:39.840198 77 coordinator.cpp:348] Coordinator attempting to write APPEND action at position 1
I1213 13:55:39.840348 77 replica.cpp:537] Replica received write request for position 1 from (25)@127.0.0.1:40102
I1213 13:55:39.842838 77 leveldb.cpp:341] Persisting action (245 bytes) to leveldb took 2.394634ms
I1213 13:55:39.848156 77 replica.cpp:712] Persisted action at 1
I1213 13:55:39.848462 77 replica.cpp:691] Replica received learned notice for position 1 from @0.0.0.0:0
I1213 13:55:39.849424 77 leveldb.cpp:341] Persisting action (247 bytes) to leveldb took 911778ns
I1213 13:55:39.849508 77 replica.cpp:712] Persisted action at 1
I1213 13:55:39.849520 77 replica.cpp:697] Replica learned APPEND action at position 1
I1213 13:55:39.849964 77 registrar.cpp:509] Successfully updated the 'registry' in 11.484928ms
I1213 13:55:39.850054 77 registrar.cpp:395] Successfully recovered registrar
I1213 13:55:39.850160 77 master.cpp:1655] Recovered 0 agents from the Registry (187B) ; allowing 10mins for agents to re-register
I1213 13:55:39.850020 75 log.cpp:596] Attempting to truncate the log to 1
I1213 13:55:39.850306 75 coordinator.cpp:348] Coordinator attempting to write TRUNCATE action at position 2
I1213 13:55:39.850533 75 replica.cpp:537] Replica received write request for position 2 from (26)@127.0.0.1:40102
I1213 13:55:39.851971 75 leveldb.cpp:341] Persisting action (16 bytes) to leveldb took 1.375167ms
I1213 13:55:39.852044 75 replica.cpp:712] Persisted action at 2
I1213 13:55:39.852219 75 replica.cpp:691] Replica received learned notice for position 2 from @0.0.0.0:0
I1213 13:55:39.853096 75 leveldb.cpp:341] Persisting action (18 bytes) to leveldb took 825996ns
I1213 13:55:39.853198 75 leveldb.cpp:399] Deleting ~1 keys from leveldb took 55808ns
I1213 13:55:39.853235 75 replica.cpp:712] Persisted action at 2
I1213 13:55:39.853245 75 replica.cpp:697] Replica learned TRUNCATE action at position 2
I1213 13:55:39.855962 68 sched.cpp:226] Version: 1.0.1
I1213 13:55:39.857800 75 sched.cpp:330] New master detected at master@127.0.0.1:40102
I1213 13:55:39.857892 75 sched.cpp:341] No credentials provided. Attempting to register without authentication
I1213 13:55:39.858000 75 master.cpp:2424] Received SUBSCRIBE call for framework 'marathon' at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:39.858047 75 master.cpp:2500] Subscribing framework marathon with checkpointing enabled and capabilities [ ]
I1213 13:55:39.858240 75 hierarchical.cpp:271] Added framework 44a35e16-dc32-4f91-afac-33dfff498944-0000
I1213 13:55:39.858304 74 sched.cpp:743] Framework registered with 44a35e16-dc32-4f91-afac-33dfff498944-0000
[2016-12-13 13:55:39,867] INFO Starting scheduler actor (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,875] INFO Scheduler actor ready (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,876] INFO Became active. Accepting event streaming requests. (mesosphere.marathon.core.event.impl.stream.HttpEventStreamActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:39,876] INFO Reset offerLeadership backoff (mesosphere.marathon.core.election.impl.ExponentialBackoff:pool-1-thread-1)
[2016-12-13 13:55:39,901] INFO Creating tombstone for old twitter commons leader election (mesosphere.marathon.core.election.impl.CuratorElectionService:pool-1-thread-1)
[2016-12-13 13:55:39,908] INFO Registered as 44a35e16-dc32-4f91-afac-33dfff498944-0000 to master 'd4536c66-4886-4c88-9a02-7dac4b5f2e6d' (mesosphere.marathon.MarathonScheduler$$EnhancerByGuice$$1ef061b0:Thread-14)
[2016-12-13 13:55:39,908] INFO Store framework id: value: "44a35e16-dc32-4f91-afac-33dfff498944-0000"
 (mesosphere.util.state.FrameworkIdUtil:Thread-14)
[2016-12-13 13:55:39,925] INFO Received reviveOffers notification: SchedulerRegisteredEvent (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-4)
I1213 13:55:39.948446 72 master.cpp:4550] Registering agent at slave(1)@127.0.0.1:40102 (openshift-installer-native-docker-compose) with id d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0
I1213 13:55:39.948563 72 registrar.cpp:464] Applied 1 operations in 10900ns; attempting to update the 'registry'
I1213 13:55:39.949964 77 log.cpp:577] Attempting to append 424 bytes to the log
I1213 13:55:39.950723 77 coordinator.cpp:348] Coordinator attempting to write APPEND action at position 3
I1213 13:55:39.951776 76 replica.cpp:537] Replica received write request for position 3 from (27)@127.0.0.1:40102
I1213 13:55:39.952749 76 leveldb.cpp:341] Persisting action (443 bytes) to leveldb took 891144ns
I1213 13:55:39.952900 76 replica.cpp:712] Persisted action at 3
I1213 13:55:39.953106 76 replica.cpp:691] Replica received learned notice for position 3 from @0.0.0.0:0
I1213 13:55:39.953799 76 leveldb.cpp:341] Persisting action (445 bytes) to leveldb took 501557ns
I1213 13:55:39.953876 76 replica.cpp:712] Persisted action at 3
I1213 13:55:39.953902 76 replica.cpp:697] Replica learned APPEND action at position 3
I1213 13:55:39.954263 76 registrar.cpp:509] Successfully updated the 'registry' in 5.665024ms
I1213 13:55:39.954856 71 hierarchical.cpp:478] Added agent d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0 (openshift-installer-native-docker-compose) with cpus(*):2; mem(*):2928; disk(*):34068; ports(*):[31000-32000] (allocated: )
I1213 13:55:39.954433 75 log.cpp:596] Attempting to truncate the log to 3
I1213 13:55:39.955282 71 coordinator.cpp:348] Coordinator attempting to write TRUNCATE action at position 4
I1213 13:55:39.955612 71 replica.cpp:537] Replica received write request for position 4 from (28)@127.0.0.1:40102
I1213 13:55:39.955880 76 master.cpp:4619] Registered agent d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0 at slave(1)@127.0.0.1:40102 (openshift-installer-native-docker-compose) with cpus(*):2; mem(*):2928; disk(*):34068; ports(*):[31000-32000]
I1213 13:55:39.956233 76 master.cpp:5725] Sending 1 offers to framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:39.956048 75 slave.cpp:1095] Registered with master master@127.0.0.1:40102; given agent ID d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0
I1213 13:55:39.957394 73 status_update_manager.cpp:181] Resuming sending status updates
I1213 13:55:39.957774 75 slave.cpp:1155] Forwarding total oversubscribed resources
I1213 13:55:39.958096 75 master.cpp:5002] Received update of agent d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0 at slave(1)@127.0.0.1:40102 (openshift-installer-native-docker-compose) with total oversubscribed resources
I1213 13:55:39.958235 75 hierarchical.cpp:542] Agent d4536c66-4886-4c88-9a02-7dac4b5f2e6d-S0 (openshift-installer-native-docker-compose) updated with oversubscribed resources (total: cpus(*):2; mem(*):2928; disk(*):34068; ports(*):[31000-32000], allocated: cpus(*):2; mem(*):2928; disk(*):34068; ports(*):[31000-32000])
I1213 13:55:39.956370 71 leveldb.cpp:341] Persisting action (16 bytes) to leveldb took 663264ns
I1213 13:55:39.958457 71 replica.cpp:712] Persisted action at 4
I1213 13:55:39.958593 71 replica.cpp:691] Replica received learned notice for position 4 from @0.0.0.0:0
I1213 13:55:39.959283 71 leveldb.cpp:341] Persisting action (18 bytes) to leveldb took 622339ns
I1213 13:55:39.959475 71 leveldb.cpp:399] Deleting ~2 keys from leveldb took 25791ns
I1213 13:55:39.959547 71 replica.cpp:712] Persisted action at 4
I1213 13:55:39.959604 71 replica.cpp:697] Replica learned TRUNCATE action at position 4
I1213 13:55:40.008047 73 master.cpp:3951] Processing DECLINE call for offers: [ d4536c66-4886-4c88-9a02-7dac4b5f2e6d-O0 ] for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
[2016-12-13 13:55:44,622] INFO Received TimedCheck (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:44,622] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-2)
I1213 13:55:44.624449 73 master.cpp:4046] Processing REVIVE call for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:44.626070 73 hierarchical.cpp:1022] Removed offer filters for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000
I1213 13:55:44.626485 73 master.cpp:5725] Sending 1 offers to framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
[2016-12-13 13:55:44,627] INFO 2 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-7)
[2016-12-13 13:55:44,630] INFO => Schedule next revive at 2016-12-13T13:55:49.621Z in 4995 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-7)
I1213 13:55:44.638694 71 master.cpp:3951] Processing DECLINE call for offers: [ d4536c66-4886-4c88-9a02-7dac4b5f2e6d-O1 ] for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:49.643371 71 master.cpp:4046] Processing REVIVE call for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
[2016-12-13 13:55:49,641] INFO Received TimedCheck (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 13:55:49,642] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 13:55:49,642] INFO 1 further revives still needed. Repeating reviveOffers according to --revive_offers_repetitions 3 (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-9)
[2016-12-13 13:55:49,643] INFO => Schedule next revive at 2016-12-13T13:55:54.640Z in 4999 milliseconds, adhering to --min_revive_offers_interval 5000 (ms) (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-9)
I1213 13:55:49.649920 71 hierarchical.cpp:1022] Removed offer filters for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000
I1213 13:55:49.652896 71 master.cpp:5725] Sending 1 offers to framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:49.664896 75 master.cpp:3951] Processing DECLINE call for offers: [ d4536c66-4886-4c88-9a02-7dac4b5f2e6d-O2 ] for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:54.672166 77 master.cpp:4046] Processing REVIVE call for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:54.672760 77 hierarchical.cpp:1022] Removed offer filters for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000
[2016-12-13 13:55:54,671] INFO Received TimedCheck (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:54,672] INFO => revive offers NOW, canceling any scheduled revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-2)
I1213 13:55:54.675570 77 master.cpp:5725] Sending 1 offers to framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:54.688268 75 master.cpp:3951] Processing DECLINE call for offers: [ d4536c66-4886-4c88-9a02-7dac4b5f2e6d-O3 ] for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
[2016-12-13 13:55:54,848] INFO initiate task reconciliation (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:54,859] INFO Requesting task reconciliation with the Mesos master (mesosphere.marathon.SchedulerActions:ForkJoinPool-2-worker-7)
I1213 13:55:54.862715 77 master.cpp:5398] Performing implicit task state reconciliation for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
[2016-12-13 13:55:54,862] INFO task reconciliation has finished (mesosphere.marathon.MarathonSchedulerActor:marathon-akka.actor.default-dispatcher-2)
[2016-12-13 13:55:54,871] INFO Message [mesosphere.marathon.MarathonSchedulerActor$TasksReconciled$] from Actor[akka://marathon/user/MarathonScheduler/$a#-694294900] to Actor[akka://marathon/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. (akka.actor.DeadLetterActorRef:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:57,020] INFO no interest in offers for reservation reconciliation anymore. (mesosphere.marathon.core.matcher.reconcile.impl.OffersWantedForReconciliationActor:marathon-akka.actor.default-dispatcher-5)
[2016-12-13 13:55:57,024] INFO Received offers NOT WANTED notification, canceling 0 revives (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
[2016-12-13 13:55:57,026] INFO => Suppress offers NOW (mesosphere.marathon.core.flow.impl.ReviveOffersActor:marathon-akka.actor.default-dispatcher-6)
I1213 13:55:57.036034 74 master.cpp:2882] Processing SUPPRESS call for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102
I1213 13:55:57.036320 74 hierarchical.cpp:1002] Suppressed offers for framework 44a35e16-dc32-4f91-afac-33dfff498944-0000
I1213 13:56:09.705217 73 master.cpp:5463] Performing explicit task state reconciliation for 1 tasks of framework 44a35e16-dc32-4f91-afac-33dfff498944-0000 (marathon) at scheduler-a6e2761a-1f40-4e86-bc73-63171f1435aa@127.0.0.1:40102

This has resolved the issue.

Summary

In this blog post we have performed following tasks:

  1. Started a Marathon + Mesos environment with ZooKeeper, Mesos Master, Mesos Agent (Slave) and Mesosphere Marathon.
  2. Started a “Hello World” application via Marathon in a default Mesos container.
  3. Tested the resiliency by killing a process managed by Marathon.
  4. Started a “Hello World” application via Marathon in a Docker container.
  5. Showed, what happens, if all CPU resources are reserved.
  6. Described many errors we have observed in the Appendix.

Our observations were:

  • Different from our expectation for Mesos and Marathon to be production-ready, the Mesos applications do not seem to be very robust: we have seen critical errors like “suicides” of the Mesos Master, ZooKeeper and Mesosphere Marathon. I.e., monitoring and watchdogs are key when using Mesos + Marathon in a production environment. Apart from the critical errors, there are some minor problems like “connection lost” messages on the Mesos Web Portal, non-working “Application Restart” functions on Mesosphere Marathon. All problems are discussed in Appendix A.1 to A.6.
  • We have demonstrated in Step 8, that Mesos will not allow for over-subscription of resources per default. I.e., if you have 2 CPU cores and you are reserving 1 CPU core of 2 instances each, all CPU resources are occupied and no other task instance can be started (it will reside in “waiting” state). Mesos’ CPU reservation feels similar to a hard assignment of resources (since over-subscription is not supported per default, as we have seen above), but under the hood, Mesos does not apply hard limits on the CPU usage, unless the Mesos slave has --cgroups_enable_cfs  (CFS = Completely Fair Scheduler) enabled. See also the second answer on this StackOverflow question. For more information on over-subscription by Mesos, see this Apache Mesos Documentation page.
  • Mesos supports processes run in Mesos containers as well as processes run on Docker containers.
  • We could demonstrate that Mesosphere Marathon does, what it is designed for: it will make sure that an application is restarted, if it has crashed or has been killed.

apache mesos 学习路线

第 1 部分 你好,Mesos …………………………………………… 1
1 初识 Mesos …………………………………………………………………… 3
1.1 遇见 Mesos …………………………………………………………………………………………… 4
1.1.1 理解它如何工作 ………………………………………………………………………… 5
1.1.2 虚拟机和容器的比较 …………………………………………………………………. 7
1.1.3 知道何时及为何使用 Mesos……………………………………………………….. 9
1.2 为什么我们要重新思考数据中心 ………………………………………………………… 10
1.2.1 资源划分 …………………………………………………………………………………. 11
1.2.2 应用部署 …………………………………………………………………………………. 12
1.3 Mesos 分布式架构 ………………………………………………………………………………. 13
1.3.1 masters …………………………………………………………………………………….. 13
1.3.2 slaves ………………………………………………………………………………………. 14
1.3.3 frameworks ………………………………………………………………………………. 15
1.4 小结 …………………………………………………………………………………………………… 15
2 使用 Mesos 管理数据中心资源 ………………………………………….17
2.1 Spark 简要介绍 …………………………………………………………………………………… 18
2.1.1 独立集群上的 Spark…………………………………………………………………. 18
2.1.2 Mesos 上的 Spark …………………………………………………………………….. 19
2.2 在 Mesos 上运行 Spark job ………………………………………………………………….. 21
2.2.1 在集合中寻找素数 …………………………………………………………………… 22
2.2.2 获取与打包代码 ………………………………………………………………………. 23
2.2.3 提交作业 …………………………………………………………………………………. 24
2.2.4 观察输出 …………………………………………………………………………………. 24
2.3 进一步探索 ………………………………………………………………………………………… 26
2.3.1 Mesos UI …………………………………………………………………………………. 26
2.3.2 Spark UI…………………………………………………………………………………… 26
2.4 小结 …………………………………………………………………………………………………… 28
第 2 部分 Mesos 核心……………………………………………. 31
3 安装 Mesos ………………………………………………………………….33
3.1 部署 Mesos …………………………………………………………………………………………. 34
3.1.1 Mesos 集群组件……………………………………………………………………….. 34
3.1.2 开发环境的注意事项 ……………………………………………………………….. 35
3.1.3 生产环境的注意事项 ……………………………………………………………….. 36
3.2 安装 Mesos 和 ZooKeeper ……………………………………………………………………. 38
3.2.1 使用安装包部署 ………………………………………………………………………. 38
3.2.2 从源文件编译并安装 ……………………………………………………………….. 40
3.3 配置 Mesos 和 ZooKeeper ……………………………………………………………………. 43
3.3.1 ZooKeeper 配置 ……………………………………………………………………….. 43
3.3.2 Mesos 配置………………………………………………………………………………. 45
3.4 安装并配置 Docker……………………………………………………………………………… 50
3.4.1 安装 Docker …………………………………………………………………………….. 51
3.4.2 配置 Docker …………………………………………………………………………….. 53
3.4.3 配置 Docker 专用的 Mesos slaves ……………………………………………… 54
3.5 升级 Mesos …………………………………………………………………………………………. 54
3.5.1 升级 Mesos masters ………………………………………………………………….. 55
3.5.2 升级 Mesos slaves …………………………………………………………………….. 55
3.6 小结 …………………………………………………………………………………………………… 56
4 Mesos 原理 ………………………………………………………………….57
4.1 调度和分配数据中心资源 …………………………………………………………………… 57
4.1.1 理解资源调度 ………………………………………………………………………….. 58
4.1.2 理解资源分配 ………………………………………………………………………….. 59
4.1.3 定制 Mesos slave 资源和属性 …………………………………………………… 61
4.2 使用容器隔离资源 ……………………………………………………………………………… 62
4.2.1 隔离并监控 CPU、内存和磁盘 ………………………………………………… 63
4.2.2 网络监控和限速 ………………………………………………………………………. 65
4.3 了解容错和高可用 ……………………………………………………………………………… 68
4.3.1 容错 ………………………………………………………………………………………… 70
4.3.2 高可用 …………………………………………………………………………………….. 70
4.3.3 处理出错和升级 ………………………………………………………………………. 70
4.4 小结 …………………………………………………………………………………………………… 76
5 日志记录和调试 ……………………………………………………………77
5.1 理解和配置 Mesos 日志记录 ……………………………………………………………….. 78
5.1.1 日志文件的路径和解释 ……………………………………………………………. 78
5.1.2 配置日志记录 ………………………………………………………………………….. 80
5.2 调试 Mesos 集群及其任务 …………………………………………………………………… 81
5.2.1 使用 Mesos Web 接口 ………………………………………………………………. 82
5.2.2 使用内置命令行工具 ……………………………………………………………….. 89
5.2.3 使用 Mesosphere 的 mesos-cli 工具 …………………………………………… 90
5.3 小结 …………………………………………………………………………………………………… 92

6 生产环境中的 Mesos ………………………………………………………93
6.1 监控 Mesos 和 Zookeeper 集群…………………………………………………………….. 94
6.1.1 监控 Mesos master ……………………………………………………………………. 94
6.1.2 监控 Mesos slave ……………………………………………………………………… 96
6.1.3 监控 ZooKeeper ……………………………………………………………………….. 97
6.2 修改 Mesos master 的法定数目 ……………………………………………………………. 99
6.2.1 添加 master 节点 ……………………………………………………………………. 100
6.2.2 移除 master 节点 ……………………………………………………………………. 100
6.2.3 替换 master 节点 ……………………………………………………………………. 101
6.3 安全和权限控制的实施 …………………………………………………………………….. 101
6.3.1 Slave 和 framework 的身份认证………………………………………………. 102
6.3.2 用户授权和访问控制列表 ………………………………………………………. 104
6.3.3 framework 速率限制……………………………………………………………….. 107
6.4 小结 …………………………………………………………………………………………………. 110
第 3 部分 运行 Mesos…………………………………………… 113
7 使用 Marathon 部署应用 ………………………………………………. 115
7.1 了解 Marathon…………………………………………………………………………………… 115
7.1.1 探索 Marathon 的 Web 接口和 API ………………………………………….. 117
7.1.2 服务发现和路由 …………………………………………………………………….. 118
7.2 部署 Marathon 和 HAProxy ……………………………………………………………….. 121
7.2.1 安装并配置 Marathon……………………………………………………………… 121
7.2.2 安装并配置 HAProxy……………………………………………………………… 124
7.3 创建并伸缩应用 ……………………………………………………………………………….. 127
7.3.1 部署简单的应用 …………………………………………………………………….. 127
7.3.2 部署 Docker 容器 …………………………………………………………………… 130
7.3.3 执行健康检查和滚动应用更新 ……………………………………………….. 131
7.4 创建应用组 ………………………………………………………………………………………. 134
7.4.1 理解应用组的构成 …………………………………………………………………. 134
7.4.2 部署应用组 ……………………………………………………………………………. 135
7.5 日志和调试 ………………………………………………………………………………………. 137
7.5.1 配置 Marathon 日志………………………………………………………………… 137
7.5.2 调试 Marathon 应用和任务……………………………………………………… 138
7.6 小结 …………………………………………………………………………………………………. 140
8 使用 Chronos 管理计划任务 ………………………………………….. 143
8.1 了解 Chronos…………………………………………………………………………………….. 144
8.1.1 探索 Chronos 的 Web 接口和 API ……………………………………………. 145
8.2 安装并配置 Chronos………………………………………………………………………….. 147
8.2.1 先决条件的检验 …………………………………………………………………….. 147
8.2.2 安装 Chronos………………………………………………………………………….. 148
8.2.3 配置 Chronos………………………………………………………………………….. 149
8.3 使用简单的作业来工作 …………………………………………………………………….. 150
8.3.1 创建基于计划的作业 ……………………………………………………………… 150
8.3.2 使用 Docker 创建基于计划的作业 ………………………………………….. 153
8.4 使用复杂的作业来工作 …………………………………………………………………….. 155
8.4.1 组合基于计划和基于依赖的作业 ……………………………………………. 155
8.4.2 形象化作业的依赖关系 ………………………………………………………….. 158
8.5 监控 Chronos 作业的输出和状态……………………………………………………….. 159
8.5.1 作业失败事件的通知和监控 …………………………………………………… 159
8.5.2 通过 Mesos 观察作业的标准输出和标准错误………………………….. 161
8.6 小结 …………………………………………………………………………………………………. 162
9 使用 Aurora 部署应用和管理计划任务 ……………………………… 165
9.1 Aurora 简介 ………………………………………………………………………………………. 166
9.1.1 Aurora 调度器 ………………………………………………………………………… 167
9.1.2 Thermos 执行器和观察者 ……………………………………………………….. 167
9.1.3 Aurora 的用户和管理员客户端 ……………………………………………….. 168
9.1.4 Aurora DSL(Domain-Speci?c Language,特定领域语言)……….. 169
9.2 部署 Aurora ………………………………………………………………………………………. 169
9.2.1 在开发环境尝试 Aurora………………………………………………………….. 170
9.2.2 构建和安装 Aurora…………………………………………………………………. 171
9.2.3 配置 Aurora……………………………………………………………………………. 174
9.3 部署应用 ………………………………………………………………………………………….. 178
9.3.1 部署一个简单的应用 ……………………………………………………………… 179
9.3.2 部署基于 Docker 的应用 ………………………………………………………… 182
9.4 管理计划任务 …………………………………………………………………………………… 184
9.4.1 创建 Cron 作业 ………………………………………………………………………. 184
9.4.2 创建基于 Docker 的 Cron 作业 ……………………………………………….. 185
9.5 管理 Aurora ………………………………………………………………………………………. 187
9.5.1 管理用户和配额 …………………………………………………………………….. 187
9.5.2 执行维护 ……………………………………………………………………………….. 189
9.6 小结 …………………………………………………………………………………………………. 190
10 framework 开发 ………………………………………………………. 191
10.1 framework 基础……………………………………………………………………………….. 192
10.1.1 编写 framework 的时机和缘由………………………………………………. 194
10.1.2 调度器的实现 ………………………………………………………………………. 194
10.1.3 执行器的实现 ………………………………………………………………………. 197
10.2 调度器开发 …………………………………………………………………………………….. 201
10.2.1 使用调度器 API……………………………………………………………………. 202
10.2.2 使用 SchedulerDriver…………………………………………………………….. 204
10.3 执行器开发 …………………………………………………………………………………….. 205
10.3.1 使用执行器 API……………………………………………………………………. 205
10.3.2 使用执行器驱动程序 ……………………………………………………………. 207
10.4 运行 framework……………………………………………………………………………….. 208
10.4.1 在开发环境中部署 ……………………………………………………………….. 208
10.4.2 生产环境部署的注意事项 …………………………………………………….. 210
10.5 小结 ……………………………………………………………………………………………….. 211
附录 A 案例研究 :Mesosphere DCOS,企业版 Mesos 分布式集群.. 213
附录 B Mesos 框架与工具的列表 …………………………………………. 225

老司机四个问题告诉你,你离大数据架构师有多远?

1.作为企业架构师,我们为什么需要构建数据结构?

数据结构主要有以下内容:

1)数据标准不一致

2)数据模型管理混乱

3)深入的性能的问题无法解决

4)SQL语句编写水平不高导致出现严重性能问题

5)开发人员对执行计划收悉

6)上线前缺乏审计

7)相对复杂的数据处理能力欠缺

8)数据质量差需要执行数据质量管理

数据是客户的财富,虽然对于我们开发人员一文不值,在客户那里就是无价之宝,保障数据的完成性,安全性,可靠性,必须要存在数据结构满足8大要求。

2.结合自身,说一下你离架构师有多远,还需要掌握哪些技术?

架构师首先有很多方向,作为架构师必须具有丰富的开发经验,是个技术主管。

因为他必须清楚什么是可以实现的,实现的方式有哪些,相应的难度怎么样,实现出来的系统面对需求变化的适应性等一系列指标。

另外,需要对面向过程、面向对象、面向服务等设计理念有深刻的理解,可以快速的察觉出实现中的问题并提出相应的改进(重构)方案(也就是通常说的反模式)。

这些都需要长期的开发实践才能真正的体会到,单从书本上很难领会到,就算当时理解了也不一定能融会到实践中去。

在技术能力上,软件架构师最重要也是最需要掌握的知识是构件通信机制方面的知识,包括进程内通信(对象访问、函数调用、数据交换、线程同步等)以及进程外(包括跨计算机)的通信(如RMI、DCOM、Web Service)。

在WEB应用大行其道的今天,开发者往往对服务器间的通信关注的比较多,而对进程内的通信较少关注。进程外跨机器通信是构建分布式应用的基石,它是架构设计中的鸟瞰视图;而进程内的通信是模块实现的骨架,它是基石的基石。

如果具体到一个基于.Net企业级架构设计,首先需要的是语言级别的认识,包括.NET的CLR、继承特性、委托和事件处理等。然后是常用解决方案的认识,包括ASP.NET Web Service、.NET Remoting、企业服务组件等。

总之,丰富的开发实践经验有助于避免架构师纸上谈兵式的高来高去,给代码编写人员带来实实在在的可行性。

其次,具有足够的行业业务知识和商业头脑也是很重要的。行业业务知识的足够把握可以给架构师更多的拥抱变化的能力,可以在系统设计的时候留出一些扩展的余地来适应可能来临的需求变化。

有经验的设计人员可能都碰到过这样的事,一厢情愿的保留接口在需求变化中的命中率非常低。也就是说,在系统设计之初为扩展性留下来的系统接口没能在需求变化的洪流中发挥真正的作用,因为需求的变化并没有按照预想的方向进行,到最后还是不得不为变化的业务重新设计系统。

这就是因为对业务知识的理解和对市场或者商业的判断没有达到一个实用的、可以为架构扩展性服务的水平。

再次,架构设计师对人的关注必须提升到架构设计之初来纳入考虑的范围,包括沟通以及对人员素质的判断。软件过程是团队协作共同构建系统的过程,沟通能力是将整个过程中多条开发线粘合在一起的胶水。

大家都应该碰到过事后说“原来是这样啊,我不知道啊”或者某个开发人员突然高声呼喊“为什么这里的数据没有了”之类的。沟通的目的就是尽量避免多条开发线的混乱,让系统构建过程可以有条理的高效进行。

另外,对人的关注还表现在对团队成员的素质判断上,比如哪些开发人员对哪些技术更熟悉,或者哪些开发人员容易拖进度等。只有合理的使用人力资源,让合适的人做合适的事情才能让整个软件过程更加高效。

架构师应时刻注意新软件设计和开发方面的发展情况,并不断探索更有效的新方法、开发语言、设计模式和开发平台不断很快地升级,软件架构师需要吸收这些新技术新知识,并将它们用于软件系统开发工作中。但对新技术的探索应该在一个理性的范围内进行,不能盲目的跟风。

解决方案提供商永远都希望你能使用它提供的最新技术,而且它们在推广自己的解决方案的时候往往是以自己的产品为中心,容易给人错觉。

比如数据库,往往让人觉得它什么都能做,只要有了它其它什么都不重要了。但事实上并不是如此,对于小型应用可以将许多业务逻辑用script的方式放入数据库中,但很少看到大型应用采用这样的做法。

对于新东西需要以一种比较的观点来判断,包括横向的比较和纵向的比较,最后得出一些性能、可移植性以及可升级等指标。另外,新入行的开发人员往往关心新技术动向而忽略了技术的历史,而从DOS时代一路杀过来的开发者就对现在的技术体系有较全面的把握。

3.如果你应聘架构师方面的工作,那么你认为设计架构具体都做些什么呢?

1):确认需求

在项目开发过程中,架构师是在需求规格说明书完成后介入的,需求规格说明书必须得到架构师的认可。架构师需要和分析人员反复交流,以保证自己完整并准确地理解用户需求。

2):系统分解

依据用户需求,架构师将系统整体分解为更小的子系统和组件,从而形成不同的逻辑层或服务。随后,架构师会确定各层的接口,层与层相互之间的关系。架构师不仅要对整个系统分层,进行“纵向”分解,还要对同一逻辑层分块,进行“横向”分解。

软件架构师的功力基本体现于此,这是一项相对复杂的工作。

3):技术选型

架构师通过对系统的一系列的分解,最终形成了软件的整体架构。技术选择主要取决于软件架构。

Web Server运行在Windows上还是Linux上?数据库采用MSSql、Oracle还是Mysql?需要不需要采用MVC或者Spring等轻量级的框架?前端采用富客户端还是瘦客户端方式?类似的工作,都需要在这个阶段提出,并进行评估。

架构师对产品和技术的选型仅仅限于评估,没有决定权,最终的决定权归项目经理。架构师提出的技术方案为项目经理提供了重要的参考信息,项目经理会从项目预算、人力资源、时间进度等实际情况进行权衡,最终进行确认。

4):制定技术规格说明

架构师在项目开发过程中,是技术权威。他需要协调所有的开发人员,与开发人员一直保持沟通,始终保证开发者依照它的架构意图去实现各项功能。

架构师不仅要保持与开发者的沟通,也需要与项目经理、需求分析员,甚至与最终用户保持沟通。所以,对于架构师来讲,不仅有技术方面的要求,还有人际交流方面的要求。

4.如果在一个成熟的企业里没有你所想象的架构师呢?或者说,架构师这种职业已经死亡或消失了呢?你会怎么定位你的职业?

如果在一个企业里没有架构师,那么我可以推动自己往这个方向努力发展。

如果在这个行业里不存在架构师,我想软件领域开发的软件质量应该也会存在很多问题。

没有架构师或者自己已经从事了架构师这个职位有了危机以后,我想对自己的职位依然做个肯定,因为业务永远会随着客户的需求存在,

既然有客户需求,业务就会产生,有业务产生,那必然少不了技术实现,可以做技术方案指导,都是很好的方向。

Shiro & CAS 实现单点登录

概览

单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录。

本文使用开源框架Jasig CAS来完成单点登录。下载地址:https://www.apereo.org/cas/download。在写本文时,使用的cas server版本为4.0.1

部署服务器

本文服务器使用Tomcat7,下载了cas-server-4.0.0-release.zip,将其解压,找到modules目录下面的cas-server-webapp-4.0.0.war直接复制到webapps文件夹下即可。启动Tomcat,访问http://localhost:8080/cas-server-webapp-4.0.0,使用casuser/Mellon登录,即可登录成功。

Tomcat默认没有开启HTTPS协议,所以这里直接用了HTTP协议访问。为了能使客户端在HTTP协议下单点登录成功,需要修改一下配置:

  • WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml和WEB-INF\spring-configuration\warnCookieGenerator.xml:将p:cookieSecure="true"改为p:cookieSecure="false"
  • WEB-INF\deployerConfigContext.xml:<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />添加p:requireSecure="false"

至此,一个简单的单点登录服务器就基本部署好了。

部署客户端

客户端需要添加对shiro-cas和cas-client-core这两个包的依赖。这里主要讲跟CAS相关的配置。

之后配置web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<!– 用于单点退出,该过滤器用于实现单点登出功能,可选配置。–>
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!– 该过滤器用于实现单点登出功能,可选配置。 –>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

自定义Realm:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyCasRealm extends CasRealm {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(userService.findRoles(username));
authorizationInfo.setStringPermissions(userService.findPermissions(username));
return authorizationInfo;
}
}

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
<bean id=“casRealm” class=“package.for.your.MyCasRealm”>
<property name=“userService” ref=“userService”/>
<property name=“cachingEnabled” value=“true”/>
<property name=“authenticationCachingEnabled” value=“true”/>
<property name=“authenticationCacheName” value=“authenticationCache”/>
<property name=“authorizationCachingEnabled” value=“true”/>
<property name=“authorizationCacheName” value=“authorizationCache”/>
<!–该地址为cas server地址 –>
<property name=“casServerUrlPrefix” value=“${shiro.casServer.url}/>
<!– 该地址为是当前应用 CAS 服务 URL,即用于接收并处理登录成功后的 Ticket 的,
必须和loginUrl中的service参数保持一致,否则服务器会判断service不匹配–>
<property name=“casService” value=“${shiro.client.cas}/>
</bean>

配置CAS过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<bean id=“casFilter” class=“org.apache.shiro.cas.CasFilter”>
<property name=“failureUrl” value=“/casFailure.jsp”/>
</bean>
<bean id=“shiroFilter” class=“org.apache.shiro.spring.web.ShiroFilterFactoryBean”>
<property name=“securityManager” ref=“securityManager”/>
<property name=“loginUrl” value=“${shiro.login.url}”/>
<property name=“successUrl” value=“${shiro.login.success.url}”/>
<property name=“filters”>
<util:map>
<entry key=“cas” value-ref=“casFilter”/>
<entry key=“logout” value-ref=“logoutFilter” />
</util:map>
</property>
<property name=“filterChainDefinitions”>
<value>
/casFailure.jsp = anon
/cas = cas
/logout = logout
/** = user
</value>
</property>
</bean>

上面登录url我的配置的是http://localhost:8080/cas-server/login?service=http://localhost:8080/cas-client/cas,service参数是之后服务将会跳转的地址。

/cas=cas:即/cas 地址是服务器端回调地址,使用 CasFilter 获取 Ticket 进行登录。

之后通过eclipse部署,访问http://localhost:8080/cas-client 即可测试。为了看到单点登录的效果,可以直接复制一份webapps中的client为client2,只需要修改上述配置中的地址即可。如果用户已经登录,那么访问http://localhost:8080/cas-client2发现不会再跳转到登录页面了,用户已经是登录状态了。

还需要注意一个问题,就是cas server默认是开启单点登出的但是这里却没有这样的效果,APP1登出了,但是APP2仍能访问,如果查看浏览器的cookie的话,会发现有两个sessionid,一个是JSESSIONID,容器原生的,另一个是shiro中配置的:

1
2
3
4
5
6
7
<!– 会话Cookie模板 –>
<bean id=“sessionIdCookie” class=“org.apache.shiro.web.servlet.SimpleCookie”>
SingleSignOutFilter发现是logoutRequest请求后,原来SingleSignOutHandler中创建的原生的session已经被销毁了,因为从a登出的,a的shiro session也会销毁,
但是b的shiro的session还没有被销毁,于是再访问b还是能访问,单点登出就有问题了–>
<constructor-arg value=“JSESSIONID”/>
<property name=“httpOnly” value=“true”/>
<property name=“maxAge” value=“-1”/>

如果我们把sid改为JSESSIONID会怎么样,答案是如果改为JSESSIONID会导致重定向循环,原因是当登录时,shiro发现浏览器发出的请求中的JSESSIONID没有或已经过期,于是生成一个JSESSIONID给浏览器,同时链接被重定向到服务器进行认证,认证成功后返回到客户端服务器的cas service url,并且带有一个ticket参数。因为有SingleSignOutFilter,当发现这是一个tocken请求时,SingleSignOutHandler会调用request.getSession()获取的是原生Session,如果没有原生session的话,又会创建并将JSESSIONID保存到浏览器cookie中,当客户端服务器向cas服务器验证ticket之后,客户端服务器重定向到之前的页面,这时shiro发现JSESSIONID是SingleSignOutHandler中生成的,在自己维护的session中查不到,又会重新生成新的session,然后login,然后又会重定向到cas服务器认证,然后再重定向到客户端服务器的cas service url,不同的是SingleSignOutHandler中这次调用session.getSession(true)不会新创建一个了,之后就如此循环。如果使用sid又会导致当单点登出时候,如果有a、b两个客户端服务器,从a登出,会跳转到cas服务器登出,cas服务器会对所有通过它认证的service调用销毁session的方法,但是b的shiro的session还没有被销毁,于是再访问b还是能访问,单点登出就有问题了

之所以这样是因为我设置shiro的session管理器为DefaultWebSessionManager,这个管理器直接抛弃了容器的session管理器,自己来维护session,所以就会出现上述描述的问题了。如果我们不做设置,那么shiro将使用默认的session管理器ServletContainerSessionManager:Web 环境,其直接使用 Servlet 容器的会话。这样单点登出就可以正常使用了。

此外如果我们非要使用DefaultWebSessionManager的话,我们就要重写一个SingleSignOutFilter、SingleSignOutHandler和SessionMappingStorage了。

如果没有使用Spring框架,则可以参考如下配置web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?xml version=“1.0” encoding=“UTF-8”?>
id=“WebApp_ID” version=“2.5”>
<display-name>YPshop Authority Manage</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>authority.root</param-value>
</context-param>
<!– ======================== 单点登录开始 ======================== –>
<!– 说明:这种客户端的配置方式是不需要Spring支持的 –>
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://localhost:8443/cas-server/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://localhost:8443</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://localhost:8443/cas-server</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://localhost:8443</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!– 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 比如AssertionHolder.getAssertion().getPrincipal().getName()。 –>
<filter>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!– ======================== 单点登录结束 ======================== –>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<distributable />
</web-app>

进阶

使用HTTPS协议

首先我们需要生成数字证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
keytool -genkey -keystore “D:\localhost.keystore” -alias localhost -keyalg RSA
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: xa
您的组织名称是什么?
[Unknown]: xa
您所在的城市或区域名称是什么?
[Unknown]: xi’an
您所在的省/市/自治区名称是什么?
[Unknown]: xi’an
该单位的双字母国家/地区代码是什么?
[Unknown]: cn
CN=localhost, OU=xa, O=xa, L=xi’an, ST=xi’an, C=cn 是否正确
?
[]: y
输入 <localhost> 的密钥口令
(如果和密钥库口令相同, 按回车):

需要注意的是 “您的名字与姓氏是什么?”这个地方不能随便填的,如果运行过程中提示“Caused by: java.security.cert.CertificateException: No name matching localhost found”那么就是因为这里设置错了,当然除了localhost也可以写其他的,如helloworld.com,但是需要能解析出来,可以直接在hosts中加127.0.0.1 helloworld.com

然后,由于Tomcat默认没有开HTTPS,所以我们需要在server.xml文件中找到8443出现的地方。然后修改如下

1
2
3
4
<Connector port=“8443” protocol=“HTTP/1.1” SSLEnabled=“true”
maxThreads=“150” scheme=“https” secure=“true”
clientAuth=“false” sslProtocol=“TLS”
keystoreFile=“D:\localhost.keystore” keystorePass=“123456”/>

keystorePass 就是生成 keystore 时设置的密码。

如果出现下面的问题,修改server.xml中的protocol为org.apache.coyote.http11.Http11Protocol

Failed to initialize end point associated with ProtocolHandler [“http-apr-8443”]
java.lang.Exception: Connector attribute SSLCertificateFile must be defined when using SSL with APR

因为 CAS client 需要使用该证书进行验证,所以我们要使用 localhost.keystore 导出数字证书(公钥)到 D:\localhost.cer。再将将证书导入到 JDK 中。

1
2
3
keytool -export –alias localhost -file D:\localhost.cer -keystore D:\localhost.keystore
cd D:\jdk1.7.0_21\jre\lib\security
keytool -import –alias localhost -file D:\localhost.cer -noprompt -trustcacerts -storetype jks -keystore cacerts -storepass 123456

如果导入失败,可以先把 security 目录下的 cacerts 删掉

搞定证书之后,我们需要将之前client中配置的地址修改一下。然后还可以添加ssl过滤器。

如果遇到以下异常,一般是证书导入错误造成的,请尝试重新导入,如果还是不行,有可能是运行应用的 JDK 和安装数字证书的 JDK 不是同一个造成的:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

单点登出重定向

客户端中配置logout过滤器

1
2
3
<bean id=“logoutFilter” class=“org.apache.shiro.web.filter.authc.LogoutFilter”>
<property name=“redirectUrl” value=“${shiro.logout.url}”/>
</bean>

WEB-INF/cas-servlet.xml中将 cas.logout.followServiceRedirects修改为true即可在登出后重定向到service参数提供的地址

单点登出

单点登出重定向是很好解决了,但是在客户端与shiro集成过程中,如客户端部署部分所述,如果shiro没有使用 ServletContainerSessionManager 管理session,单点登出就会有问题了。最简单奏效的办法就是改用 ServletContainerSessionManager 了,但是我们偏要用 DefaultWebSessionManager 呢,那就应该要参考org.jasig.cas.client.session这个包中的几个类,重新实现单点登出了。我的思路是,添加一个shiro过滤器,继承自AdviceFilter在preHandle方法中实现逻辑:如果请求中包含了ticket参数,记录ticket和sessionID的映射;如果请求中包含logoutRequest参数,标记session为无效;如果session不为空,且被标记为无效,则登出。如果请求中包含了logoutRequest参数,那么这个请求是从cas服务器发出的,所以这里不能直接用subject.logout(),因为subject跟线程绑定,客户端对cas服务器端的请求会创建一个新的subject。

那么CAS单点登出是怎么实现的呢,下面是我对CAS单点登出的简单理解:

在TicketGrantingTicketImpl有一个HashMap<string, service=””> services字段,以id和通过认证的客户端service为键值对。当我们要登出时LogoutManagerImpl通过for (final String ticketId : services.keySet())向每个service发送一个POST请求,请求中包含一个logoutRequest参数,参数的值由SamlCompliantLogoutMessageCreator创建。客户端的 SingleSignOutFilter会判断请求中是否包含了logoutRequest参数,如果包含,那么销毁session。SingleSignOutHttpSessionListener实现了javax.servlet.http.HttpSessionListener接口,用于监听session销毁事件。</string,>

我在配置的过程中发现单点登出有问题,首先在服务端打开 debug log,cas 服务器默认是打开单点登出功能的,所以正常的话日志中会记录<Sending logout request for: [https://localhost:8443/cas-client1/cas]>之类的内容,有日志记录发送了请求,一般服务器应该不会有什么问题了。那么有可能会是客户端的问题,我重新配置了一个客户端,这个客户端没有使用spring也没有使用shiro,只用了在部署客户端中提到的无spring的web.xml文件,发现从其他客户端登出,这个客户端也是登出的,所以这个配置是没有什么问题。后来在浏览器打开控制台才发现有两个SESSIONID一个是sid是在shiro中配置的,另一个是JSESSIONID,应该是容器原生的。再然后就下了3.2.2版本的cas-client-core,通过maven构建,导入eclipse中,开始调试。我们的cas-client要依赖这个cas-client-core工程,怎么设置可以参考eclipse小技巧。然后调试,一定要保证在cas-client的propertie 设置中的Deployment Assembly中已经没有之前的版本的cas-client-core的jar包了。调试的过程中才发现,SingleSignOutFilter销毁的是容器原生的session,但是shiro的session还在,所以如果是从其他客户端登出的,那这个客户端还是能够登录。

通过数据库中的用户密码认证

服务器端需要添加cas-server-support-jdbc和mysql-connector-java依赖。

cas-server-support-jdbc提供了org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler、org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler 和org.jasig.cas.adaptors.jdbc.QueryAndEncodeDatabaseAuthenticationHandler。他们都继承自AbstractJdbcUsernamePasswordAuthenticationHandler 能够通过配置sql语句验证用户凭证,后者更复杂些,能够配置盐,散列函数迭代次数。

下面说一下配置QueryDatabaseAuthenticationHandler,配置/src/main/webapp/WEB-INF/deployerConfigContext.xml,先注释掉原先的primaryAuthenticationHandler然后添加下面配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!– 自定义数据库鉴权 –>
<bean id=“primaryAuthenticationHandler” class=“org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler”>
<property name=“dataSource” ref=“dataSource”/>
<property name=“sql” value=“${auth.sql}/>
<property name=“passwordEncoder” ref=“MD5PasswordEncoder”/>
</bean>
<!– 数据源 –>
<bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>
<property name=“driverClassName” value=“${dataSource.driver}></property>
<property name=“url” value=“${dataSource.url}/>
<property name=“username” value=“${dataSource.username}/>
<property name=“password” value=“${dataSource.password}/>
</bean>
<!– MD5加密 –>
<bean id=“MD5PasswordEncoder” class=“org.jasig.cas.authentication.handler.DefaultPasswordEncoder”>
<constructor-arg value=“MD5”/>
</bean>

加密算法可以自定义。

添加验证码

验证码的实现使用了kaptcha,所以需要添加其依赖。

web.xml添加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<servlet>
<servlet-name>Kaptcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<!– 设定宽度 –>
<init-param>
<param-name>kaptcha.image.width</param-name>
<param-value>100</param-value>
</init-param>
<!– 设定高度 –>
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</param-value>
</init-param>
<!– 如果需要全部是数字 –>
<init-param>
<param-name>kaptcha.textproducer.char.string</param-name>
<param-value>0123456789</param-value>
</init-param>
<!– 去掉干扰线 –>
<init-param>
<param-name>kaptcha.noise.impl</param-name>
<param-value>com.google.code.kaptcha.impl.NoNoise </param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/captcha.jpg</url-pattern>
</servlet-mapping>

在login-webflow.xml中找到viewLoginForm,在binder节点下面添加<binding property="captcha" />,对应我们页面提交的验证码参数

然后我们还要实现一个UsernamePasswordCaptchaCredential 类,继承UsernamePasswordCredential 在其中添加了captcha字段和相应setter和getter方法。

1
2
3
4
5
6
7
8
public class UsernamePasswordCaptchaCredential extends UsernamePasswordCredential {
private static final long serialVersionUID = -2988130322912201986L;
@NotNull
@Size(min=1,message = “required.captcha”)
private String captcha;
//set、get方法
}

接着回到 login-webflow.xml ,找到credential的声明处,将org.jasig.cas.authentication.UsernamePasswordCredential修改为刚刚实现的类全路径名。viewLoginForm 也需要修改

1
2
3
<transition on=“submit” bind=“true” validate=“true” to=“validatorCaptcha”>
<evaluate expression=“authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)” />
</transition>

再添加如下配置

1
2
3
4
5
6
<!– 添加一个 validatorCaptcha 校验验证码的操作 –>
<action-state id=“validatorCaptcha”>
<evaluate expression=“authenticationViaFormAction.validatorCaptcha(flowRequestContext, flowScope.credential, messageContext)”></evaluate>
<transition on=“error” to=“generateLoginTicket” />
<transition on=“success” to=“realSubmit” />
</action-state>

我们在配置中添加了一个 validatorCaptcha 的操作,同时可以看到 expression 是 authenticationViaFormAction.validatorCaptcha(…),所以我们需要在 authenticationViaFormAction 中添加一个校验验证码的方法 validatorCaptcha()。authenticationViaFormAction 这个bean是配置在 cas-servlet.xml 中的:

1
2
3
4
<bean id=“authenticationViaFormAction” class=“org.jasig.cas.web.flow.AuthenticationViaFormAction”
p:centralAuthenticationService-ref=“centralAuthenticationService”
p:warnCookieGenerator-ref=“warnCookieGenerator”
p:ticketRegistry-ref=“ticketRegistry”/>

我们可以看看 org.jasig.cas.web.flow.AuthenticationViaFormAction 的源代码,里面有一个 submit 方法,这个就是我们提交表单时的方法了。继承AuthenticationViaFormAction实现一个新类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyAuthenticationViaFormAction extends AuthenticationViaFormAction{
public final String validatorCaptcha(final RequestContext context, final Credential credential,
final MessageContext messageContext){
final HttpServletRequest request = WebUtils.getHttpServletRequest(context);
HttpSession session = request.getSession();
String captcha = (String)session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
session.removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
UsernamePasswordCaptchaCredential upc = (UsernamePasswordCaptchaCredential)credential;
String submitAuthcodeCaptcha =upc.getCaptcha();
if(!StringUtils.hasText(submitAuthcodeCaptcha) || !StringUtils.hasText(submitAuthcodeCaptcha)){
messageContext.addMessage(new MessageBuilder().code(“required.captcha”).build());
return “error”;
}
if(submitAuthcodeCaptcha.equals(captcha)){
return “success”;
}
messageContext.addMessage(new MessageBuilder().code(“error.authentication.captcha.bad”).build());
return “error”;
}
}

这边有抛出两个异常,这两个异常信息 required.captcha、error.authentication.captcha.bad 需要在 messages_zh_CN.properties 文件下添加

1
2
required.captcha=必须输入验证码。
error.authentication.captcha.bad=您输入的验证码有误。

然后把 authenticationViaFormAction 这个Bean路径修改为我们新添加的类的全路径名。

当然最后,我们的页面也需要修改,找到casLoginView.jsp添加

1
2
3
4
5
6
<section class=“row”>
<spring:message code=“screen.welcome.label.captcha.accesskey” var=“captchaAccessKey” />
<spring:message code=“screen.welcome.label.captcha” var=“captchaHolder” />
<form:input cssClass=“required” cssErrorClass=“error” id=“captcha” size=“10” tabindex=“3” path=“captcha” placeholder=“${captchaHolder } accesskey=“${captchaAccessKey} autocomplete=“off” htmlEscape=“true” />
<img alt=“${captchaHolder } src=“captcha.jpg” onclick=“this.src=’captcha.jpg?’+Math.random();”>
</section>

以上添加验证码参考http://www.cnblogs.com/vhua/p/cas_3.html

添加记住密码

可以参考http://jasig.github.io/cas/development/installation/Configuring-LongTerm-Authentication.html

在cas.properties中添加如下配置

1
2
# Long term authentication session length in seconds
rememberMeDuration=1209600

spring-configuration文件夹下找到 ticketExpirationPolicies.xml 和 ticketGrantingTicketCookieGenerator.xml 需要在这两个配置文件中定义长期有效的session

在 ticketExpirationPolicies.xml文件中更新如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<bean id=“standardSessionTGTExpirationPolicy”
class=“org.jasig.cas.ticket.support.TicketGrantingTicketExpirationPolicy”
p:maxTimeToLiveInSeconds=${tgt.maxTimeToLiveInSeconds:28800}
p:timeToKillInSeconds=${tgt.timeToKillInSeconds:7200}/>
<!–
| The following policy applies to long term CAS SSO sessions.
| Default duration is two weeks (1209600s).
–>
<bean id=“longTermSessionTGTExpirationPolicy”
class=“org.jasig.cas.ticket.support.TimeoutExpirationPolicy”
c:timeToKillInMilliSeconds=“#{ ${rememberMeDuration:1209600} * 1000 }” />
<bean id=“grantingTicketExpirationPolicy”
class=“org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy”
p:sessionExpirationPolicy-ref=“standardSessionTGTExpirationPolicy”
p:rememberMeExpirationPolicy-ref=“longTermSessionTGTExpirationPolicy” />

更新ticketGrantingTicketCookieGenerator.xml

1
2
3
4
5
6
<bean id=“ticketGrantingTicketCookieGenerator” class=“org.jasig.cas.web.support.CookieRetrievingCookieGenerator”
p:cookieSecure=“true”
p:cookieMaxAge=“-1”
p:rememberMeMaxAge=“${rememberMeDuration:1209600}”
p:cookieName=“CASTGC”
p:cookiePath=“/cas” />

在 deployerConfigContext.xml 中找到 PolicyBasedAuthenticationManager 使其包含RememberMeAuthenticationMetaDataPopulator组件

1
2
3
4
5
6
7
8
<property name=“authenticationMetaDataPopulators”>
<list>
<bean
class=“org.jasig.cas.authentication.SuccessfulHandlerMetaDataPopulator” />
<bean
class=“org.jasig.cas.authentication.principal.RememberMeAuthenticationMetaDataPopulator” />
</list>
</property>

和添加验证码类似的,我们还需要修改login-webflow.xml

找到credential 的声明修改如下

1
<var name=“credential” class=“org.jasig.cas.authentication.RememberMeUsernamePasswordCredential” />

由于之前已经实现了验证码,所以这里不需要修改了,只需让 UsernamePasswordCaptchaCredential继承RememberMeUsernamePasswordCredential即可

找到viewLoginForm 在binder节点下添加<binding property="rememberMe" />

更新 casLoginView.jsp

1
2
3
4
<section class=“row check”>
<input id=“rememberMe” name=“rememberMe” value=“false” tabindex=“4” accesskey=“<spring:message code=”screen.welcome.label.rememberMe.accesskey” />” type=“checkbox” />
<label for=“rememberMe”><spring:message code=“screen.welcome.label.rememberMe” /></label>
</section>

自定义primaryAuthenticationHandler

虽然已经有QueryDatabaseAuthenticationHandler和QueryAndEncodeDatabaseAuthenticationHandler两个类,能够通过配置sql语句验证用户凭证,后者还能配置盐,散列函数迭代次数。但是我们可能还需要判断用户是否被锁定或被禁用了,我们可以参考QueryAndEncodeDatabaseAuthenticationHandler自定义一个AuthenticationHandler,继承AbstractJdbcUsernamePasswordAuthenticationHandler。添加两个字段名lockedFieldName和disabledFieldName通过这两个字段判断用户是否被锁定或被禁用,关键代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class ValidUserQueryDBAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler{
……
private static final String DEFAULT_LOCKED_FIELD = “locked”;
private static final String DEFAULT_DISABLED_FIELD = “disabled”;
……
@NotNull
protected String disabledFieldName = DEFAULT_DISABLED_FIELD;
@NotNull
protected String lockedFieldName = DEFAULT_LOCKED_FIELD;
……
public ValidUserQueryDBAuthenticationHandler(final DataSource datasource, final String sql, final String algorithmName) {
super();
setDataSource(datasource);
this.sql = sql;
this.algorithmName = algorithmName;
}
@Override
protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential transformedCredential)
throws GeneralSecurityException, PreventedException {
final String username = getPrincipalNameTransformer().transform(transformedCredential.getUsername());
try {
final Map<String, Object> values = getJdbcTemplate().queryForMap(this.sql, username);
if (Boolean.TRUE.equals(values.get(this.disabledFieldName))) {
throw new AccountDisabledException(username + ” has been disabled.”);
}
if (Boolean.TRUE.equals(values.get(this.lockedFieldName))) {
throw new AccountLockedException(username + ” has been locked.”);
}
final String digestedPassword = digestEncodedPassword(transformedCredential.getPassword(), values);
if (!values.get(this.passwordFieldName).equals(digestedPassword)) {
throw new FailedLoginException(“Password does not match value on record.”);
}
return createHandlerResult(transformedCredential,
new SimplePrincipal(username), null);
} catch (final IncorrectResultSizeDataAccessException e) {
if (e.getActualSize() == 0) {
throw new AccountNotFoundException(username + ” not found with SQL query”);
} else {
throw new FailedLoginException(“Multiple records found for “ + username);
}
} catch (final DataAccessException e) {
throw new PreventedException(“SQL exception while executing query for “ + username, e);
}
}
protected String digestEncodedPassword(final String encodedPassword, final Map<String, Object> values) {
final ConfigurableHashService hashService = new DefaultHashService();
if (StringUtils.isNotBlank(this.staticSalt)) {
hashService.setPrivateSalt(ByteSource.Util.bytes(this.staticSalt));
}
hashService.setHashAlgorithmName(this.algorithmName);
Long numOfIterations = this.numberOfIterations;
if (values.containsKey(this.numberOfIterationsFieldName)) {
final String longAsStr = values.get(this.numberOfIterationsFieldName).toString();
numOfIterations = Long.valueOf(longAsStr);
}
hashService.setHashIterations(numOfIterations.intValue());
if (!values.containsKey(this.saltFieldName)) {
throw new RuntimeException(“Specified field name for salt does not exist in the results”);
}
final String dynaSalt = values.get(this.saltFieldName)==null?“”:values.get(this.saltFieldName).toString();
final HashRequest request = new HashRequest.Builder()
.setSalt(dynaSalt)
.setSource(encodedPassword)
.build();
return hashService.computeHash(request).toHex();
}
public final void setDisabledFieldName(final String disabledFieldName) { this.disabledFieldName = disabledFieldName; }
public final void setLockedFieldName(final String lockedFieldName) { this.lockedFieldName = lockedFieldName; }
}

然后更新配置deployerConfigContext.xml

1
2
3
4
5
<bean id=“primaryAuthenticationHandler” class=“io.github.howiefh.cas.authentication.ValidUserQueryDBAuthenticationHandler”>
<constructor-arg ref=“dataSource” index=“0”></constructor-arg>
<constructor-arg value=“${auth.sql} index=“1”></constructor-arg>
<constructor-arg value=“MD5” index=“2”></constructor-arg>
</bean>

自定义登录页面

  1. 在cas.properties 修改 cas.viewResolver.basename 值为 custom_view ,那样系统就会自动会查找 custom_view.properties 这个配置文件
  2. 直接复制原来的 default_views.properties 就行了,重命名为custom_view.properties
  3. 把 custom_view.properties 中的WEB-INF\view\jsp\default全部替换把这地址替换成 WEB-INF\view\jsp\custom
  4. 接下来把 cas\WEB-INF\view\jsp\default 下面的所有文件复制,然后重命名为我们需要的名称,cas\WEB-INF\view\jsp\custom

主要修改casLoginView.jsp和cas.css即可

布局时遇到一个问题,就是将页脚固定在页面底部。可以参看如何将页脚固定在页面底部

其它

【SSO单点系列】(4):CAS4.0 SERVER登录后用户信息的返回
在多点环境下使用cas实现单点登陆及登出
关于单点登录中的用户信息存储问题的探讨

原理

从结构来看,CAS主要分为Server和Client。Server主要负责对用户的认证工作;Client负责处理客户端受保护资源的访问请求,登录时,重定向到Server进行认证。

基础模式的SSO访问流程步骤:

  1. 访问服务:客户端发送请求访问应用系统提供的服务资源。
  2. 定向认证:客户端重定向用户请求到中心认证服务器。
  3. 用户认证:用户进行身份认证
  4. 发放票据:服务器会产生一个随机的 Service Ticket 。
  5. 验证票据: SSO 服务器验证票据 Service Ticket 的合法性,验证通过后,允许客户端访问服务。
  6. 传输用户信息: SSO 服务器验证票据通过后,传输用户认证结果信息给客户端。

CAS最基本的协议过程:

CAS 最基本的协议过程CAS 最基本的协议过程

如上图: CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护 Web 应用的受保护资源,过滤从客户端过来的每一个 Web 请求,同时, CAS Client 会分析 HTTP 请求中是否包含请求 Service Ticket( ST 上图中的 Ticket) ,如果没有,则说明该用户是没有经过认证的;于是 CAS Client 会重定向用户请求到 CAS Server ( Step 2 ),并传递 Service (要访问的目的资源地址)。 Step 3 是用户认证过程,如果用户提供了正确的 Credentials , CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket ,并缓存以待将来验证,并且重定向用户到 Service 所在地址(附带刚才产生的 Service Ticket ) , 并为客户端浏览器设置一个 Ticket Granted Cookie ( TGC ) ; CAS Client 在拿到 Service 和新产生的 Ticket 过后,在 Step 5 和 Step6 中与 CAS Server 进行身份核实,以确保 Service Ticket 的合法性。

在该协议中,所有与 CAS Server 的交互均采用 SSL 协议,以确保 ST 和 TGC 的安全性。协议工作过程中会有两次重定向的过程。但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的(使用 HttpsURLConnection )。

相关概念

TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0协议中就有的票据,PGT、PGTIOU、PT是CAS2.0协议中有的票据。

CAS为用户签发登录票据,CAS认证成功后,将TGT对象放入自己的缓存,CAS生成cookie即TGC,自后登录时如果有TGC的话,则说明用户之前登录过,如果没有,则用户需要重新登录。

  • TGC (Ticket-granting cookie):存放用户身份认证凭证的cookie,在浏览器和CAS Server用来明确用户身份的凭证。
  • ST(Service Ticket):CAS服务器通过浏览器分发给客户端服务器的票据。一个特定服务只能有一个唯一的ST。
  • PGT(Proxy Granting Ticket):由 CAS Server 颁发给拥有 ST 凭证的服务, PGT 绑定一个用户的特定服务,使其拥有向 CAS Server 申请,获得 PT 的能力。
  • PGTIOU(全称 Proxy Granting Ticket I Owe You):作用是将通过凭证校验时的应答信息由 CAS Server 返回给 CAS Client ,同时,与该 PGTIOU 对应的 PGT 将通过回调链接传给 Web 应用。 Web 应用负责维护 PGTIOU 与 PGT 之间映射关系的内容表。PGTIOU是CAS的serviceValidate接口验证ST成功后,CAS会生成验证ST成功的xml消息,返回给Proxy Service,xml消息中含有PGTIOU,proxy service收到Xml消息后,会从中解析出PGTIOU的值,然后以其为key,在map中找出PGT的值,赋值给代表用户信息的Assertion对象的pgtId,同时在map中将其删除。
  • PT(Proxy Ticket):是应用程序代理用户身份对目标程序进行访问的凭证;

CAS 基本流程图(没有使用PROXY代理)

CAS 基本流程图(没有使用PROXY代理)CAS 基本流程图(没有使用PROXY代理)

对于客户端来说会通过客户端session判断用户是否已认证,没有的话跳转到服务器认证,对于服务器,通过SSO session判断用户是否认证,没有的话跳到登录页面。

CAS 基本流程图(使用PROXY代理)

CAS 基本流程图(使用PROXY代理)CAS 基本流程图(使用PROXY代理)

Ansible shell 模块

shell 模块

这个是一个很神奇的模块,它也是ansible的核心模块之一。它跟command模块一样负责在被ansible控制的节点(服务器)执行命令行。它与command模块有着相似的地方,也有不同的地方,看完这篇文章将告诉你答案。

shell模块常用参数

parameter required default choices comments
chdir no 跟command一样的,运行shell之前cd到某个目录
creates no 跟command一样的,如果某个文件存在则不运行shell
removes no 跟command一样的,如果某个文件不存在不运行shell

shell模块案例

案例1:
让所有节点运行somescript.sh并把log输出到somelog.txt。

$ ansible -i hosts all -m shell -a "sh somescript.sh >> somelog.txt"

案例2:
先进入somedir/ ,再在somedir/目录下让所有节点运行somescript.sh并把log输出到somelog.txt。

$ ansible -i hosts all -m shell -a "somescript.sh >> somelog.txt" chdir=somedir/

案例3:
体验shell和command的区别,先cd到某个需要编译的目录,执行condifgure然后,编译,然后安装。

$ ansible -i hosts all -m shell -a "./configure && make && make insatll" chdir=/xxx/yyy/

shell模块如何使用你明白了么?