marathon에서 haproxy 기본 포트는 다 열려있다. 서비스는 80/443 포트 연결되게 했지만, 특정 마라톤에서는 http 접근시 80만 막고 싶을 때가 있다. 



  "labels": {

    "HAPROXY_0_MODE": "http",

    "HAPROXY_0_HTTP_FRONTEND_ACL": "",

    "HAPROXY_0_VHOST": "plus.google.com",

    "HAPROXY_0_SSL_CERT": "/etc/ssl/marathon/268.pem"

  },

  


HAPROXY_0_HTTP_FRONTEND_ACL가 정의되어 있으면 80포트 접근시 503 에러가 나타나게 한다.

반면 443 포트는 열려 있다.



$ curl -I -XPOST http://plus.google.com/

HTTP/1.0 503 Service Unavailable

Cache-Control: no-cache

Connection: close

Content-Type: text/html




$ curl -XPOST https://plus.google.com...

성공


Posted by 김용환 '김용환'



마라톤(marathon)에서 80으로 들어온 특정 도메인 요청(예, plus.google.io)을 443 포트로 띄워진 앱을 실행하는 방법은 다음과 같다. 


참고로 HAPROXY_0_MODE는 tcp와 http만 된다. 따라서 다른 먼가가 필요한다. 그것이 HAPROXY_0_REDIRECT_TO_HTTPS이다. 


"labels": {
"HAPROXY_0_MODE"="http",

"HAPROXY_0_REDIRECT_TO_HTTPS"="true",

"HAPROXY_0_VHOST"="plus.google.io",

"HAPROXY_0_SSL_CERT"="/etc/ssl/marathon/268.pem"

}




실제 80 포트로 접속하면 301로 forwading된다.


$ curl -I -XGET http://...

HTTP/1.1 301 Moved Permanently

Content-length: 0

Location: https://...

Connection: close



Posted by 김용환 '김용환'



특정 mesos 에만 동작하도록 하는 방법이다.



$ sudo vi /etc/default/mesos-slave

export MESOS_ATTRIBUTES="ip:11.11.11.11;os:Ubuntu;os-version:16;server-type:user;service:google-api"


$ sudo vi /etc/default/mesos-slave

$ sudo service mesos-slave stop


MESOS_ATTRIBUTES를 수정할 때마다 MESOS_WORK_DIR의 모든 메타 파일을 삭제해야 합니다

$ sudo rm -rf $MESOS_WORK_DIR/*


$ sudo service mesos-slave start



확인하는 방법.



curl 'http://슬레이브_ip:5051/slave(1)/state' | jq


...


  "attributes": {

    "ip": "10.61.106.159",

    "os": "Ubuntu",

    "os-version": 16,

    "server-type": "user",

    "service": "google-api"

  },

  "master_hostname": "11.11.11.11",

  "log_dir": "/var/log/mesos",

  "flags": {

    "appc_simple_discovery_uri_prefix": "http://",

    "appc_store_dir": "/tmp/mesos/store/appc",

    "attributes": "ip:11.11.11.11;os:Ubuntu;os-version:16;server-type:user;service:google-api",


...





마라톤 앱에 다음 constraints를 추가한다.



"constraints": [

    [

      "service",

      "CLUSTER",

      "google-api"

    ]

  ],






kubernetes로 가면 저 labeling을 환경 설정(env)로 쉽게 진행할 수 있다. mesos 약간 불편한 점이 있다.


Posted by 김용환 '김용환'





marathon 앱의 포트를 지정할 때. 



servicePort는 앱에서 외부로 노출될 서비스 port를 의미한다. 
servicePort: When you create a new application in Marathon (either through the REST API or the front end), you may assign one or more service ports to it. You can specify all valid port numbers as service ports or you can use 0 to indicate that Marathon should allocate free service ports to the app automatically


containerPort는 컨테이너에서 앱이 실행중인 포트를 지정한다.즉 load balancer와 앱 간에 연결되고 있는 port를 의미한다.  이 포트로 health check가 일어난다. 

containerPort: A container port specifies a port within a container. This is only necessary as part of a port mapping when using BRIDGE or USER mode networking with a Docker container.




아래 예를 보면, 외부에서 8080포트로 접근할 수 있고, LB와 마라톤 앱간에는 18080으로 통신한다라는 뜻이다. 


"container": {

    "type": "DOCKER",

    "volumes": [],

    "docker": {

      "image": "imageurl",

      "network": "BRIDGE",

      "portMappings": [

        {

          "containerPort": 8080,

          "hostPort": 0,

          "servicePort": 18080,

          "protocol": "tcp",

          "name": "8080",

          "labels": {}

        }

      ],

      "privileged": false,

      "parameters": [],

      "forcePullImage": true

    }

  },









Posted by 김용환 '김용환'

marathon의 상태에 대한 내용이다.


- Running

- Deploying

- Suspended

- Delayed

- Waiting


(- Staging)


waiting 상태이면 메소스 자원이 없는지 메소스 슬레이브 자원 상태를 확인하거나, 추가 자원을 확보한다.


staging 상태이면 health check 실패거나 오래 걸리는 상황일 수 있다. 로그를 줄이거나 예외(exception) 또는 에러로 인해서 데몬이 실행 중인지 확인한다.  확인하는 방법은 로컬에서 진행할 수 있다. 


healthy였다고 unhealthy였다가 반복하면 docker 컨테이너에 앱이 종료되었다가, 실행되었다가 하는 것이다.항상 foreground 앱이 docker 컨테이너 안에 있어야 한다.

참조 

https://mesosphere.github.io/marathon/docs/marathon-ui.html#application-status-reference





Posted by 김용환 '김용환'





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 김용환 '김용환'