Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Mesos

Mesos는 분산 시스템 커널(distributed systems kernel)이다. 뭔가 굉장히 복잡해 보이지만, 기본 개념은 간단하다. 네트워크로 묶여 있는 여러 개의 컴퓨터의 자원 즉, CPU, 메모리, 디스크 등의 자원을 하나로 묶어서 resource pool로 만들어서 마치 하나의 컴퓨터 처럼 보이게 하겠다는 거다. 그리고 커널로서 작동하기 위한 기능인 스케쥴러와 애플리케이션 관리 기능을 더해서, 분산 커널을 만든다. 이제 유저가 애플리케이션 실행을 요청하면, 자원이 넉넉한 인스턴스를 할당하고 애플리케이션을 실행 하면 된다.

Mesos의 아키텍처는 다음과 같다.

 Mesos 아키텍처

Mesos는 주키퍼 quorum을 구성해서 자신의 가용성을 확보한다. Active-Standby타입으로 구성이 되는데, 이를 위해서 Mesos master 중 하나를 leader로 선출(elect) 한다. Mesos master는 Messos slave로 부터 자원을 보고 받아서 자원 풀을 만든다. 예를 들어 4 core, 16G를 가진 4개의 Messos slave가 접속했다면, 16 core, 64 G의 자원을 가지는 pool을 구성한다. 스케쥴러는 이 자원 정보를 읽어서 자원을 실행할 Mesos slave를 선택한다.

Messos slave는 leader로 선출된 Mesos master에 접속하고, 자신이 실행된 인스턴스의 자원정보를 보고(reporting)한다. 또한 Executor를 가지고 있어서, 애플리케이션을 실행하는 일을 한다. 애플리케이션이 종료되면, 이 정보를 Messos master에 전송해서 자원을 분산 시스템 터널에 자원을 돌려준다.

Mesosphere

Datacenter Operationg System을 표방하는 소프트웨어다. Messos를 핵심 컴포넌트로 하고 여기에 Mesos DNS, Marathon, Admin router 등을 더한 소프트웨어다. 설치에서 운영/관리까지 Mesospher를 이용하는게 편하기 때문에, Mesos대신 Mesospher를 사용해서 테스트하기로 했다.

테스트 환경 구성

개인 리눅스 박스에 virtualbox로 만들었다. 구성은 다음과 같다.

 Mesos 테스트 환경

우분투 리눅스 15.10은 패키지에 약간의 버그가 있어서, 14.04로 구성해서 테스트 했다.

Mesos master 설치

mesos-01, 02, 03에 대해서 작업들을 진행한다. 먼저 오라클 Java를 설치한다. Java를 설치하지 않으면 marathon 설치에 실패한다.
# add-apt-repository ppa:webupd8team/java
# apt-get update
# apt-get install oracle-java8-installer
# apt-get install oracle-java8-set-default

mesos패키지를 설치하기 위해서, 저장소를 등록하고 패키지를 설치한다.
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
# echo "deb http://repos.mesosphere.com/ubuntu trusty main" >> /etc/apt/sources.list
# apt-get update
# apt-get install -y mesos marathon 
패키지를 설치하면, messos-slave, messos-master가 모두 설치되고 서비스에 등록된다. messos-master를 설치하는게 목적이니 messos-slave 서비스는 중단한다.
# service mesos-slave stop
# echo manual > /etc/init/mesos-slave.override

주키퍼 설정을 한다. 주키퍼 quorum을 구성하는 주키퍼 노드들은 고유의 id를 가지고 있어야 한다. mesos-01은 1, 02는 2, 03은 3을 설정했다.
# cat /etc/zookeeper/conf/myid
1
주키퍼 quorum을 구성하는 노드들의 정보를 설정한다.
# cat /etc/zookeeper/conf/zoo.cfg
server.1=192.168.56.155:2888:3888
server.2=192.168.56.156:2888:3888
server.3=192.168.56.157:2888:3888
/etc/hosts 정보도 설정한다.
# cat /etc/hosts
127.0.0.1	localhost
192.168.56.155	mesos-01.joinc.priv
192.168.56.156  mesos-02.joinc.priv
192.168.56.157  mesos-03.joinc.priv

mesos가 바라볼 주키퍼 서버 설정을 한다.
# cat /etc/mesos/zk 
zk://192.168.56.155:2181,192.168.56.156:2181,192.168.56.157:2181/mesos

Quorum 값을 설정한다. 이 값은 마스터 노드의 갯수 / 2 보다 커야 한다. 예를들어 5개의 마스터로 구성된 클러스터라면 3을 설정한다. 내가 구성한 클러스터는 3개의 노드로 구성됐으므로 2를 설정했다.

이제 서비스를 시작한다.
# service zookeeper restart
# service mesos-master restart
# service marathon restart

Mesos 클러스터 구성 확인

Mesos 클러스터가 제대로 구성됐는지 확인하자. Mesos master 서버에서 zlCli.sh로 확인 했다.
# /usr/share/zookeeper/bin/zkCli.sh -server localhost
[zk: localhost(CONNECTED) 0] ls /
[mesos, zookeeper, marathon]
mesos와 marathon znode를 확인 할 수 있다.
[zk: localhost(CONNECTED) 1] ls /mesos
[json.info_0000000070, json.info_0000000067, log_replicas, json.info_0000000066]
/mesos 밑에는 3개의 chieldren이 보이는데, mesos 클러스터를 구성하는 3개의 mssos master 노드들이다. get으로 각 노드들의 상세 정보를 가져올 수 있다.

mesos-ui

mesos는 자원관리를 위한 웹 UI를 제공한다. 5050포트로 접근할 수 있다. 웹 브라우저를 이용해서 3개의 master 노드 중 하나로 접근하면 된다.

 mesos-ui

아직 등록된 mesos slave가 없는 관계로, 리소스(Resources)가 모두 0 인걸 확인 할 수 있다. Mesos master는 하나만 active 상태다. 만약 standby 상태의 master에 연결하면 자동으로 mater로 리다이렉트 한다.

Marathon-ui

Marathonmesos containers도커를 지원하는 container runtime이다. 관리자는 marathon API를 이용해서 애플리케이션을 실행하고 관리 할 수 있다. 그리고 간단하게 사용 할수 있는 web ui를 제공한다. Master의 8080 포트로 접근해보자.

 Marathon-ui

Create Application으로 애플리케이션을 만들 수 있으며, 생성된 애플리케이션을 확인 할 수도 있다.

Mesos Slave 구성

이제 Messos Slave를 구성한다. 최초에 계획한대로 node-01, node-02 두 개의 노드를 구성한다.

Mesos slave 설치

두 개의 노드 모두에 Mesos 패키지 저장소를 등록하고 업데이트 후 설치한다.
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
# echo "deb http://repos.mesosphere.com/ubuntu trusty main" >> /etc/apt/sources.list
# apt-get update
# apt-get -y install mesos
Marathon을 설치하지 않는 다는 것만 제외하면 master 설치와 다를게 없다.

쓸데없이 설치된 zooker와 messos-master 서비스를 중지한다.
# service zookeeper stop
# service mesos-master stop

Slave가 연결할 zooker 노드들을 설정한다.
# cat /etc/mesos/zk 
zk://192.168.56.155:2181,192.168.56.156:2181,192.168.56.157:2181/mesos

/etc/hosts를 설정한다.
# cat /etc/hosts
127.0.0.1	    localhost
192.168.56.10	node-01.joinc.priv

192.168.56.155  mesos-01.joinc.priv
192.168.56.156  mesos-02.joinc.priv
192.168.56.157  mesos-03.joinc.priv

이제 mesos-slave 서비스를 재 시작한다.
# service mesos-slave restart

Mesos-ui에 접근하면 등록된 Slave와 리소스 정보를 확인 할 수 있다. 각 slave에 1G의 메모리를 할당해서 2개의 CPU가 리소스로 등록된 걸 확인 할 수 있다.

 Slave 등록 화면

애플리케이션 실행

Marathon ui에서 애플리케이션을 실행해 보자. Marathon은 Mesos 컨테이너와 도커 컨테이너의 실행을 지원하는데, 아직 도커를 설치하지 않았으니, Mesos 컨테이너 타입 애플리케이션을 실행해 보자. ping localhost를 실행하기로 했다.

 app 실행

Docker container settings를 설정하지 않은면 Mesos 컨테이너로 실행된다. CPUs는 애플리케이션에 할당할 CPU core 갯수다. 할당이라는 것에 주의해야 하는데, 할당한 만큼 점유를 해버린다. 예컨데 2 core 짜리 인스턴스에 2 CPUs 애플리케이션을 실행해 버리면, (CPU가 남아돌아도) 애플리케이션 실행을 할 수 없게 된다. 하둡처럼 균일한 애플리케이션이 아닌 다수의 애플리케이션이 서로 경쟁하는 그런 서비스라면, CPUs 설정에 약간의 고민이 필요 할 수 있다.

 앱 실행 화면

2개의 앱을 실행한 화면이다. Mesos ui에서 애플리케이션에 대한 상세정보를 확인 할 수 있다.

 앱 상세 정보

docker 애플리케이션 실행

2014년 Mesos 0.20.0 버전부터 도커를 지원하고 있다. 각 Mesos slave의 설정을 아래와 같이 변경하고 재 시작 하면 된다. 물론 도커는 설치돼 있어야 겠다.
# echo 'docker,mesos' > /etc/mesos-slave/containerizers
# echo '5mins' > /etc/mesos-slave/executor_registration_timeout
이제 marathon에 docker 설정을 해주는 것으로 docker 컨테이너를 실행 할 수 있다.

Marathon API

Marathon rest-api 참고

Mesos 분석

Leader 선출

Mesos를 고가용성(HA)모드로 작동하기 위해서는 zookeeper가 필요하다. Mesos master들을 설정한 뒤에 zkCli.sh로 주키퍼의 상태를 확인해 보자.
# zkCli.sh -server 192.168.56.155
[zk: 192.168.56.155(CONNECTED) 2] ls /mesos
[json.info_0000000081, json.info_0000000080, json.info_0000000079, log_replicas]
get 명령으로 znode의 상세 정보를 가져올 수 있다. json 정보는 보기 좋게 가공했다.
[zk: 192.168.56.155(CONNECTED) 3] get /mesos/json.info_0000000081
{
   "id" : "12215788-8367-4746-8bc0-21b664b1eaa0",
   "pid" : "master@192.168.56.157:5050",
   "hostname" : "mesos-03.joinc.priv",
   "ip" : 2637736128,
   "version" : "0.28.0",
   "address" : {
      "port" : 5050,
      "hostname" : "mesos-03.joinc.priv",
      "ip" : "192.168.56.157"
   },
   "port" : 5050
}
3개의 json.info_로 시작하는 3개의 znode들이 있는데, 이들이 mesos master 들이다. 이들 znode들은 sequence타입의 노드로 11자리의 유일한 일련번호가 할당된다. 이 일련번호를 mesos master의 id로 해서 leader를 선출 할 수 있다. 대략 아래와 같이 작동할 것이다.

 리더 알림
  1. node-1이 zk에 연결한다. 자신이 leader가 된다. 주키퍼 sequence znode 특성상 가장 낮은 번호를 가진다.
  2. node-2, 3, 4 가 zk에 연결하면, 자신이 리더라는 걸 알린다.
  3. node-1과 zk의 연결이 끊어지면, watch하고 있던 노드들 중 가장 우선순위가 높은 node-2가 리더로 선출되기 위한 작업을 수행한다. 주변의 노드에 내가 리더가 돼겠다는 요청을 보낸다. node-3,4는 가장 높은 node가 요청을 했기 때문에 허가해야 한다. 요청ㅇ을 받은 node-2는 자신을 리더로 설정하고, 주변노드에 이를 알린다.
  4. node-1이 다시 zk에 연결을 할 경우, node-5로 연결이 된다. node-2가 자신이 리더라는 걸 node-5에 알린다.
실제 구현하기 위해서는 좀 더 손을 봐야 하는 것들이 있겠다.

Active-Standby 방식을 사용하는 이유

Active-Active 방식도 가능 한데, 굳이 Active-Standby 방식을 사용한 이유에 대해서 생각해볼 여지가 있다. Active-Active 방식으로 할 경우 Mesos 클러스터에 있는 모든 mesos-master와 marathon들의 동기화를 위해서, mesos salve의 정보들을 주키퍼를 통해서 공유해야 한다. 이 경우 Mesos slave의 모든 정보를 주키퍼에 저장해야 하기 때문에, 쓰기 작업이 늘어날 것이다. Mesos 류의 애플리케이션은 데이터 센터 단위의 노드를 관리하기 위해서 만들어졌기 때문에 충분히 문제가 될 수 있다.

Active-Standby로 한다면, 하나의 Mesos master만 데이터를 가지고 있으면 되므로 데이터 동기화에 신경쓸 필요가 없다. 그냥 active 상태의 Mesos master가 메모리에 Mesos slave의 정보를 가지고 있으면 된다. 만약 active mesos에 문제가 생겨서 새로운 messos master가 leader로 선택될 경우, master slave들은 자신들이 가지고 있는 정보를 재 전송하기만 하면 된다.

실제 주키퍼 자료구조를 보면 /messos에는 messos master 노드 정보만 가지고 있음을 알 수 있다. 비록 주키퍼가 분산 잠금, 분산 데이터 공유를 지원한다고 해도 가능한 데이터는 공유하지 않는게 좋다. 이런 점에서 Active-Standby는 좋은 선택이라고 할 수 있다.