mesos 1.3.1 에서 mesos-slave를 재시작한 후 상태 로그를 확인하려면 다음과 같다. 


curl 'http://${mesos-slave IP}:5051/slave(1)/state'

...

"attributes": {

  "ip": "${mesos-slave IP}",

  "os": "Ubuntu",

  "os-version": 16

},

...




/etc/default/mesos-slave 설정을 수정할 때는 조심해야 한다. 



export MESOS_ATTRIBUTES="ip:1.1.1.1;os:Ubuntu;os-version:16;server-type:user"라는 기본 값이 있을 때..


key:value라는 값을 추가하니 동작한다. key=value하면 mesos-slave 데몬이 뜨지 않는다.  위의 상태 체크 URL를 호출해본다. 

아래와 같이 수정한다.


export MESOS_ATTRIBUTES="ip:1.1.1.1;os:Ubuntu;os-version:16;server-type:user;key:value" 




* 주의할 점.


1. 설정할 때 key=value가 아니라 key:value이다. (콤마)


2. /etc/default/mesos-slave의 property를 수정할 때는 


MESOS_WORK_DIR를 지정한 디렉토리의 모든 파일을 지우고(sudo rm -rf 메소스_작업_DIR/*) 재시작해야 한다. 

(예, export MESOS_WORK_DIR=/var/mesos)



만약 MESOS_WORK_DIR 디렉토리를 지우지 않고 재시작하면 아래와 같은 에러가 발생한다.


$ sudo service  mesos-slave status

● mesos-slave.service - Mesos Slave

   Loaded: loaded (/lib/systemd/system/mesos-slave.service; enabled; vendor preset: enabled)

   Active: activating (auto-restart) (Result: exit-code) since Fri 2018-12-13 19:38:33 KST; 7s ago

  Process: 3343 ExecStart=/usr/bin/mesos-init-wrapper slave (code=exited, status=1/FAILURE)

 Main PID: 3343 (code=exited, status=1/FAILURE)


Apr 13 19:38:33 media-site-node51 systemd[1]: mesos-slave.service: Unit entered failed state.

Apr 13 19:38:33 media-site-node51 systemd[1]: mesos-slave.service: Failed with result 'exit-code'.



Posted by 김용환 '김용환'


마라톤 lb에서 포트별 설정(첫 번째, 두 번째... 등등)을 할 수 있다. 


https://github.com/mesosphere/marathon-lb/blob/master/Longhelp.md


Templates

The following is a list of the available HAProxy templates. Some templates are global-only (such as HAPROXY_HEAD), but most may be overridden on a per service port basis using the HAPROXY_{n}_... syntax.





Labels

HAPROXY_0_MODE=http

HAPROXY_0_VHOST=plus.google.com

HAPROXY_0_SSL_CERT=/etc/ssl/marathon/250.pem



Posted by 김용환 '김용환'


마라톤(marathon)에서 자원 (메모리)가 없으면 다음과 가은 에러가 발생한다. (비슷하게 다른 자원도 해결할 수 있다)


눈으로 볼 때는 메모리 자원 여유는 있지만.. 


앱을 재시작하면서 순간적으로 용량이 부족할 수 있기 때문에, 항상 기존 앱 + 새로 시작할 앱 사이에 2배 공간의 여유가 순간적으로 있을 수 있으니.. 적당하게 공간을 할애하는 것이 좋다. 


 



INFO Offer [c6424609-c06c-463b-91bb-97962d915e56-O374]. Considering resources with roles {googledev, *} without resident reservation labels. Not all basic resources satisfied: cpus SATISFIED (0.1 <= 0.1), mem NOT SATISFIED (256.0 > 176.0) (mesosphere.mesos.ResourceMatcher$:marathon-akka.actor.default-dispatcher-2)



INFO Offer [c6424609-c06c-463b-91bb-97962d915e56-O374]. Insufficient resources for [/plus-stage] (need cpus=0.1, mem=256.0, disk=0.0, gpus=0, ports=(), available in offer: [id { value: "c6424609-c06c-463b-91bb-97962d915e56-O374" } framework_id { value: "3549a1e4-9a61-4bb1-9a0a-8fc66d4e76f4-0000" } slave_id { value: "c6424609-c06c-463b-91bb-97962d915e56-S1" } hostname: "11.11.11.11" resources { name: "cpus" type: SCALAR scalar { value: 7.4 } role: "*" } resources { name: "mem" type: SCALAR scalar { value: 176.0 } role: "*" } resources { name: "disk" type: SCALAR scalar { value: 45240.0 } role: "*" } resources { name: "ports" type: RANGES ranges { range { begin: 31000 end: 31021 } range { begin: 31023 end: 31075 } range { begin: 31077 end: 31136 } range { begin: 31138 end: 31345 } range { begin: 31347 end: 31560 } range { begin: 31562 end: 31856 } range { begin: 31858 end: 32000 } } role: "*" } url { scheme: "http" address { hostname: "10.197.1.63" ip: "10.197.1.63" port: 5051 } path: "/slave(1)" }] (mesosphere.mesos.TaskBuilder$:marathon-akka.actor.default-dispatcher-2)




INFO Finished processing c6424609-c06c-463b-91bb-97962d915e56-O374 from 10.197.1.63. Matched 0 ops after 1 passes. cpus(*) 7.4; mem(*) 176.0; disk(*) 45240.0; ports(*) 31000->31021,31023->31075,31077->31136,31138->31345,31347->31560,31562->31856,31858->32000 left. (mesosphere.marathon.core.matcher.manager.impl.OfferMatcherManagerActor:marathon-akka.actor.default-dispatcher-25)





그러나... 마라톤에서는 계속 Deploying 으로 뜨고 자원도 좀 있었긴 했다...

mesos slave간에 통신으로 mesos에서 저런 에러를 내보낼 수 있다.. 마라톤 하위 버전(1.0.1이었음)이라면 의심해도 좋다.


mesos 슬레이브 에러 로그를 확인하니.. 메소스 통신 중에 문제가 있었고.. 그 여파가 마라톤에서 앱 배포가 문제가 발생했다.


E0409 18:14:34.853005  2198 slave.cpp:3456] Failed to update resources for container 41283b2f-3d3f-40d6-9c37-0011f1dfaa52 of executor 'plus-stage.489512aa-9618-11e7-8450-0242540dd87f' running task plus-stage.489512aa-9618-11e7-8450-0242540dd87f on status update for terminal task, destroying container: Failed to determine cgroup for the 'cpu' subsystem: Failed to read /proc/15390/cgroup: Failed to open file: No such file or directory




문제 해결을 하려면 메소스 버전업을 진행해야 한다. 


Posted by 김용환 '김용환'



마라톤(marathon)에는 fault tolerance와 locality를 극복할 수 있는 방법으로 constraints를 제공한다. 동일한 기능을 하는 데몬을 한 장비에 두면, 한 장비가 죽으면 더 이상 서비스를 진행할 수 없다.


그래서 가상 장비(virutal machine)에서는 anti affinity 라는 단어를 사용해 동일한 기능을 가진 서비스를 여러 장비에 분산시키면 fault tolerance와 locality를 지원한다.



<fault tolerance와 locality 소개>

https://www.bayt.com/en/specialties/q/215179/what-is-affinity-and-anti-affinity-rule-in-vmware/


Affinity rule, ensure that multiple virtual machines are always running on the same host.  As such, if one of the virtual machines is vMotioned to a different host, the associated virtual machines must be moved as well.






http://mesosphere.github.io/marathon/docs/constraints.html


CLUSTER allows you to run all of your app’s tasks on agent nodes that share a certain attribute. This is useful for example if you have apps with special hardware needs, or if you want to run them on the same rack for low latency.

A field of "hostname" tells Marathon that launched tasks of the app/pod have affinity for each other and should be launched together on the same agent:

....




하나의 장비에 동일한 서비스(데몬)을 실행시키지 않으려면 

marathon json에 다음을 추가한다.



 "constraints": [["hostname", "UNIQUE"]]



Posted by 김용환 '김용환'

https://mesosphere.github.io/marathon/docs/ports.html


https://mesosphere.com/blog/networking-docker-containers/


https://stackoverflow.com/questions/36265502/difference-between-ports-and-service-ports





Posted by 김용환 '김용환'


마라톤(marathon)을 로컬 모드/확장형으로 설치/실행하는 예이다.


 

 마라톤 상태를 저장하려면 주키퍼가 필요하다. 주키퍼를 설치하고 주키퍼를 실행한다.

 

$ wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gz


$ tar xf zookeeper-3.4.8.tar.gz 


$ cd ~/zookeeper-3.4.8/


$ mv conf/zoo_sample.cfg conf/zoo.cfg

 

$ vi conf/zoo.cfg

# The number of milliseconds of each tick

tickTime=2000

# The number of ticks that the initial

# synchronization phase can take

initLimit=10

# The number of ticks that can pass between

# sending a request and getting an acknowledgement

syncLimit=5

# the directory where the snapshot is stored.

# do not use /tmp for storage, /tmp here is just

# example sakes.

dataDir=/var/zookeeper

# the port at which the clients will connect

clientPort=2181

# the maximum number





$ sudo bin/zkServer.sh start

Starting zookeeper ... STARTED



마라톤 바이너리 파일(libmesos.so)을 lib 공통 폴더에 복사한다. 


$ sudo cp ~/mesos/build/src/.libs/libmesos.so /usr/lib

 

이렇게 하지 않으면 마라톤 실행이 되지 않는다. 


Failed to load native Mesos library from

java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library:

at java.lang.Runtime.load0(Runtime.java:806)

at java.lang.System.load(System.java:1086)

at org.apache.mesos.MesosNativeLibrary.load(MesosNativeLibrary.java:159)

at org.apache.mesos.MesosNativeLibrary.load(MesosNativeLibrary.java:188)

at org.apache.mesos.MesosSchedulerDriver.<clinit>(MesosSchedulerDriver.java:61)

at mesosphere.marathon.MarathonSchedulerDriver$.newDriver(MarathonSchedulerDriver.scala:81)

at mesosphere.marathon.MesosSchedulerDriverFactory.createDriver(SchedulerDriverFactory.scala:28)

at mesosphere.marathon.DebugModule$MetricsBehavior$$anonfun$invoke$1.apply(DebugConf.scala:62)

at mesosphere.marathon.metrics.Metrics.timed(Metrics.scala:27)

at mesosphere.marathon.DebugModule$MetricsBehavior.invoke(DebugConf.scala:61)

at mesosphere.marathon.MarathonSchedulerService.liftedTree1$1(MarathonSchedulerService.scala:282)

at mesosphere.marathon.MarathonSchedulerService.onElected(MarathonSchedulerService.scala:267)

at mesosphere.marathon.DebugModule$MetricsBehavior$$anonfun$invoke$1.apply(DebugConf.scala:62)

at mesosphere.marathon.metrics.Metrics.timed(Metrics.scala:27)

at mesosphere.marathon.DebugModule$MetricsBehavior.invoke(DebugConf.scala:61)

at mesosphere.marathon.core.leadership.CandidateImpl$4.onGroupChange(CandidateImpl.java:177)

at mesosphere.marathon.core.leadership.CandidateImpl.offerLeadership(CandidateImpl.java:212)

at mesosphere.marathon.MarathonSchedulerService$$anonfun$mesosphere$marathon$MarathonSchedulerService$$offerLeadership$1$$anonfun$apply$2.apply(MarathonSchedulerService.scala:370)

at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)

at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)

at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)

at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)

at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)

at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)

at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

 




마라톤을 설치한다. 


$ wget http://downloads.mesosphere.com/marathon/v1.1.1/marathon-1.1.1.tgz 

$ tar xf marathon-1.1.1.tgz 

$ cd ~/marathon-1.1.1

$ ./bin/start --master local --zk zk://localhost:2181/marathon 

 [2017-04-26 23:31:17,081] INFO All services up and running. (mesosphere.marathon.Main$:main)






데모로 아래 링크를 참조해서 Hello Marathon를 하나 생성한다.


https://mesosphere.github.io/marathon/docs/application-basics.html


하나의 application을 만들 수 있지만, scale application을 할 수 없다. 로컬 모드라서...






로컬 모드가 아니라 이미 설치된 메소스와 연동한다. 아래와 같이 zookeeper 연동하면 잘 작동한다. 




./bin/start --master zk://zk1:2181,zk2:2181/mesos --zk zk://zk1:2181,zk2:2181/marathon



scala application을 눌러 cpu50개를 사용하는 job을 생성한다. 







그리고, 메소스 내부는 아래와 같이 애플리케이션을 다양하게 사용됨을 확인할 수 있다.






정상적으로 동작하는지 테스트해본다.




curl -X POST http://마라톤_장비:8080/v2/apps -d @basic-3.json -H "Content-type: application/json"


{

  "id": "basic-3",

  "cmd": "python3 -m http.server 8080",

  "cpus": 0.5,

  "mem": 32.0,

  "container": {

    "type": "DOCKER",

    "docker": {

      "image": "python:3",

      "network": "BRIDGE",

      "portMappings": [

        { "containerPort": 8080, "hostPort": 0 }

      ]

    }

  }

}



http-json으로 app 생성을 요청해 본다.


$ curl -X POST http://마라톤-ip:8080/v2/apps -d @basic-4.json -H "Content-type: application/json"


{"id":"/basic-4","cmd":"python3 -m http.server 8080","args":null,"user":null,"env":{},"instances":5,"cpus":0.5,"mem":32,"disk":0,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[0],"portDefinitions":[{"port":0,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"python:3","network":"BRIDGE","portMappings":[{"containerPort":8080,"hostPort":0,"servicePort":0,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"ipAddress":null,"version":"2017-04-28T13:59:01.853Z","residency":null,"tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"c6c8a6db-5e25-49ed-aaae-9d902dcf2744"}],










참고 문서 : https://mesosphere.github.io/marathon/docs/application-basics.html

Posted by 김용환 '김용환'

메소스 다운로드



http://www.apache.org/dist/mesos/ 에서 다운받을 바이너리를 확인한다.



sudo yum install -y cyrus-sasl-md5  subversion-devel 

http://www.apache.org/dist/mesos/1.0.3/mesos-1.0.3.tar.gz

tar -zxf mesos-1.0.0.tar.gz

mv mesos-1.0.0 mesos 

cd mesos 

mkdir build 

cd build 

../configure

make 


다운로드 에러가 발생한다면 proxy 이슈이다. 아래와 같이 maven 설정 파일에 proxy를 추가한다.


$ cat ~/.m2/settings.xml

<settings>

    <proxies>

        <proxy>

            <active>true</active>

            <protocol>http</protocol>

            <host>proxy서버</host>

            <port>8888</port>

        </proxy>

    </proxies>

</settings>




제대로 컴파일되었는지 확인한다.


make check 



스탠드얼론 형태로 마스터 서비스를 실행한다. (마스터가 1인 메소스)



cd /home/deploy/mesos/build


sudo ./bin/mesos-master.sh --work_dir=/var/lib/mesos



http://서버-IP:5050






이제 클러스터 모드로 돌려본다.


rsync를 이용해 슬레이브가 될 장비들에 복사를 진행한다. 이미 컴파일된 된 상태이다.


rsync ...




슬레이브 장비에서 yum을 설치하고 mesos를 슬레이브 상태로 실행했다.


 sudo yum install -y cyrus-sasl-md5  subversion-devel  screen

 

 sudo ./bin/mesos-slave.sh --work_dir=/var/lib/mesos --master=마스터_IP:5050




여기서 high availability를 지원하기 위해 zookeeper를 사용하는 것이 좋다.



예제로 두 대의 서버에 zookeeper를 실행하고 다음과 같이 master를 실행했다. 



sudo ./bin/mesos-master.sh --work_dir=/var/lib/mesos  --quorum=1 --zk=zk://zk1:2181,zk2:2181,zk3:2181/mesos --log_dir=/var/log/mesos



잘 동작하고 있다.












참고 : 에러


* Need to specify --quorum for replicated log based registry when using ZooKeeper  : 이 에러를 해결하려면 쿼럼의 값을 조절하는 것이다. --quorum=2 처럼 사용한다.



* F0427 18:21:35.832242 22151 master.cpp:1536] Recovery failed: Failed to recover registrar: Failed to perform fetch within 1mins

*** Check failure stack trace: *** 

메소스를 처음에 실행할 때 에러가 발생했다. 이 문제의 해결은 quorum의 값을 잘못 넣어서 발생했다. quorum의 값을 제대로 넣어보니 더 이상 발생하지 않았다.

(실제 복구 문제라면 이렇게 쉽게 해결되지 않을 것 같다.)




Posted by 김용환 '김용환'