一步一步搭建ZooKeeper + Mesos + Marathon平臺管理Docker集羣

最近在Youtube看Docker視頻的過程中不幸看到了Mesos的介紹,然後就有一種一見如故的感覺,最終根據mesosphere官網的文檔在IBM的Bluemix虛擬機上搭建了基於ZooKeeper + Mesos + Marathon的平臺。


搭建之前先簡單瞭解下各個組件是做什麼的。(來自wikipedia及其他網絡)


ZooKeeper:Zookeeper 分佈式服務框架是 Apache Hadoop 的一個子項目,它主要是用來解決分佈式應用中經常遇到的一些數據管理問題,如:統一命名服務、狀態同步服務、集羣管理、分佈式應用配置項的管理等。官網:https://zookeeper.apache.org/


Mesos:來自mesosphere的定義是Mesos是下一代的雲數據中心的kernel,它是Apache下的開源分佈式資源管理框架,作者之一Benjamin在Mesosconf上一直強調Mesos只做kernel的事情,只做scheduling,並不實際運行任務。現該作者也去了Mesosphere公司做雲數據中心操作系統DC/OS的工作(看起來很令人興奮的軟件)。


Marathon:是Mesos的一個框架,能夠支持運行長期任務,也與這個名字有點關聯,馬拉松本身就是長時間要完成的任務,它可以提供REST API服務,可以通過HAProxy實現服務發現和負載均衡。(負載均衡可以看mesosphere公司開源的marathon-lb https://github.com/mesosphere/marathon-lb/)


Docker:就不用介紹了吧。記住它是應用容器引擎,可以給微服務提供完美的運行環境,儘量一個容器只有一個服務。


下面說一下服務器的運行環境:總共六臺服務器,三臺運行Mesos-master,4臺運行Mesos-slave,服務器都是IBM Bluemix上申請的虛擬機,處於一個***網絡裏,底層是基於Openstack的架構,在底層是Softlayer和Cloudfoundry。


Server NameInternal IpOperation SystemRoles
bastion.shanker192.168.0.33Centos 6.7Mesos Master1,ZooKeeper, slave, Jenkins,Haproxy
dbmaster.shanker192.168.0.28Centos 6.7Mesos Master2,ZooKeeper
dbslave2.shanker192.168.0.31Centos 6.7Mesos Master3,ZooKeeper
dbslave3.shanker192.168.0.32Centos 6.7Mesos Slave
dbslave.shanker192.168.0.29Ubuntu 14.04Mesos Slave
dbarbiter.shanker192.168.0.30Ubuntu 14.04Mesos Slave,Mysql Slave


軟件安裝:

RedHat 6 / CentOS 6


# Add the repository
sudo rpm -Uvh http://archive.cloudera.com/cdh4/one-click-install/redhat/6/x86_64/cloudera-cdh-4-0.x86_64.rpm 

yum -y install mesos marathon zookeeper


所有機器用ansible安裝Java:


ansible mesos -m shell -a "wget http://download.oracle.com/otn-pub/java/jdk/8u73-b02/jdk-8u73-linux-x64.tar.gz "
ansible mesos -m shell -a "tar zxf jdk-8u73-linux-x64.tar.gz -C /usr/java/


導入jre到.zshrc,然後用ansible分發下去:


export JAVA_HOME=/usr/java/jdk1.8.0_73
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar



Master Node Setup


ZooKeeper的配置:


在三臺ZooKeeper server上設置ID,這個數字必須是1到255的整數,並且每個節點的ID是不一樣的。


sudo zookeeper --server-initialize --myid=<YOUR ID HERE>


編輯/etc/zookeeper/conf/zoo.cfg,在每臺機器上都需要添加zk 集羣的服務器名稱,ip地址,端口號等信息:server.A=B:C:D


server.1=192.168.0.33:2888:3888
server.2=192.168.0.28:2888:3888
server.3=192.168.0.31:2888:3888


A:代表一個1-255的整數,是第幾號服務器,可以隨便定義。

B:代表服務器的ip地址。

C:代表服務器與集羣中的Leader通信的端口。

D:代表如果集羣中的Leader down了,需要用這個端口來重新選舉,如果使用一臺主機多個zk實例,這個D的值不能與C相同。

zk最終的配置:


# egrepv /etc/zookeeper/conf/zoo.cfg
maxClientCnxns=50
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper
clientPort=2181
server.1=192.168.0.33:2888:3888
server.2=192.168.0.28:2888:3888
server.3=192.168.0.31:2888:3888


一份簡單的zk配置就完成了,sudo service zookeeper restart。


Mesos & Marathon的配置:


在每一個master節點添加以下文件,並把master的ip地址寫進去:


# cat /etc/mesos/zk
zk://192.168.0.33:2181,192.168.0.28:2181,192.168.0.31:2181/mesos


Quorum的設定原則是Mesos master的數量除以2得到的整數,我們用了3個maser,除以2 是1.5,得到的整數是2,所以這裏用2


# cat /etc/mesos-master/quorum 
2


Hostname的設置是可選的,如果有DNS的前提下,可以不用設置,但是爲了避免後期出現不能解析域名的情況,我這裏設置的hostname,在每一臺機器(包括slave)的/etc/mesos-{master,slave}/hostname的文件裏寫上改機器的ip地址,注意:每臺機器只需要寫自己機器的ip即可,不需要把所有機器的ip都寫進去:


$ ansible all -m shell -a 'cat /etc/mesos-master/hostname' -s
bastion | success | rc=0 >>
192.168.0.33
dbmaster | success | rc=0 >>
192.168.0.28
dbslave2 | success | rc=0 >>
192.168.0.31


然後將hostname 複製到Marathon的目錄一份:


cp /etc/mesos-master/hostname /etc/marathon/conf/


如果你不需要master的機器跑slave的話,需要將slave的功能override


sudo stop mesos-slave
sudo sh -c "echo manual > /etc/init/mesos-slave.override"


然後沒有問題的話就可以start Mesos-master和Marathon了。


ansible master -m shell -a "start mesos-msater && start marathon"


Slave Node Setup


安裝mesos-slave軟件

Debian/Ubuntu


# Setup
# sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
# DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
# CODENAME=$(lsb_release -cs)
#
# # Add the repository
# echo "deb http://repos.mesosphere.com/${DISTRO} ${CODENAME} main" | \
#   sudo tee /etc/apt/sources.list.d/mesosphere.list
#   sudo apt-get -y update
#   sudo apt-get -y install mesos


RedHat/CentOS6


#   # Add the repository
#   sudo rpm -Uvh 
#   sudo yum -y install mesos


如果系統使用的是Ubuntu like的系統,需要將自動安裝的ZooKeeper禁用


sudo service zookeeper stop
sudo sh -c "echo manual > /etc/init/zookeeper.override"


配置zk,跟master節點的內容一樣,可以使用ansible 分發到slave節點:


# cat zk
zk://192.168.0.33:2181,192.168.0.28:2181,192.168.0.31:2181/mesos


要支持運行Docker,還需要在slave節點/etc/mesos-slave/添加兩個文件:containerizers,executor_registration_timeout,文件內容如下:


# ibmcloud at dbarbiter.shanker in /etc/mesos-slave [15:43:23]
$ cat containerizers
docker,mesos
# ibmcloud at dbarbiter.shanker in /etc/mesos-slave [15:43:27]
$ cat executor_registration_timeout
5mins



需要配置的就這麼多,接下來就是要在slave節點上禁用mesos-master,要不然選舉的時候會出莫名其妙的錯的


sudo service mesos-master stop
sudo sh -c "echo manual > /etc/init/mesos-master.override"


然後開啓slave服務


Ubuntu:


sudo service mesos-slave restart


CentOS:


sudo start mesos-slave


然後在瀏覽器裏輸入一個master節點的ip:5050看看是否有Mesos的console出現,如果輸入的ip地址不是leader,mesos會自動跳轉到Leader的ip地址上:


wKiom1dWdtKBZ_ltAABGhFaHrUU879.png-wh_50


登錄進Mesos-master的dashborad之後會發現有顯示Cluster Name, 當前Leader的ip地址,有多少Slaves, Resources具體情況,Active Tasks,即當前的任務都有哪些,Completed Tasks,:


wKiom1dWek7wnJU0AAFg89Qzj3I873.png


如果不確認當前的Marathon的Leader ip是哪個,可以看Mesos-master的Framework頁面,來查看Marathon的ip:


wKiom1dWdtTxZ14xAABbPB2rlq4998.png-wh_50


然後Marathon的界面如下:


wKiom1dWejiDNEiOAAE_DqDLK1c752.jpg


利用這個UI界面可以很容易的創建應用,並且可以以json的方式編輯,只要右上角這個JSON Mode被選中即可:


wKioL1dWe9ST2eLhAAAzsnC0lq8224.png


比如我們創建一個python的應用程序,來看看後來Docker是否正常運行:


wKioL1dWd9nxpg8XAABx_cpeGw8605.png-wh_50


有了這個平臺創建基於Docker的應用非常容易,而且擴展起來也是秒級的,比如我們創建了一個Nginx的應用,然後需要擴展到5個,只需要點擊Scale Application,輸入5,後臺就自動擴展了5個Nginx的應用。

然後就是故障自動轉移,加入我們去後臺終止一個正在運行的容器,Marathon會自動檢測到正在運行的任務與設置的不一樣,而立馬新創建一個應用。

初了用web ui的方式來創建任務,也可以使用API的形式:

比如我這裏有個2048遊戲的json格式的文件,使用的image爲nginx:latest,將本地的/home/ibmcloud/2048-maser/ 映射到容器的nginx根目錄,採用BRIDGE網絡,expose容器的80端口,並對改容器進行http的健康檢查:


$ cat nginx-bridge-2048game.json 
{
  "id": "/nginx",
  "cpus": 1,
  "mem": 128,
  "disk": 0,
  "instances": 1,
  "container": {
    "type": "DOCKER",
    "volumes": [
      {
        "containerPath": "/usr/share/nginx/html/",
        "hostPath": "/home/ibmcloud/2048-master/",
        "mode": "RO"
      }
    ],
    "docker": {
      "image": "nginx",
      "network": "BRIDGE",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp",
          "servicePort": 80,
          "labels": {}
        }
      ],
      "privileged": false,
      "parameters": [],
      "forcePullImage": false
    }
  },
  "healthChecks": [
    {
      "path": "/",
      "protocol": "HTTP",
      "portIndex": 0,
      "gracePeriodSeconds": 120,
      "intervalSeconds": 30,
      "timeoutSeconds": 5,
      "maxConsecutiveFailures": 3,
      "ignoreHttp1xx": false
    }
  ],
  "portDefinitions": [
    {
      "port": 10003,
      "protocol": "tcp",
      "labels": {}
    }
  ]
}


在Marathon的Leader機器上運行


# curl -u username:password -i -H 'Content-Type: application/json' [email protected] 192.168.0.33:8080/v2/apps 
HTTP/1.1 201 Created
Date: Tue, 07 Jun 2016 07:59:17 GMT
X-Marathon-Leader: http://192.168.0.33:8080
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Location: http://192.168.0.33:8080/v2/apps/nginx
Content-Type: application/json; qs=2
Transfer-Encoding: chunked
Server: Jetty(9.3.z-SNAPSHOT)
{"id":"/nginx","cmd":null,"args":null,"user":null,"env":{},"instances":1,"cpus":1,"mem":128,"disk":0,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[80],"portDefinitions":[{"port":80,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[{"containerPath":"/usr/share/nginx/html/","hostPath":"/home/ibmcloud/2048-master/","mode":"RO"}],"docker":{"image":"nginx","network":"BRIDGE","portMappings":[{"containerPort":80,"hostPort":0,"servicePort":80,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[{"path":"/","protocol":"HTTP","portIndex":0,"gracePeriodSeconds":120,"intervalSeconds":30,"timeoutSeconds":5,"maxConsecutiveFailures":3,"ignoreHttp1xx":false}],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"ipAddress":null,"version":"2016-06-07T07:59:18.003Z","residency":null,"tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"c30b9f6e-786c-45bd-9e7e-cc6cc001d91d"}],"tasks":[]}#


 爲了方便,可以將這個命令寫入到腳本里運行:


$ cat runapp.sh 
#!/bin/bash
curl -i -H 'Content-Type: application/json' -d@"$1" 192.168.0.33:8080/v2/apps


可以看到我們的2048遊戲已經可以玩了:


wKioL1dWgU7yJ_v0AACvbL9AybI448.png



最後強調一下安全問題,因爲我把Marathon暴漏到公網了,而且沒加認證,導致有壞蛋掃描到我的機器,並且創建了一個Metasploit的任務對我的服務器進行***,好在我的安全性做的還可以,兇手沒有得逞,參考這篇文章:http://shanker.blog.51cto.com/1189689/1785797

然後marathon開啓認證的方式是這樣運行的:

marathon --http_credentials "username:password"


注意問題:


1. 需要添加MESOS_QUORUM到/etc/default/mesos-master, 即使/etc/mesos-master/quorum 有這個,也必須要做這一步(來自stackoverflow的解決方案)

# cat /etc/default/mesos-master

PORT=5050

ZK=`cat /etc/mesos/zk`

MESOS_QUORUM=`cat /etc/mesos-master/quorum`


2.  slave start fails, need to delete the slave.info file /tmp/mesos/meta/slaves/latest/slave.info


3.當遇到主節點不是當前節點,瀏覽器自動轉發的時候,用到的轉發的文件是/etc/mesos-master/hostname,是每臺機器的hostname只寫自己的ip地址,而不是將所有master節點ip都寫上,
然後marathon 的hostname同master的hostname,cp 過去即可。


4.遇到這個問題是因爲你的slave沒有禁用mesos-master,或者開啓了mesos-master進程

Failed to create ZooKeeper, zookeeper_init: No such file or directory


5.遇到以下問題需要查看/etc/mesos-master/quorum 是否都設置的數量,而且/etc/default/mesos-master配置文件也有QUORUM的設置,請參考問題1

Replica in VOTING status received a broadcasted recover request from 192.168.0.33:37798


6. 查看mesos 網頁的的LOG ,出現以下內容,纔是正常的

I0524 07:53:33.242832 27506 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
I0524 07:53:41.834223 27507 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:53:44.241183 27509 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
I0524 07:53:52.034374 27502 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:53:55.241883 27504 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
I0524 07:54:02.236343 27505 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:54:06.243017 27508 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
I0524 07:54:13.141284 27507 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:54:22.238883 27509 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
I0524 07:54:23.345165 27509 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:54:33.545162 27509 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'
I0524 07:54:34.240898 27503 http.cpp:312] HTTP GET for /master/state from 124.193.167.1:18148 with User-Agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'

I0524 07:54:43.755383 27504 http.cpp:312] HTTP GET for /master/state from 192.168.0.33:37798 with User-Agent='Mozilla/5.0 (Windows NT 6.1; rv:46.0) Gecko/20100101 Firefox/46.0'


8.要支持Docker任務,一定要添加這兩個文件到salve下。

/etc/mesos-slave/{containerizers,executor_registration_timeout }




參考文檔:

https://open.mesosphere.com/getting-started/install/

https://www.youtube.com/watch?v=hZNGST2vIds&feature=youtu.be

https://www.youtube.com/watch?v=EgYyf3bSb8Q

https://www.youtube.com/watch?v=_uw1ISM_uRU



歡迎補充!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章