Mesos+Zookeeper+Marathon+Docker分佈式集羣管理最佳實踐

本文來自於老男孩架構班-趙班長佈置年後作業,覺得非常實用,特此分享。

參考趙班長的unixhot以及馬亮blog

筆者QQ572891887

Linux架構交流羣:471443208

1.1Mesos簡介

MesosApache下的開源分佈式資源管理框架,它被稱爲分佈式系統的內核。Mesos最初是由加州大學伯克利分校的AMPLab開發,後在Twitter得到廣泛使用。

Mesos-Master:主要負責管理各個frameworkslave,並將slave上的資源分配給各個framework

Mesos-Slave:負責管理本節點上的各個mesos-task,比如:爲各個executor分配資源。

Framework:計算框架,如:HadoopSparkKafakaElasticSerach等,通過MesosSchedulerDiver接入Mesos

Executor:執行器,就是安裝到每個機器節點的軟件,這裏就是利用docker的容器來擔任執行器的角色。具有啓動銷燬快,隔離性高,環境一致等特點。

 

Mesos-Master是整個系統的核心,負責管理接入Mesos的各個framework(frameworks_manager管理)slave(slaves_manager管理),並將slave上的資源按照某種策略分配給framework(由獨立插拔模塊Allocator管理)

 

Mesos-Slave負責接受並執行來自Mesos-master的命令、管理節點上的mesos-task,併爲各個task分配資源。Mesos-slave將自己的資源量發送給mesos-master,由mesos-master中的Allocator模塊決定將資源分配給哪個framework,當前考慮的資源有CPU和內存兩種,也就是說,Mesos-slave會將CPU個數的內存量發送給mesos-master,而用戶提交作業時,需要指定每個任務需要的CPU個數和內存。這樣:當任務運行時,mesos-slave會將任務放導包含固定資源Linux container中運行,以達到資源隔離的效果。很明顯,master存在單點故障問題,爲此:Mesos採用了Zookeeper解決該問題。

 

Framework是指外部的計算框架,如果HadoopMesos等,這些計算框架可通過註冊的方式接入Mesos,以便Mesos進行統一管理和資源分配。Mesos要求可接入的框架必須有一個調度模塊,該調度器負責框架內部的任務調度。當一個framework想要接入Mesos時,需要修改自己的調度器,以便向Mesos註冊,並獲取Mesos分配給自己的資源,這樣再由自己的調度器將這些資源分配給框架中的任務,也就是說,整個Mesos系統採用了雙層調度框架:第一層,Mesos將資源分配給框架。第二層,框架自己的調度器將資源分配給自己內部的任務。當前Mesos支持三中語言編寫的調度器,分別是C++JavaPython。爲了向各種調度器提供統一的接入方式,Mesos內部採用C++實現了一個MesosSchedulerDriver(調度驅動器)framework的調度器可調用該driver中的接口與Mesos-master交互,完成一系列功能(如註冊,資源分配等。)

 

Executor主要用於啓動框架內部的task。由於不同的框架,啓動task的接口或者方式不同,當一個新的框架要接入mesos時,需要編寫一個Executor,告訴Mesos如何啓動該框架中的task。爲了向各種框架提供統一的執行器編寫方式,Mesos內部採用C++實現了一個MesosExecutorDiver(執行器驅動器)framework可通過該驅動器的相關接口告訴Mesos啓動task的方式。

 

整體架構如圖1.1-1所示

wKiom1bmWu-z92-XAAKgpXHw9C8743.jpg

1.1-1總體架構

1.1-1展示了Mesos的重要組成部分,Mesos由一個master進程管理運行着每個客戶端節點的slave進程和跑任務的Mesos計算框架。

Mesos進程通過計算框架可以很細緻的管理cpu和內存等,從而提供資源。每個資源提供都包含了一個清單(slave ID,resource1amount1,resource2,amount2,…)master會根據現有的資源決定提供每個計算框架多少資源。例如公平分享或者根據優先級分享。

爲了支持不同種的政策,master通過插件機制新增額一個allocation模塊使之分配資源更簡單方便。

一個計算框架運行在兩個組建之上,一個是Scheduler,他是master提供資源的註冊中心,另一個是Executor程序,用來發起在slave節點上運行計算框架的任務。master決定給每個計算框架提供多少計算資源,計算框架的調度去選擇使用哪種資源。當一個計算框架接受了提供的資源,他會通過Mesos的任務描述運行程序。Mesos也會在相應的slave上發起任務。

 

資源提供案例,如圖1.1-2所示

wKioL1bmW4nh4iJ1AAJeigoxmMg207.jpg

1.1-2資源提供案例

下面我帶大家一起熟悉圖1.1-2的流程步驟

1slave1報告給master他擁有4cpu4G剩餘內存,Marathon調用allocation政策模塊,告訴slave1計算框架1應該被提供可用的資源。

2master給計算框架1發送一個在slave上可用的資源描述。

3、計算框架的調度器回覆給master運行在slave上兩個任務相關信息,任務1需要使用2CPU,內存1G,任務2需使用1CPU2G內存。

4、最後,master發送任務給slave,分配適當的給計算框架執行器,繼續發起兩個任務(1.1-2虛線處),因爲任有1CPU1G內存未分配,allocation模塊現在或許提供剩下的資源給計算框架2

除此之外,當任務完成,新的資源成爲空閒時,這個資源提供程序將會重複。

1.2Zookeeper簡介

Zookeeper是一個分不是的,開放源碼的分佈式應用程序協調服務,是GoogleChuby一個開源的實現,是HadoopHbase的重要組件。它是一個分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、名字服務、分佈式同步、組服務等。

1.2.1Zookeeper角色

Leader(領導者):負責投票發起和決議,更新系統狀態。

follower(跟隨者)Follower用於接收客戶請求並向客戶端返回結果,在選主過程中參與投票。

ObServer(觀察者)ObServer可以接受客戶端連接,將寫請求轉發給Leader節點,但ObServer不參加投票過程,只同步Leader的狀態,ObServer的目的是爲了拓展系統,提高讀取速度。

Client(客戶端):請求發起方。

1.2.2Zookeeper工作原理

Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和Leader的狀態同步以後,回覆模式就結束了。狀態同步保證了LeaderServer具有相同的系統狀態。

爲了保證事物的順序一致性,Zookeeper採用了遞增的事物ID(zxid)來標識事物。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識Leader關係是否改變,每次一個Leader被選出來,它都會有每一個Server在工作過程中三中狀態。

  • LOOKING:當前Server不知道Leader是誰,正在搜尋。

  • LEADING:當前Server即爲選舉出來的Leader

  • FOLLOWINGLeader已經選舉出來,當前Server與之同步。

Leader崩潰或者Leader失去大多數的Follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的Leader,讓所有的Server都恢復到一個正確的狀態。

ZK的選舉算法有兩種:

1、基於Basic paxos實現

2、基於fast paxos算法實現

系統默認的選舉算法爲fast paxos

1.2.4Zookeeper同步流程

選完Leader以後,zk就進入狀態同步過程。

  • Leader等待server連接。

  • Follower連接Leader,將最大的zxid發送給Leader

  • Leader根據Followerzxid確定同步點。

  • 完成同步後通知Follower已經成爲uptodate狀態。

  • Follower收到uptodate消息後,又可以重新接受client的請求進行服務。

Leader三大功能:

  • 恢復數據

  • 維持與learner的心跳,接收learner請求並判斷learner的請求消息類型

  • learner的消息類型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根據不同的消息類型,進行不同的處理。

PING消息是指Learner的心跳信息;REQUEST消息是Follower發送的提議信息,包括寫請求及同步請求;ACK消息是Follower的回覆,超半數的Followercommit該提議;REVALIDATE消息是用來延SESSION有效時間

 

Follower主要四大功能:

  • Leader發送請求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息)。

  • 接收Leader消息並進行處理。

  • 接收Client的請求,如果爲寫請求,發送給Leader進行投票。

  • 返回Client結果。

 

Follower的消息循環處理如下幾種來自Leader的消息:

  • PING消息:心跳消息。

  • PROPOSAL消息:Leader發起的提案,要求Follower投票。

  • COMMIT消息:服務器端最新一次提案的信息。

  • UPTODATE消息:表明同步完成。

  • REVALIDATE消息:根據LeaderREVALIDATE結果,關閉待revalidatesession還是允許其接受消息。

  • SYN消息:返回SYNC結果到客戶端,這個消息最初由客戶端發起,用來強制得到最新的更新。

  • 簡介

Marathon是一個Mesos框架,能夠支持運行長服務,比如Web應用等。它是集羣的分佈式init.d能夠原樣運行任何Linux二進制發佈版本,如TomcatPlay等等。它也是一種私有的PaSS,實現服務的發現,爲部署提供REST API服務,有授權和SSL、配置約束,通過HaProxy實現服務發現和負載平衡。

1.4docker集羣實踐

1.4.1集羣環境準備

主機名

IP地址(Host-Only)

描述

linux-node1.com

eth0:192.168.56.11

Mesos MasterMesos SlaveMarathon

linux-node2.com

eth0:192.168.56.12

ZookeeperMesos Slave

Zookeeper使用分佈式不是,也就是一臺虛機上啓三個不同端口的Zookeeper

 

Linux-node1實踐環境

[root@linux-node1 ~]# cat /etc/redhat-release #查看系統版本

CentOS Linux release 7.1.1503 (Core)

[root@linux-node1 ~]# uname -r #查看內核信息

3.10.0-229.el7.x86_64

[root@linux-node1 ~]#  getenforce#檢測selinux是否關閉

Permissive

[root@linux-node1 ~]# systemctl stop firewalld #關閉firewall防火牆

Linux-node2實踐環境

[root@linux-node2 ~]# cat /etc/redhat-release #查看系統版本

CentOS Linux release 7.1.1503 (Core)

[root@linux-node2 ~]# uname -r #查看內核信息

3.10.0-229.el7.x86_64

[root@linux-node2 ~]#  getenforce #檢測selinux是否關閉

Permissive

[root@linux-node2 ~]# systemctl stop firewalld #關閉firewall防火牆

1.4.2Zookeeper僞集羣安裝部署

部署Zookeeper需要java支持, 主流1.7,穩定最新1.8,開發最新1.9,這邊選擇yum安裝即可支持Zookeeper

[root@linux-node2 ~]# yum install -y java  #安裝java

[root@linux-node2 ~]# cd /usr/local/src/ #進入源碼安裝目錄

[root@linux-node2 src]# wget http://mirrors.cnnic.cn/apache/zookeeper/stable/zookeeper-3.4.8.tar.gz #下載Zookeeper穩定版3.4.8

[root@linux-node2 src]# tar xf zookeeper-3.4.8.tar.gz  #解壓Zookeeper

[root@linux-node2 src]# mv zookeeper-3.4.8 /usr/local/ #Zookeeper移動/usr/local/

[root@linux-node2 src]# ln -s /usr/local/zookeeper-3.4.8/ /usr/local/zookeeper #Zookeeper做一個軟鏈接,方便以後升級等操作

1.4.2.1Zookeeper配置文件詳解

由於是僞集羣的配置方式,B(IP地址)都是一樣,所以不同的Zookeeper實例通信端口號不能一樣,所以要給它分配不同的端口號。

[root@linux-node2 src]# cd /usr/local/zookeeper/conf/ #進入Zookeeper配置文件目錄

[root@linux-node2 conf]# mv zoo_sample.cfg zoo.cfg #重新命名爲zoo.cfg

[root@linux-node2 conf]# cat zoo.cfg

tickTime=2000 #Zookeeper服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個tickTime時間就會發送一個心跳。

initLimit=10 #ZookeeperLeader接受客戶端(Follower)初始化連接時最長能忍受多個個心跳時間間隔數。當已經超過5個心跳的時間(也就是tickTime)長度後Zookeeper服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是5*200010秒。

syncLimit=5 #表示LeaderFollower之間發送消息時請求和應答時間長度,最長不能超過多少個tickTime的時間長度,總的時間長度就是2*2000=4秒。

dataDir=/tmp/zookeeper #數據存放目錄

clientPort=2181 #客戶端連接端口

#maxClientCnxns=60 #對於一個客戶端的連接數限制,默認是60,但是有的團隊將幾十個應用全部部署到一臺機器上,以方便測試,這樣這個數值就會超過。

#autopurge.purgeInterval=1 #指定了清理頻率,單位是小時,需要填寫一個1或更大的整數,默認是0,表示不開啓自己清理功能。

#autopurge.snapRetainCount=3 #這個參數和上面的參數搭配使用,這個參數指定了需要保留的文件數目。默認是保留3個。

server.A=BCD

A#代表一個數字,表示這個是幾號服務器。

B#代表服務器的IP地址。

C#代表服務器與集羣中的Leader服務器交換信息的端口。

D#如果集羣中的Leader服務器掛了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。

1.4.2.2Zookeeper配置文件修改

由於是僞集羣的配置方式,B(IP地址)都是一樣,所以不同的Zookeeper實例通信端口號不能一樣,所以要給它分配不同的端口號。

[root@linux-node2 conf]# grep '^[a-z]' zoo.cfg#過濾出修改好的配置

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zk1

clientPort=2181

server.1=192.168.56.12:3181:4181

server.2=192.168.56.12:3182:4182

server.3=192.168.56.12:3183:4183

1、創建三個目錄來存放Zookeeper的數據

[root@linux-node2 conf]# mkdir -p /data/{zk1,zk2,zk3}

[root@linux-node2 conf]# echo "1" > /data/zk1/myid

[root@linux-node2 conf]# echo "2" > /data/zk2/myid

[root@linux-node2 conf]# echo "3" > /data/zk3/myid

2、生成三份Zookeeper配置文件

[root@linux-node2 conf]# pwd

/usr/local/zookeeper/conf

[root@linux-node2 conf]# cp zoo.cfg zk1.cfg

[root@linux-node2 conf]# cp zoo.cfg zk2.cfg

[root@linux-node2 conf]# cp zoo.cfg zk3.cfg

3、修改zk2zk3對應的數據存放目錄以及端口

[root@linux-node2 conf]# pwd

/usr/local/zookeeper/conf

[root@linux-node2 conf]# sed -i 's#zk1#zk2#g' zk2.cfg

[root@linux-node2 conf]# sed -i 's#zk1#zk3#g' zk3.cfg

[root@linux-node2 conf]# sed -i 's#2181#2182#g' zk2.cfg

[root@linux-node2 conf]# sed -i 's#2181#2183#g' zk3.cfg

1.4.2.3Zookeeper角色查看

1、啓動Zookeeper並查看角色

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk1.cfg #啓動zk1

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk1.cfg

Starting zookeeper ... STARTED

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk2.cfg #啓動zk2

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk2.cfg

Starting zookeeper ... STARTED

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk3.cfg #啓動zk3

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk3.cfg

Starting zookeeper ... STARTED

 

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk1.cfg    

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk1.cfg

Mode: follower #zk1當前狀態Follower

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk2.cfg 

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk2.cfg

Mode: leader #zk2當前狀態Leader

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk3.cfg 

ZooKeeper JMX enabled by default

Using config: /usr/local/zookeeper/conf/zk3.cfg

Mode: follower #zk3當前狀態Follower

2、連接Zookeeper

[root@linux-node2 conf]# /usr/local/zookeeper/bin/zkCli.sh -server 192.168.56.12:2181

1.5Mesos集羣部署

安裝Mesosphere倉庫,需要在Mesos MasterMesos Slave節點安裝

1.5.1Mesos_Master部署

[root@linux-node1 ~]# rpm -ivh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm #node1安裝Mesosphere倉庫

[root@linux-node1 ~]# yum -y install mesos marathon #安裝MesosMarathon

[root@linux-node1 ~]# cat /etc/mesos/zk #增加Zookeeper配置

zk://192.168.56.12:2181,192.168.56.12:2182,192.168.56.12:2183/mesos

[root@linux-node1 ~]# systemctl enable mesos-master mesos-slave marathon #加入開機啓動 Mesos-master slave Marathon

[root@linux-node1 ~]# systemctl start mesos-master mesos-slave marathon #啓動Mesos-master slave Marathon

1.5.2Mesos_Slave部署

[root@linux-node2 ~]# rpm -ivh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm #node2安裝Mesosphere倉庫

[root@linux-node2 ~]# yum -y install mesos #安裝Mesos

[root@linux-node2 ~]# systemctl start mesos-slave #啓動Mesos-slave

1.5.3Mesos_Web界面

訪問:http://192.168.56.11:5050如圖1.5-1所示

wKiom1bmWyDRLkiVAAIP5Egfxs4927.jpg

1.5-1Tasks表格沒有任何條目

運行Mesos任務,可以在Web界面查看task如圖1.5-2所示

[root@linux-node1 ~]# MASTER=$(mesos-resolve `cat /etc/mesos/zk`)

[root@linux-node1 ~]# mesos-execute --master=$MASTER --name="cluster-test"--command="sleep 60"

wKioL1bmXAGDfJdKAAJU4JiNvNo198.jpg

1.5-2運行Mesos任務

1.5.4Marathon調用Mesos運行Docker容器

[root@linux-node1 ~]# yum -y install docker #安裝Docker

[root@linux-node1 ~]# systemctl enable docker #Docker加入開機自啓動

[root@linux-node1 ~]# systemctl start docker #啓動Docker容器

[root@linux-node1 ~]# docker pull nginx #pull一個nginx鏡像

 

linux-node1:再所有mesos-slave上增加配置參數,並重啓

[root@linux-node1 ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers

[root@linux-node1 ~]# systemctl restart mesos-slave #重啓Mesos-slave

 

linux-node2: 再所有mesos-slave上增加配置參數,並重啓

[root@linux-node2 ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers

[root@linux-node2 ~]# systemctl restart mesos-slave #重啓Mesos-slave

通過marathon默認監聽8080端口,通過marathon創建項目,如圖1.5-3所示

wKioL1bmXBXB0UHRAAGd6xstJ4I149.jpg

1.5-3Marathon界面

下面通過Mesos調度,使用marathon來創建一個nginx鏡像的Docker容器,Marathon啓動時會讀取/etc/mesos/zk配置文件,Marathon通過Zookeeper來找到Mesos Master

 

Marathon有自己的REST API,我們通過API的方式來創建一個NginxDocker容器。首先創建如下的配置文件nginx.json

[root@linux-node1 ~]# cat nginx.json

{

"id":"nginx",

"cpus":0.2,

"mem":32.0,

"instances": 1,

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

"container": {

"type":"DOCKER",

"docker": {

"p_w_picpath": "nginx",

"network": "BRIDGE",

"portMappings": [

{"containerPort": 80, "hostPort": 0,"servicePort": 0, "protocol": "tcp" }

]

  }

    }

      }

使用curl的方式調用

[root@linux-node1 ~]# curl -X POST http://192.168.56.11:8080/v2/apps -d @/root/nginx.json -H "Content-type: application/json"

[root@linux-node1 ~]# docker ps -a #查看通過API和手動創建的容器

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES

1231814cd679        nginx               "nginx -g 'daemon off"   56 seconds ago      Up 55 seconds       443/tcp, 0.0.0.0:31011->80/tcp   mesos-16f943e5-be56-4254-858e-6347b89779de-S0.c47be185-eafc-4bd6-b0ca-e13e4536440b

訪問Docker隨機啓動的端口31011,如圖1.5-4所示

wKiom1bmW57jPMXRAAFbvK1brqg967.jpg

1.5-4成功訪問Nginx界面

MarathonWeb界面查看,如圖1.5-5所示

wKioL1bmXDeCtJNlAAGg9tsfXao713.jpg

1.5-5MarathonWeb界面查看Nginx已經在運行

Mesos界面查看,如圖1.5-6所示

wKiom1bmW7-jFjlSAAJTx2mseT4798.jpg

1.5-5Mesos界面查看Nginx Tasks

也可以點擊Marathon左上角的創建進行創建容器。

 

注意:這裏哪Nginx來舉例,註冊中心的marathon+mesos+docker集羣是不適合用於服務的,也就是說不適合於對外開放端口的。比如說爬蟲,因爲不開放端口,需要做的僅僅是從隊列中取資源,然後處理,存庫。

這個僅僅是job的發佈管理運行,還有沒CI,也就是說持續集成,後期我會發布jenkins+docker+mesos+marathon+git持續集成的方案,如果將代碼發佈結合DCO框架。

 

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