天天看點

Mesos+Marathon+zk+docker建構PaaS平台

參考文檔:

mesos:http://mesos.apache.org/documentation/latest/

mesosphere社群版:https://github.com/mesosphere/open-docs

mesosphere倉庫:https://github.com/mesosphere/open-docs/blob/master/downloads/mesos.md

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

chronos: https://mesos.github.io/chronos/docs/

consul:https://www.consul.io/ https://releases.hashicorp.com/consul/

docker安裝:https://docs.docker.com/engine/installation/linux/docker-ce/centos/

mesos 叢集資源管理架構(以叢集的形式出現,主決定資源的配置設定,從負責執行executor),配置設定資源,提供offer給framework,不負責排程資源,千言萬語都在這裡了mesos的設計結構。

marathon 是mesos的framework,容器編排系統,保證長時間的運作任務,類似背景執行或者supervisor。

zooKeeper是一個分布式的,開放源碼的分布式應用程式協調服務,是Google的Chubby一個開源的實作,是Hadoop和Hbase的重要元件。它是一個為分布式應用提供一緻性服務的軟體,提供的功能包括:配置管理維護、域名服務、分布式同步、組服務、健康檢查,HA等。

Chronos是一個運作在Mesos之上的具有分布式容錯特性的作業排程器。在Airbnb公司,它是cron的替代品。與cron相比,Chronos在很多方面具備優勢。比如,它支援ISO8601标準,允許更靈活地定義排程時間;Chronos也支援任務依賴,即一個作業的開始依賴于一些任務的完成,和marathon一樣都是聽從mesos的指令,給mesos搬磚的。

consul經常拿來和etcd、 zookeeper來對比,他有和etcd一樣的服務發現、服務注冊功能,也有和etcd、zookeeper一樣的配置存儲功能,詳細的對比在此不再列出。

Registrator是一個獨立于服務系統資料庫的自動服務注冊/登出元件,一般以容器的方式進行部署。會自動偵測它所在的主控端上的所有 容器狀态(啟用/銷毀),并根據容器狀态到對應的服務注冊清單注冊/登出服務。去除了需要手動管理Consul服務條目的複雜性,它監視容器的啟動和停止,根據容器暴露的端口和環境變量自動注冊服務。

事實上, 通過讀取同一台主控端的其他容器 的環境變量進行服務注冊、健康檢查定義等操作,支援可插拔式的服務系統資料庫配置。

架構圖看起來像這樣:

Mesos+Marathon+zk+docker建構PaaS平台

mesos架構:

Mesos+Marathon+zk+docker建構PaaS平台

架構圖可以看出mesos主要兩部分主和從 ,主叢集依靠zookeeper

架構圖展示了Mesos的重要組成部分,Mesos由一個master程序管理運作着每個用戶端節點的slave程序和跑任務的Mesos計算架構。

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

為了支援不同種的政策,master通過插件機制新增額一個allocation子產品使之配置設定資源更簡單友善。

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

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

Mesos-Master:主要負責管理各個framework和slave,并将slave上的資源配置設定給各個framework。

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

Framework:計算架構,如:Hadoop、Spark、Kafaka、ElasticSerach等,通過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是指外部的計算架構,如果Hadoop、Mesos等,這些計算架構可通過注冊的方式接入Mesos,以便Mesos進行統一管理和資源配置設定。Mesos要求可接入的架構必須有一個排程子產品,該排程器負責架構内部的任務排程。當一個framework想要接入Mesos時,需要修改自己的排程器,以便向Mesos注冊,并擷取Mesos配置設定給自己的資源,這樣再由自己的排程器将這些資源配置設定給架構中的任務,也就是說,整個Mesos系統采用了雙層排程架構:第一層,由Mesos将資源配置設定給架構。第二層,架構自己的排程器将資源配置設定給自己内部的任務。目前Mesos支援三中語言編寫的排程器,分别是C++、Java、Python。為了向各種排程器提供統一的接入方式,Mesos内部采用C++實作了一個MesosSchedulerDriver(排程驅動器),framework的排程器可調用該driver中的接口與Mesos-master互動,完成一系列功能(如注冊,資源配置設定等。)

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

mesos運作流程:

Mesos+Marathon+zk+docker建構PaaS平台

流程步驟:

1、slave1報告給master他擁有4核cpu和4G剩餘記憶體,Marathon調用allocation政策子產品,告訴slave1計算架構1應該被提供可用的資源。

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

3、計算架構的排程器回複給master運作在slave上兩個任務相關資訊,任務1需要使用2個CPU,記憶體1G,任務2需使用1個CPU,2G記憶體。

4、最後,master發送任務給slave,配置設定适當的給計算架構執行器,繼續發起兩個任務(圖1.1-2虛線處),因為任有1個CPU和1G記憶體未配置設定,allocation子產品現在或許提供剩下的資源給計算架構2。

除此之外,當任務完成,新的資源成為空閑時,這個資源提供程式将會重複。

說明:

主機名

IP

OS

安裝服務

mesos-master1

192.168.8.131

CentOS-7.5

mesos-master, marathon,zookeeper, consul-server, chronos, consul-template

mesos-master2

192.168.8.132

mesos-master, marathon,zookeeper, consul-server, chronos

mesos-master3

192.168.8.133

mesos-slave1

192.168.8.134

mesos-slave, docker, registrator

mesos-slave2

192.168.8.135

軟體版本:

服務

版本

作用

zookeeper

3.4.12

保持各master之間的通信,選舉leader、HA

mesos-master

1.6.0

管理接入mesos的各個framework & slave,并将slave上的資源按照相應政策配置設定給framework

mesos-slave

任務執行節點

marathon

1.6.352

排程器,用于下發任務,可保持長應用

docker

1.13.1

具體執行docker下發任務

chronos

3.0+

cron-on-mesos,用來運作基于容器的定時任務的Mesos架構

consul/ registrator

1.1.0/ latest

提供服務自動注冊、發現功能

consul-template

0.19.4

Consul template 搭配consul使用,支援多種負載均衡接入層,如Nginx、Haproxy,LVS

以節點zk-node1為例,zk-node2/3根據情況調整。

# systemctl stop firewalld

# setenforce 0

# systemctl disable firewalld

# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1      localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.8.131  mesos-master1

192.168.8.132  mesos-master2

192.168.8.133  mesos-master3

192.168.8.134  mesos-slave1

192.168.8.135  mesos-slave2

# yum groupinstall -y "Development Tools"

# yum install -y tar wget git lrzsz lsof

ZooKeeper運作在java環境下,文檔中建議安裝jdk 1.7以上版本(含)。

# yum -y install java java-devel

# java -version

openjdk version "1.8.0_171"

OpenJDK Runtime Environment (build 1.8.0_171-b10)

OpenJDK 64-Bit Server VM (build 25.171-b10, mixed mode)

# tar xf zookeeper-3.4.12.tar.gz -C /usr/local

# chown -R root.root /usr/local/zookeeper-3.4.12

# ln -s /usr/local/zookeeper-3.4.12/ /usr/local/zk

# cp /usr/local/zk/conf/zoo_sample.cfg /usr/local/zk/conf/zoo.cfg

zookeeper配置檔案詳解:

下面就是zoo.cfg配置檔案的修改了,那麼我們首先要熟悉下zookeeper配置檔案。

# cat /usr/local/zk/conf/zoo.cfg

dataDir:資料目錄

dataLogDir:日志目錄

clientPort:用戶端連接配接端口

tickTime:Zookeeper 伺服器之間或用戶端與伺服器之間維持心跳的時間間隔,也就是每隔tickTime 時間就會發送一個心跳。

initLimit:Zookeeper的Leader 接受用戶端(Follower)初始化連接配接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是tickTime)長度後 Zookeeper 伺服器還沒有收到用戶端的傳回資訊,那麼表明這個用戶端連接配接失敗。總的時間長度就是 5*2000=10 秒

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

server.A=B:C:D:

A 是一個數字,表示這個是第幾号伺服器;

B 是這個伺服器的 ip 位址;

C 表示的是這個伺服器與叢集中的 Leader 伺服器交換資訊的端口;

D 表示的是萬一叢集中的 Leader 伺服器挂了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時伺服器互相通信的端口。

# grep -Ev "#|^$" /usr/local/zk/conf/zoo.cfg

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/usr/local/zk/data/zk1

dataLogDir=/usr/local/zk/logs

clientPort=2181

maxClientCnxns=60

server.1=192.168.8.131:2888:3888

server.2=192.168.8.132:2888:3888

server.3=192.168.8.133:2888:3888

# mkdir /usr/local/zk/data/zk1 -p

# mkdir /usr/local/zk/logs -p

# echo "1" > /usr/local/zk/data/zk1/myid

# scp -p /usr/local/zk/conf/zoo.cfg [email protected]:/usr/local/zk/conf/zoo.cfg

# scp -p /usr/local/zk/conf/zoo.cfg [email protected]:/usr/local/zk/conf/zoo.cfg

# mesos-master2的zk配置,同樣需要建立dataDir,dataLogDir目錄和myid檔案,檔案内容2

# sed -i 's/zk1/zk2/g' /usr/local/zk/conf/zoo.cfg

# mkdir /usr/local/zk/data/zk2 -p

# echo "2" > /usr/local/zk/data/zk2/myid

dataDir=/usr/local/zk/data/zk2

# mesos-master3的zk配置,同樣需要建立dataDir,dataLogDir目錄和myid檔案,檔案内容3

# sed -i 's/zk1/zk3/g' /usr/local/zk/conf/zoo.cfg

# mkdir /usr/local/zk/data/zk3 -p

# echo "3" > /usr/local/zk/data/zk3/myid

dataDir=/usr/local/zk/data/zk3

啟動zk服務,檢視狀态:

# /usr/local/zk/bin/zkServer.sh start

# /usr/local/zk/bin/zkServer.sh status

zk叢集各節點狀态:

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

zk各節點端口:

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

由此可見,叢集已經正常運作。

Mesos+Marathon+zk+docker建構PaaS平台

用戶端可以通過nc或telnet連接配接ZooKeeper Server送出指令。

ZooKeeper Client 簡單操作:

9個基本操作指令:

Mesos+Marathon+zk+docker建構PaaS平台

Mesos 叢集部署

Mesos叢集有MesosMaster和Mesos Slave兩個角色。

mesosphere倉庫

需要在Mesos Master和MesosSlave節點均安裝。

# 添加mesosphere repository,根據github mesosphere社群版擷取最新repository

# rpm -Uvh http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-2.noarch.rpm

# hostnamectl --static set-hostname mesos-master1 //修改主機名

# yum -y install mesos marathon

mesos-master增加zookeeper配置,選主并增加HA:

# vi /etc/mesos/zk

zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/mesos

# scp /etc/mesos/zk [email protected]:/etc/mesos/zk

# scp /etc/mesos/zk [email protected]:/etc/mesos/zk

設定檔案/etc/master-/quorum内容為一個大于(master節點數除以2)的整數。即采用四舍五入,比如這裡有3個master節點,那麼3/2=1.5,四舍五入為2。

# echo "2" >/etc/mesos-master/quorum

# cat /etc/mesos-master/quorum

2

# scp /etc/mesos-master/quorum [email protected]:/etc/mesos-master/quorum

# scp /etc/mesos-master/quorum [email protected]:/etc/mesos-master/quorum

<code>#</code><code>主機名和ip要在hosts中寫入,最好不要使用localhost,否則會出現slave不能識别,以及marathon任務下發不正常等現象。</code>

# 預設marathon無相關配置目錄/檔案

# mkdir -p /etc/marathon/conf

mesos-master1:

# echo "192.168.8.131" &gt;/etc/mesos-master/hostname

# echo "192.168.8.131" &gt;/etc/mesos-master/ip

# echo "192.168.8.131" &gt;/etc/marathon/conf/hostname

# echo "192.168.8.131" &gt;/etc/marathon/conf/ip

mesos-master2:

# echo "192.168.8.132" &gt;/etc/mesos-master/hostname

# echo "192.168.8.132" &gt;/etc/mesos-master/ip

# echo "192.168.8.132" &gt;/etc/marathon/conf/hostname

# echo "192.168.8.132" &gt;/etc/marathon/conf/ip

mesos-master3:

# echo "192.168.8.133" &gt;/etc/mesos-master/hostname

# echo "192.168.8.133" &gt;/etc/mesos-master/ip

# echo "192.168.8.133" &gt;/etc/marathon/conf/hostname

# echo "192.168.8.133" &gt;/etc/marathon/conf/ip

marathon連接配接mesos-master及HA:

# cp /etc/mesos/zk /etc/marathon/conf/master

# cp /etc/mesos/zk /etc/marathon/conf/zk

# sed -i 's|mesos|marathon|g' /etc/marathon/conf/zk

# cat /etc/marathon/conf/master

# cat /etc/marathon/conf/zk

zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/marathon

# scp /etc/marathon/conf/master [email protected]:/etc/marathon/conf/

# scp /etc/marathon/conf/master [email protected]:/etc/marathon/conf/

# scp /etc/marathon/conf/zk [email protected]:/etc/marathon/conf/

# scp /etc/marathon/conf/zk [email protected]:/etc/marathon/conf/

# systemctl enable mesos-master marathon

# systemctl start mesos-master marathon

# systemctl disable mesos-slave

# systemctl status mesos-master marathon

# systemctl status marathon #marathon啟動報錯

● marathon.service - Scheduler for Apache Mesos

Loaded: loaded (/usr/lib/systemd/system/marathon.service; enabled; vendor preset: disabled)

Active: activating (auto-restart) (Result: exit-code) since Mon 2018-05-14 21:13:32 CST; 37s ago

Process: 25368 ExecStart=/usr/share/marathon/bin/marathon (code=exited, status=1/FAILURE)

……

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

May 14 21:13:32 mesos-master1 systemd[1]: marathon.service: main process exited, code=exited, status=1...LURE

Hint: Some lines were ellipsized, use -l to show in full.

用以下指令 [journalctl -o verbose _PID=24962] 檢視marathon程序的詳細資訊。

# journalctl -o verbose _PID=25368

-- Logs begin at Sun 2018-05-13 03:47:48 CST, end at Mon 2018-05-14 21:08:12 CST. --

Mon 2018-05-14 21:07:04.849490 CST [s=2f8e0393e2dc4d639f4d5bf76a4e9b6f;i=ec5;b=4a9ee33c3e074eb987230b0202c47a

PRIORITY=6

_SYSTEMD_SLICE=system.slice

_BOOT_ID=4a9ee33c3e074eb987230b0202c47a39

_MACHINE_ID=74bb4614536844d798b123d0cc927d4e

SYSLOG_FACILITY=3

_TRANSPORT=stdout

_SELINUX_CONTEXT=system_u:system_r:init_t:s0

_EXE=/usr/bin/bash

_CAP_EFFECTIVE=0

_COMM=bash

_HOSTNAME=mesos-master1

SYSLOG_IDENTIFIER=marathon

MESSAGE=No start hook file found ($HOOK_MARATHON_START). Proceeding with the start script.

_UID=998

_GID=996

_CMDLINE=bash /usr/share/marathon/bin/marathon

_SYSTEMD_CGROUP=/system.slice/marathon.service

_SYSTEMD_UNIT=marathon.service

_STREAM_ID=bd3ee42018a94236baeab1e5f653171f

_PID=24962

Mon 2018-05-14 21:07:08.496043 CST [s=2f8e0393e2dc4d639f4d5bf76a4e9b6f;i=ec6;b=4a9ee33c3e074eb987230b0202c47a

MESSAGE=[scallop] Error: Required option 'master' not found

_COMM=java

_EXE=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.171-7.b10.el7.x86_64/jre/bin/java

_CMDLINE=java -cp /usr/share/marathon/lib/mesosphere.marathon.marathon-1.6.352.jar:/usr/share/marathon/li

通過上述日志可以看出,是找不到master導緻啟動失敗。檢查了下以上關于marathon的所有配置,确認沒有問題。可以根據如下辦法直接帶master參數啟動marathon,最終成功!

# which marathon

/usr/bin/marathon

# nohup marathon --master zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/mesos --zk zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/marathon &amp; &gt;&gt;nohup.out

# ss -tunlp|grep 8080 #8080端口為marathon的程序監聽端口

tcp LISTEN 0 50 :::8080 :::* users:(("java",pid=17946,fd=179))

檢視application的metric

# curl http://192.168.8.131:8080/metrics | python -m json.tool | less

檢視運作的app

# curl http://192.168.8.131:8080/v2/apps | python -m json.tool

檢視ID為nginx-test的app

# curl http://192.168.8.131:8080/v2/apps/nginx-test | python -m json.tool

删除ID為nginx-test的app

# curl -X DELETE http://192.168.8.131:8080/v2/apps/nginx-test | python -m json.tool

以slave-node1為例,slave-node2配置根據環境微調。

# yum install mesos docker –y

# echo "docker,mesos" &gt;/etc/mesos-slave/containerizers

# echo "192.168.8.134"&gt;/etc/mesos-slave/ip

# echo "192.168.8.134" &gt;/etc/mesos-slave/hostname

# systemctl stop mesos-master

# systemctl disable mesos-master

# systemctl enable mesos-slave docker

# systemctl start mesos-slave docker

# systemctl status docker

報錯:Unit dockergetenforce.service could not be found.

解決方法:

重新開機服務

# systemctl status mesos-slave

登陸mesos web:http://192.168.8.131:5050/#/

Mesos+Marathon+zk+docker建構PaaS平台

1. 從首頁可以看到mesos-agent:activated狀态的agent有2個;

2. mesos-master管理的2個agent的資源已彙總。

Mesos+Marathon+zk+docker建構PaaS平台

1. 在mesos架構中,marathon架構已經被識别,marathon的leader是:mesos-master2;

2. 雖然mesos-master與marathon的leader相同,但兩者的leader是zookeeper獨立選舉的,并沒有直接關系,是可以不同的。

Mesos+Marathon+zk+docker建構PaaS平台

1.在Agnets中能看到2個agent;

2.同時能看到每個agent的資源;

點選上面2個slave中的任意一個,也能看出它的master是mesos-master2

Mesos+Marathon+zk+docker建構PaaS平台

通路marathon的管理頁面,http://master_ip:8080

這裡的master_ip就是在上面通路mesos頁面Frameworks中識别出的marathon,即192.168.8.132:8080

或者直接點選mesos通路頁面Frameworks中識别出的marathon也可以。

Mesos+Marathon+zk+docker建構PaaS平台

浏覽器通路:http://192.168.8.132:5050/master/state

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

比如建立一個nginx鏡像的Docker容器,Marathon啟動時會讀取/etc/mesos/zk配置檔案,Marathon通過Zookeeper來找到Mesos Master。

1)Marathon有自己的REST API,我們通過API的方式來建立一個 tomcat 的Docker容器

首先建立一個json檔案(這個要在master節點機器上建立,任意一台master節點機上都可以):

# docker pull nginx

# docker pull tomcat

<code>nginx-example:</code>

{

"id":"nginx", #容器名,隻在marathon生效

"cpus":0.2, #cpu用量

"mem":32.0, #mem用量

"instances": 1, #容器數量

"constraints": [["hostname", "UNIQUE",""]], #限制

"container": {

"type":"DOCKER", #應用類型

"docker": { #docker具體配置

"image": "docker.io/nginx", #采用的image

"network": "BRIDGE", #網絡模式

"portMappings": [

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

] #端口映射,”0”表示任意端口,"servicePort"服務端口

}

<code># vi tomcat.json # tomcat</code><code>的docker鏡像要提前建立或下載下傳</code>

"id":"tomcat-1",

"cpus":0.5,

"mem":64,

"instances": 1,

"constraints": [["hostname", "CLUSTER",""]],

"type":"DOCKER",

"docker": {

"image": "docker.io/tomcat",

"network": "BRIDGE",

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

]

注意:json檔案中的每一行内容的開頭和結尾一定不能有空格,但可以有空行,否則手動通過curl的方式建立容器執行個體,會有各種各樣的報錯!!!

接着使用curl的方式調用,注意上面的<code>tomcat.json</code>檔案是在/root路徑下的(注意下面指令中json檔案路徑)。

# curl -X POST http://192.168.8.131:8080/v2/apps -d @/root/tomcat.json -H "Content-type: application/json"

{"id":"/tomcat-1","backoffFactor":1.15,"backoffSeconds":1,"constraints":[["hostname","CLUSTER",""]],"container":{"type":"DOCKER","docker":{"forcePullImage":false,"image":"docker.io/tomcat","parameters":[],"privileged":false},"volumes":[],"portMappings":[{"containerPort":8080,"hostPort":0,"labels":{},"protocol":"tcp","servicePort":0}]},"cpus":0.5,"disk":0,"executor":"","instances":1,"labels":{},"maxLaunchDelaySeconds":3600,"mem":64,"gpus":0,"networks":[{"mode":"container/bridge"}],"requirePorts":false,"upgradeStrategy":{"maximumOverCapacity":1,"minimumHealthCapacity":1},"version":"2018-05-20T09:20:37.589Z","killSelection":"YOUNGEST_FIRST","unreachableStrategy":{"inactiveAfterSeconds":0,"expungeAfterSeconds":0},"tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"8035fe3f-44a7-4c8d-9f8f-22ecf66ea24f"}],"tasks":[]}

也可以将上面的tomcat.json檔案内容直接複制到marathon建立應用容器的"JSON Mode"模式裡,然後直接點選建立。

Mesos+Marathon+zk+docker建構PaaS平台

登陸marathon界面檢視是在哪一台slave機器上建立的docker容器執行個體(這個是随機的),點選"running"。(如果容器建立失敗,即非"running"狀态,可以嘗試重新開機slave節點的docker服務)

Mesos+Marathon+zk+docker建構PaaS平台

然後登陸mesos-slave1機器,發現在伺服器上,這個容器隻是被關閉了(docker ps -a),可以選擇删除。如果再次在機器上啟動這個nginx容器,那麼在marathon上是不會顯示的。

注意:在節點機器上手動建立的docker容器,這些容器資訊是不會在marathon和mesos裡展示的。

在marathon界面裡"Destory"删除對應的application後,在mesos界面的"Active Tasks"裡的對應任務也會删除。

另外要注意:在marathon界面裡通過調用mesos建立docker容器,隻能建立應用容器(Application),如nginx、tomcat、mysql、redis等,需要映射端口,這裡是映射的是主控端的随機端口。不能建立基本centos,ubuntu的系統容器!

2)nginx執行個體擴容

點選marathon首頁正在運作的nginx執行個體最後面的"…",選擇"Scale",在彈出來的執行個體擴容對話框中,輸入所要擴容的執行個體個數,确定後進行擴容。很快會看到原來正在運作的nginx單執行個體由一個變為多個。Marathon的執行個體擴容同時也有相應的API,也可以在bash下通過api進行擴容。

通路所建立的nginx容器。(marathon ui界面裡建立的docker容器映射到主控端的通路端口預設都是随機配置設定的(BRIDGE模式))、可以自己制作應用的docker鏡像,或者自定義建構容器并送出為新鏡像(自己設定應用容器結構),然後根據自己制作的鏡像在Marathon上建立應用。

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

如以上截圖中可知,這個nginx容器是在mesos-slave1節點機(192.168.8.134)上建立的

注意:如果mesos-slave1節點機當機或docker服務重新開機,那麼這個nginx容器就會自動漂移到其他的slave節點機上;另外,通過上面方式建立好的容器,在單個slave節點機上删除後,容器也會自動轉移到其他slave節點機器上,這樣就實作了在slave節點出現故障時容器自動轉移的高可用功能。

可以登陸mesos-slave1機器檢視所建立的容器,如上可知:通路Docker随機啟動的端口是31725。

接着通路mesos頁面,可以看到"Active Tasks"有剛才建立的nginx任務了。(注意:隻有當mesos通路界面"Active Tasks"裡有容器建立任務時,才說明此容器真正建立成功了)

Mesos+Marathon+zk+docker建構PaaS平台

3)圖形化建立并運作容器

Mesos+Marathon+zk+docker建構PaaS平台

然後填寫建立容器的配置資訊,如下圖,可以點選"New Application"建立頁面右上角的"JSON Mode"模式,将上面建立nginx容器的json檔案複制到這裡。

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

剩下以上紅框中的配置選項暫時先不配置,待以後測試。

Mesos+Marathon+zk+docker建構PaaS平台

4)删除marathon建立的docker執行個體。如下圖,點選"Destory"即可删除

Marathon還可以對App應用實作手動擴縮的功能,選擇"Scale Application"進行快速擴容。如下圖,對上面已建立的tomcat應用容器進行擴充到2個Task(注意:這裡有2個slave節點,那麼擴充的Task執行個體最好是2個,即2個Instances;如果擴充多個Task,會發現多餘的建立失敗,這時候可以點選"Configuration"修改,修改成2個)。

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

點選下面的日志"stderr"和"stdout"就會下載下傳到本地。

Mesos+Marathon+zk+docker建構PaaS平台

也可以到mesos頁面檢視或下載下傳。點選下面mesos頁面對應容器任務後面的"Sandbox"

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

具體配置可以參考marathon官方文檔:https://mesosphere.github.io/marathon/docs/persistent-volumes.html裡面有關于json檔案的配置

在marathon界面裡建立應用,可以使用volumes,即映射容器目錄到主控端上,JSON檔案内容如下:

"id": "nginx-1",

"cmd": null,

"cpus": 0.5,

"mem": 32,

"disk": 2048,

"image": "docker.io/nginx",

"containerPort": 80,

"protocol": "tcp",

"name": null,

"labels": null

},

"type": "DOCKER",

"volumes": [

"containerPath": "/usr/share/nginx/html",

"hostPath": "/opt/web/www",

"mode": "RW"

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

# mkdir -p /opt/web/www //如上圖在192.168.8.135(mesos-slave2)節點上建立使用的卷目錄(volumes,即映射的主控端目錄)

# echo "test" &gt; /opt/web/www/index.html //映射的主控端目錄下建立測試檔案

Mesos+Marathon+zk+docker建構PaaS平台

注意事項:

1)映射到主控端的目錄/opt/web/www要在每個slave節點機器上都要建立,并且裡面的檔案要在每個slave節點機上都有,因為容器重新開機後會在各個slave節點之間随機漂移。

2)上面映射的是nginx容器應用的站點目錄,預設建立後,/usr/share/nginx/html是空的(/opt/web/www目錄也是空的),是以容器預設通路會出現403報錯。隻需在slave節點的/opt/web/www目錄下編寫html檔案(如index.html)即可通路。

3)marathon裡建立好的容器應用,你可以在對應的slave機器上登陸容器内修改,但是這個容器應用一旦在marathon界面裡restart,那麼你之前的修改就沒有了。因為重新開機應用,就是再次使用初始鏡像進行建構了。

4)可以自己制作應用鏡像,在鏡像裡設定好應用的配置檔案;或者将自己建立的容器送出為新的鏡像。然後在marathon界面裡根據自己定義的鏡像建立應用。

預設情況下,marathon建立的應用通路端口是随機配置設定的,因為hostPort預設配置的是0,具體看下面說明:

marathon建立應用後,會涉及到三個端口:containerPort:、hostPort、servicePort,其中:

1)containerPort:用來指定容器内部的一個端口。當使用BRIDGE或USER網絡模式連接配接Docker容器時,必須将這個屬性設定為port mapping的一部分。

2)hostPort:用來指定綁定到主機上的一個端口。當使用BRIDGE或USER網絡模式,你可以指定一個port mapping将一個主機端口映射到容器端口。在HOST網絡模式下,預設的請求端口就是主機的端口。

請注意,主機端口隻可以通過環境變量提供給一個任務。

3)servicePort:當您在Marathon上(不管是通過REST API或界面)建立一個新的應用程式,你可以指定一個或多個服務端口給它。

可以指定所有有效的端口号為服務端口,也可以用0表示Marathon應該自動配置設定的可用服務端口給應用程式使用。如果你選擇自己的服務端口,你必須自己確定,這個端口在所有應用程式中是唯一的。

portMapping:在Docker BRIDGE模式下,在容器外部可被通路到的端口都需要做端口映射。端口映射是一個包含host port, container port, service port和協定的元組。可以為Marathon應用指定多個端口映射; 未指定hostPort,則其預設值為0(意味着Marathon将随機配置設定一個)。在Docker USER模式下,hostPort的語義為稍有點變化:USER模式不需要指定hostPort,如果未指定Marathon不會自動配置設定一個随機的。這允許在USER網絡模式下部署容器,包括containerPort和發現資訊,但不暴露主機網絡上的這些端口(意味着将不消耗主機端口資源)。

marathon建立應用的網絡模式介紹:

1)BRIDGE網絡模式:指定Docker應用程式使用BRIDGE網絡模式。在這種模式下,容器端口(容器内部的端口)被映射到主機端口(主控端上的端口)。在這種模式下,應用程式被綁定到容器内的指定端口,容器的端口被綁定到主控端上的指定端口。

2)USER網絡模式:指定Docker應用程式使用USER網絡模式。在這種模式下,容器端口(容器内部的端口)被映射到主機端口(主控端上的端口)。在這種模式下,應用程式被綁定到容器内的指定端口,容器的端口被綁定到主控端上的指定端口。在與“使用者自定義”Docker網絡內建時,USER網絡模式将會非常有用。在Mesos世界,這種網絡通常是通過使用與Mesos CNI網絡隔離的 CNI 插件通路。

3)HOST網絡模式:該種模式在Marathon應用為非容器化而其它應用為容器化的情況下使用。在這種模式下,應用程式直接綁定到主控端上的一個或多個端口。

如下JSON檔案内容,注意一下:如果hostport端口指定了,那麼serviceport端口也要指定(最好使用大端口),否則會導緻應用容器建立失敗。

"id":"nginx-2",

"cpus":0.2,

"mem":32.0,

{"containerPort": 80, "hostPort": 31030,"servicePort": 33180, "protocol": "tcp" }

在marathon界面裡建立應用,将上面的JSON檔案内容複制到"JSON Mode"模式下。建構成功後,就會發現該應用容器的通路端口就是上面自己定義的31030端口了(如下)

Mesos+Marathon+zk+docker建構PaaS平台

在marathon中,應用是一個完整的概念。每個應用是一個典型的長運作的服務,這個服務有很多執行個體,并且是運作在多個slave節點機上。下面通過一個小示例說明下:

一個内嵌的shell腳步:

如下通過内嵌的shell腳步,編寫一個簡單的app,即:

列印Hello world到slave節點的/mnt/test檔案中,然後sleep 5秒,周而複始。可以使用下面的應用定義檔案(json格式)來描述應用(注意:cmd是要執行的指令。它的值會以/bin/sh -c ${cmd}的方式執行。):

    "id": "basic-0",

    "cmd": "while [ true ] ; do echo 'Hello world' &gt;&gt; /mnt/test ; sleep 5 ; done",

    "cpus": 0.1,

    "mem": 10.0,

    "instances": 1

在marathon界面裡添加應用,采用"JSON Mode "模式,如下:

Mesos+Marathon+zk+docker建構PaaS平台

不采用"JSON Mode"模式,即将上面的json檔案内容粘貼進去後,去掉右上方的"JSON Mode"模式,也就是隻配置"General"選向,其他選項都不配置。注意:marathon裡的應用是一個長運作服務,是以shell腳本裡要配置長運作動作。

Mesos+Marathon+zk+docker建構PaaS平台

然後到192.168.8.135這台slave節點機上檢查,發現每隔5秒鐘,就會輸出"hello world"到/mnt/test檔案中。如果這台節點機出現故障,就會輸出到其他節點機上。

# tail -f /mnt/test

Hello world

***************當你發現自己的才華撐不起野心時,就請安靜下來學習吧!**************

下圖是chronos任務排程系統的基本結構圖:

Mesos+Marathon+zk+docker建構PaaS平台

整體上來看,該系統由業務隊列、業務排程器、Chronos和Mesos組成。每個組成部分的說明如下:

業務隊列:實際存放任務的隊列,隊列中的任務可以是按照優先級排序,也可以是FIFO. 多個業務隊清單示不同的業務,或者同一業務的不同隊列。

業務排程器:根據一定的排程算法從多個業務隊列中選擇任務來排程。業務排程器接受Chronos的資源彙報,然後給這些資源配置設定任務。

Chronos:向業務排程器彙報剩餘資源,接受業務排程器送出的任務然後在Mesos叢集上面運作。

Mesos:運作各個Docker容器的載體。每個任務都在Docker容器中執行。

有一點需要解釋的是,在這個任務排程系統中,存在多個排程器:

Mesos中的排程器:一種通用的叢集資源配置設定算法,也就是DRF

Chronos中的排程器:在我們這個場景中,不需要定時排程任務。我們隻需使用Chronos的Rest API送出一個Docker任務就可以了,這個Docker任務然後由Chronos排程到Mesos叢集上面運作。為什麼不繞過Chronos直接送出任務到Mesos呢?Mesos本身是個兩級排程架構,如果繞過Chronos,那麼業務排程器就需要實作Mesos的上級排程接口,增加了複雜性。

業務排程器:這就是和業務聯系最緊密的地方了,此處必須考慮各種業務特性,比如各個業務隊列的任務總量、到達速率、優先級等等。

系統的核心在于業務排程器。經過調研各種排程算法,覺得YARN資源管理系統中的容量排程(Capacity Scheduler)适合多業務多隊列的場景。

以兩級隊列為例來說明容量排程算法。下圖是Chronos資源的容量配置示例:

Mesos+Marathon+zk+docker建構PaaS平台

在該示意圖中,Chronos資源容量的20%配置設定給了業務1,80%配置設定給了業務2. 接着,20%容量中的40%配置設定給了業務隊列11,60%配置設定給了業務隊列12. 業務1和業務2是業務層次的隊列,業務隊列11、業務隊列12和業務隊列21是具體業務下的子隊列。

1、master節點上安裝配置chronos

拉取docker官方chronos鏡像

# docker pull mesosphere/chronos

# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

docker.io/mesosphere/chronos latest ec8accd8eb53 15 months ago 511 MB

# docker run -itd --net=host -e PORT0=18080 -e PORT1=8081 docker.io/mesosphere/chronos:latest --zk_hosts zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181 --master zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/mesos

# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

a6f9ecd25d38 docker.io/mesosphere/chronos:latest "/chronos/bin/star..." 2 minutes ago Up 2 minutes gallant_wescoff

2、登入chronos的web管理頁面

http://192.168.8.131:18080

Mesos+Marathon+zk+docker建構PaaS平台

3、在Chronos頁面,點選“ADD JOB”建立任務

注意:時間是UTC時間

Mesos+Marathon+zk+docker建構PaaS平台

Name: 作業名稱

Command: 實際需要執行的指令

Schedule: 作業的排程規則,遵循ISO8601規範。由三部分組成,通過”/“符号分割。例如”R10/2012-10-01T05:52:00Z/PT2S”的三部分内容如下:

1&gt; 重複執行作業務次數,如果隻有一個R,則代表無限次執行。

2&gt; 開始啟動作業的時間,如果為空,則表示立即執行,其遵循ISO8601規範。

3&gt; 執行頻率(即間隔多長時間執行一次),其定義方式如下:

P10M=10 months

PT10M=10 minutes

P1Y12M12D=1 years plus 12 months plus 12 days

P12DT12M=12 days plus 12 minutes

P1Y2M3DT4H5M6S=P(eriod) 1Y(ear) 2M(onth) 3D(ay) T(ime) 4H(our) 5M(inute) 6S(econd)

其中,P是必選字段,T是可選字段,用來區分M(inute)和M(onth)。

ScheduleTimeZone: 用來設定作業排程的時區。

Epsilon: 指因某些原因Chronos丢失了運作作業的下一次時間時,采用的固定運作周期。

Owner: 作業責任人的郵件位址。

Async: 作業是否在背景運作。

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

chronos任務如果正常排程并執行的話,在mesos的web頁面上的“Active Tasks”下會有任務執行相關的資訊,如下圖:

Mesos+Marathon+zk+docker建構PaaS平台

也可以在Chronos的任務頁面,點選「Run」強制執行。

Mesos+Marathon+zk+docker建構PaaS平台

4、測試通過Chronos執行Docker任務

啟動Docker,抓取nginx鏡像,啟動chronos-nginx容器

A、建立json檔案

# vi chronos-test.json

"network": "HOST"

"schedule": "R/2018-05-30T14:00:00.000Z/PT24H",

"name": "chronos-nginx",

"cpus": "0.3",

"mem": "32",

"uris": [],

"command": "/usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf"

network": "BRIDGE",因為Docker預設的網絡模式是橋接,不指定預設也是BRIDGE,此處指定為“HOST”。

B、通過BASH調用chronos的RestfulAPI排程接口運作并啟動chronos-nginx容器

# curl -L -H 'Content-Type: application/json' -X POST -d @/root/chronos-test.json http://192.168.8.131:18080/v1/scheduler/iso8601

在chronos的web管理界面上檢視chronos-nginx容器運作的狀态如下圖:

Mesos+Marathon+zk+docker建構PaaS平台

在Mesos頁面确認任務的詳細資訊,如下圖:

Mesos+Marathon+zk+docker建構PaaS平台

在節點上确認容器啟動,如下圖:

db3165da2284 docker.io/nginx "/bin/sh -c '/usr/..." 9 minutes ago Up 9 minutes 80/tcp mesos-97cce9bb-a884-454e-aed7-dea10d68737e

5、确認nginx網頁可以通路

Mesos+Marathon+zk+docker建構PaaS平台

consul的架構圖如下所示:

Mesos+Marathon+zk+docker建構PaaS平台

啟動consul後預設會監聽5個端口:

8300: replication、leader farwarding的端口

8301: lan gossip的端口

8302: wan gossip的端口

8500: web ui界面的端口

8600: 使用dns協定檢視節點資訊的端口

叢集角色:

上圖是官方的consul cluster的架構,Consul Cluster有Server和Client兩種角色。不管是Server還是Client,統稱為Agent,Consul Client是相對無狀态的,隻負責轉發RPC到Server,資源開銷很少。Server是一個有一組擴充功能的代理,這些功能包括參與Raft選舉,維護叢集狀态,響應RPC查詢,與其他資料中心互動WAN gossip和轉發查詢給leader或者遠端資料中心。

在每個資料中心,client和server是混合的。一般建議有3-5台server。這是基于有故障情況下的可用性和性能之間的權衡結果,因為越多的機器加入達成共識越慢,Server之間會選舉出一個leader。然而,并不限制client的數量,它們可以很容易的擴充到數千或者數萬台。

consul更像一個“全棧”解決方案,内置了服務注冊與發現,具有健康檢查、Key/Value存儲、多資料中心的功能。個人比較偏愛他有三點:

1、開箱即用,友善運維:安裝包僅包含一個可執行檔案,友善部署,無需其他依賴,與Docker等輕量級容器可無縫配合;

2、自帶ui界面,可以通過web界面直接看到注冊的服務,更新K/V;

3、采用GOSSIP協定進行叢集内成員的管理和消息的傳播,使用和etcd一樣的raft協定保證資料的一緻性。

Consul提供的四個關鍵特性:

1、服務發現:提供HTTP和DNS兩種發現方式。

2、健康監測: 支援多種方式,HTTP、TCP、Docker、Shell腳本定制化監控。

3、K/V存儲: Key、Value的存儲方式。

4、多資料中心:Consul支援多資料中心。

當然Consul還有很多錦上添花的特性,比如:可視化Web界面、配置模闆“consul-template”等。

Mesos+Marathon+zk+docker建構PaaS平台

通過registrator的服務自動注冊,配合consul服務,在docker容器中能夠自動識别服務的域名,以便在mesos+marathon中部署docker執行個體能夠通過域名互通,也就是consul在docker容器中的自動發現。如果是線上consul server最少3台做叢集,consul client是每個mesos-slave上跑一個,mesos-master也最少3台叢集,marathon和zookeeper都應該是叢集的模式。

consul經常拿來和etcd、zookeeper來對比,他有和etcd一樣的服務發現、服務注冊功能,也有和etcd、zookeeper一樣的配置存儲功能,詳細的比對這裡就不描述了。下面是consul叢集的服務注冊,服務發現,健康檢查,和模闆使用。

registrator服務注冊         | | consul服務端                     | |nginx代理                  | |應用服務

做健康檢查                      | |接收用戶端發送的健康         | | 如果nginx的模闆       | |

确定本地服務是否正常     | |檢查資訊做服務的注冊         | |更改,則                    | |

通報給consul服務端        | |如果用戶端有變動,則         | |nginx reload              | |

                                       | |更新代理的配置                   | |                                  | |

1、consul叢集服務安裝配置

# unzip consul_1.1.0_linux_amd64.zip -d /usr/local

# ln -s /usr/local/consul /usr/local/bin/consul

# mkdir -p /etc/consul.d //在每個consul節點上配置

command方式建立consul叢集:

# consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=192.168.8.131 -config-dir=/etc/consul.d -client 0.0.0.0

==&gt; Multiple private IPv4 addresses found. Please configure one with 'bind' and/or 'advertise'.

報錯:Multiple private IPv4 addresses found. Please configure one with 'bind' and/or 'advertise'.

意思是:找到多個私有IPv4位址。請用“bind”綁定配置一個,就可以解決,根據提示.

[root@mesos-master1 ~]# nohup consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=mesos-master1 -config-dir=/etc/consul.d -bind=192.168.8.131 -client 0.0.0.0 -ui &amp;

bootstrap_expect &gt; 0: expecting 3 servers

==&gt; Starting Consul agent...

==&gt; Consul agent running!

Version: 'v1.1.0'

Node ID: 'cc8eebd0-6f84-6eee-f8cc-92ae7bf44494'

Node name: 'mesos-master1'

。。。。。。

2018/06/03 15:00:21 [INFO] agent: Started DNS server 0.0.0.0:8600 (tcp)

2018/06/03 15:00:21 [INFO] agent: Started HTTP server on [::]:8500 (tcp)

2018/06/03 15:00:21 [INFO] agent: started state syncer

2018/06/03 15:00:28 [ERR] agent: failed to sync remote state: No cluster leader

2018/06/03 15:00:30 [WARN] raft: no known peers, aborting election

2018/06/03 15:00:51 [ERR] agent: Coordinate update error: No cluster leader

2018/06/03 15:00:54 [ERR] agent: failed to sync remote state: No cluster leader

報錯:No cluster leader,是因為其它兩台consul的server端還沒有啟動!

啟動參數說明:

agent: 運作一個consul代理。

-server: 切換代理到伺服器模式。

-bootstrap: 當consulserver-node1節點啟動之後,等待另外兩個節點的加入,3個節點聚齊後,之後才開始選舉leader。

-ui: 啟用内置的靜态web UI伺服器。

-data-dir: 路徑到資料目錄存儲代理狀态。

-bind: 設定叢集通信的綁定位址。

-client: 設定用于綁定用戶端通路的位址。這包括RPC、DNS、HTTP和HTTPS(如果配置)。

-node: 此節點的名稱。 在叢集中必須是唯一的,如果你運作第2台consul,可以寫server02、server03等。

-advertise:如果要讓節點在WAN網絡中被發現,就要配置這個參數,暴露出外網ip

[root@mesos-master2 ~]# nohup consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=mesos-master2 -config-dir=/etc/consul.d -bind=192.168.8.132 -client 0.0.0.0 -join 192.168.8.131 &amp; //注意:此處的-join啟動選項,後面跟mesos-master1的IP位址,或者也可以在mesos-master1上執行consul join 192.168.8.132/133,否則同樣還是會報以上錯誤!

[root@mesos-master3 ~]# nohup consul agent -server -bootstrap-expect=3 -data-dir=/tmp/consul -node=mesos-master3 -config-dir=/etc/consul.d -bind=192.168.8.133 -client 0.0.0.0 -join 192.168.8.131 &amp;

很×××台mesos-master上的consul都會列印:

consul: New leader elected: mesos-master1

證明此時leader已經選出,叢集可以正常工作。

[root@mesos-slave1 ~]# nohup consul agent -client 192.168.8.134 -data-dir=/tmp/consul -config-dir=/etc/consul.d -node=mesos-slave1 -bind=192.168.8.134 -join 192.168.8.131 &amp;

[root@mesos-slave2 ~]# nohup consul agent -client 192.168.8.135 -data-dir=/tmp/consul -config-dir=/etc/consul.d -node=mesos-slave2 -bind=192.168.8.135 -join 192.168.8.131 &amp;

[root@mesos-master1 ~]# consul info consul

叢集參數put/get測試:

[root@mesos-slave1 ~]# consul kv put key value

Success! Data written to: key

[root@mesos-master2 ~]# consul kv get key

value

5台機器擷取key的值均為value,如此可知key的值已經在叢集中同步。

[root@mesos-master1 ~]# consul members

Node Address Status Type Build Protocol DC Segment

mesos-master1 192.168.8.131:8301 alive server 1.1.0 2 dc &lt;all&gt;

mesos-master2 192.168.8.132:8301 alive server 1.1.0 2 dc &lt;all&gt;

mesos-master3 192.168.8.133:8301 alive server 1.1.0 2 dc &lt;all&gt;

mesos-slave1 192.168.8.134:8301 alive client 1.1.0 2 dc &lt;default&gt;

mesos-slave2 192.168.8.135:8301 alive client 1.1.0 2 dc &lt;default&gt;

[root@mesos-master1 ~]# consul operator raft list-peers

Node ID Address State Voter RaftProtocol

mesos-master1 f0522384-3554-61e7-57ce-607a583a179f 192.168.8.131:8300 leader true 3

mesos-master2 b5ffff40-f993-0f9e-7877-4e0bffdabb3d 192.168.8.132:8300 follower true 3

mesos-master3 fc42ff3f-617f-9524-090b-b8c5584b3cac 192.168.8.133:8300 follower true 3

可以看出叢集中mesos-master1是leader,mesos-master2和mesos-master3都是follower

[root@mesos-master1 ~]# consul info |grep leader

leader = false

leader_addr = 192.168.8.132:8300

[root@mesos-master1 ~]# consul catalog services

consul

mesos

配置檔案方式建立consul叢集:

在其中一個mesos master節點上配置bootstrap配置,該節點就是consul叢集中的bootstrap節點(192.168.8.131)。

# cat &gt; /etc/consul.d/bootstrap/config.json &lt;&lt;EOF

"bootstrap": true,

"server": true,

"datacenter": "dc",

"data_dir": "/var/consul",

"log_level": "INFO",

"enable_syslog": true,

"disable_update_check": true,

"ui": true

EOF

在其他的mesos master 節點上配置server配置,這些節點就是consul叢集中的server節點(192.168.8.132/192.168.8.133)。

# cat &gt; /etc/consul.d/server/config.json &lt;&lt;EOF

"bootstrap": false,

"start_join": ["192.168.8.131", "192.168.8.133"],

注意: start_join: 記錄了其他consul server節點的IP。

在所有的mesos agent 節點上配置client配置,這些節點也就是consul叢集中的client節點

# cat &gt; /etc/consul.d/client/config.json &lt;&lt;EOF

"server": false,

"start_join": ["192.168.8.131", "192.168.8.132", "192.168.8.133"],

注意:start_join: 記錄了所有的consul server的IP。

啟動Consul叢集:

在consul bootstrap節點啟動:

在所有consul server節點啟動:

在所有consul client節點啟動:

注意: self_ip是本機的IP。

檢查consul叢集狀态:

在consul叢集中任意一個節點執行

2、consul的DNS服務發現

consul支援dns的服務注冊:

3、consul的常用http api

對consul來說一個重要的接口就是RESTful HTTP API,http api可用于操作nodes, services, checks, configuration等等的CRUD(create, read, update and delete),詳見Consul Http Api,下面是幾個例子?說明

http api可以通過連結請求:

檢視目前consul節點的服務

# curl mesos-master1:8500/v1/agent/checks |python -m json.tool

檢視目前consul叢集的leader

# curl mesos-master1:8500/v1/status/leader

檢視目前節點的資訊

# curl mesos-master1:8500/v1/operator/raft/configuration |python -m json.tool

檢視mesos-slave1節點的健康檢查資訊

# curl mesos-master1:8500/v1/health/node/mesos-slave1 |python -m json.tool

檢視webserver服務的資訊

# curl -s http://mesos-master1:8500/v1/catalog/service/webserver | python -m json.tool

# 叢集server成員

#curl 127.0.0.1:8500/v1/status/peers

# 叢集Raft leader

#curl 127.0.0.1:8500/v1/status/leader

# 注冊的所有服務

#curl 127.0.0.1:8500/v1/catalog/services

# 服務資訊

#curl 127.0.0.1:8500/v1/catalog/services/nginx

# 叢集節點詳細資訊

#curl 127.0.0.1:8500/v1/catalog/nodes

4、registrator容器實作服務自動注冊

服務發現與注冊

1. 具體流程

服務注冊中心:作為整個架構中的核心,要支援分布式、持久化存儲,注冊資訊變動實時通知消費者。

服務提供者:服務以容器化方式部署(實作服務端口的動态生成),可以通過 的方式來管理。通過 檢測到 程序資訊以完成服務的自動注冊。

服務消費者:要使用服務提供者提供的服務,和服務提供者往往是動态互相轉位置的。

一個較為完整的服務注冊與發現流程如下:

Mesos+Marathon+zk+docker建構PaaS平台

注冊服務:服務提供者到注冊中心注冊;

訂閱服務:服務消費者到注冊中心訂閱服務資訊,對其進行監聽;

緩存服務清單:本地緩存服務清單,減少與注冊中心的網絡通信;

調用服務:先查找本地緩存,找不到再去注冊中心拉取服務位址,然後發送服務請求;

變更通知:服務節點變動時 (新增、删除等),注冊中心将通知監聽節點,更新服務資訊。

2. 相關元件

一個服務發現系統主要由三部分組成:

注冊器(registrator):根據服務運作狀态,注冊/登出服務。主要要解決的問題是,何時發起注冊/登出動作。

系統資料庫(registry):存儲服務資訊。常見的解決方案有zookeeper、etcd、cousul等。

發現機制(discovery):從系統資料庫讀取服務資訊,給使用者封裝通路接口。

通過Registrator收集需要注冊到Consul作為Nginx後端伺服器資訊然後注冊到Consul key/value.Consul-template去Consul key/value中讀取資訊,然後自動修改Nginx配置檔案并平滑重新開機Nginx,不需要修改nginx.conf。

分别在mesos-slave1 和mesos-slave2 上都建立:

利用chronos的任務排程下載下傳registrator:

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

利用chronos的任務排程在所有的mesos-slave上運作registrator:

Mesos+Marathon+zk+docker建構PaaS平台

Command: docker run -d --name registrator --network=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest --ip 192.168.8.134 consul://192.168.8.131:8500

參數說明:

--network:把運作的docker容器設定為host網絡模式;

-v /var/run/docker.sock:把主控端的Docker守護程序(Docker daemon)預設監聽的Unix域套接字挂載到容器中;

--ip : 剛才把network指定了host模式,是以我們指定下IP為主控端的IP;

consul: 最後這個選項是配置consul伺服器的IP和端口。

服務注冊前:

Mesos+Marathon+zk+docker建構PaaS平台

通過marathon啟動tomcat服務:

[root@mesos-master1 ~]# curl -X POST http://192.168.8.131:8080/v2/apps -d @/root/tomcat.json -H "Content-type: application/json"

{"id":"/tomcat-1","backoffFactor":1.15,"backoffSeconds":1,"constraints":[["hostname","CLUSTER",""]],"container":{"type":"DOCKER","docker":{"forcePullImage":false,"image":"docker.io/tomcat","parameters":[],"privileged":false},"volumes":[],"portMappings":[{"containerPort":8080,"hostPort":0,"labels":{},"protocol":"tcp","servicePort":0}]},"cpus":0.5,"disk":0,"executor":"","instances":1,"labels":{},"maxLaunchDelaySeconds":3600,"mem":64,"gpus":0,"networks":[{"mode":"container/bridge"}],"requirePorts":false,"upgradeStrategy":{"maximumOverCapacity":1,"minimumHealthCapacity":1},"version":"2018-06-10T08:34:47.600Z","killSelection":"YOUNGEST_FIRST","unreachableStrategy":{"inactiveAfterSeconds":0,"expungeAfterSeconds":0},"tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"346444ac-978b-42d6-8975-6b01fd6869ab"}],"tasks":[]}

Mesos+Marathon+zk+docker建構PaaS平台

服務注冊後:

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

從上圖可以看出,剛才建立的marathon應用tomcat容器服務已經注冊到了 consul中。

[root@mesos-master1 ~]# curl 127.0.0.1:8500/v1/catalog/services

{"consul":[],"mesos":["master","leader"],"tomcat":[]}

服務被調整後,負載均衡要想動态重新配置設定負載,就需要修改相應的配置檔案,consul-template就是解決這個問題的應用,通過監聽consul的注冊資訊,來自動完成負載均衡相應的配置更新。

安裝nginx,此處略過。。。

安裝consul-template非常簡單,下載下傳二進制包即可使用。

1、下載下傳consul-template

下載下傳位址:https://releases.hashicorp.com/consul-template/0.19.4/consul-template_0.19.4_linux_amd64.zip

# wget https://releases.hashicorp.com/consul-template/0.19.4/consul-template_0.19.4_linux_amd64.zip

2、解壓并安裝到/usr/bin目錄

# unzip consul-template_0.19.4_linux_amd64.zip

# mv consul-template /usr/bin/

# consul-template -v

consul-template v0.19.4 (68b1da2)

3、建立nginx模闆

# cd /usr/local/nginx

# mkdir consul

# cd consul/

# vi nginx.ctmpl

upstream http_backend {

{{range service "nginx"}}

server {{ .Address }}:{{ .Port }} max_fails=3 fail_timeout=90;

{{ end }}

server {

listen 8085;

server_name localhost;

location / {

proxy_pass http://http_backend;

4、修改nginx.conf

# grep "consul" nginx.conf

include /usr/local/nginx/consul/*.conf; //添加這一行在http子產品

# /usr/local/nginx/sbin/nginx //啟動nginx服務

5、啟動consul-template

# ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

# cd /usr/local/nginx/consul/

[root@mesos-master1 ~]# ps -ef | grep consul-template

root 41543 16705 0 19:33 pts/2 00:00:00 consul-template --consul-addr 192.168.8.131:8500 --template ./nginx.ctmpl:vhost.conf --log-level=info

root 41758 38089 0 19:35 pts/1 00:00:00 grep --color=auto consul-template

[root@mesos-master1 ~]# ll /usr/local/nginx/consul/

total 8

-rw-r--r-- 1 root root 333 Jun 10 18:26 nginx.ctmpl

-rw-r--r-- 1 root root 255 Jun 10 19:33 vhost.conf

在consul目錄下,是不是發現多了一個檔案vhost.conf,就是剛才啟consul-template時生成的。檢視下vhost.conf的内容,目前upstraem的server配置為空,還沒有docker主機加入進來:

[root@mesos-master1 ~]# cat /usr/local/nginx/consul/vhost.conf

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

{"id":"/nginx-1","backoffFactor":1.15,"backoffSeconds":1,"container":{"type":"DOCKER","docker":{"forcePullImage":false,"image":"docker.io/nginx","parameters":[],"privileged":false},"volumes":[{"containerPath":"/usr/share/nginx/html","hostPath":"/opt/web/www","mode":"RW"}],"portMappings":[{"containerPort":80,"hostPort":0,"labels":{},"protocol":"tcp","servicePort":0}]},"cpus":0.5,"disk":2048,"executor":"","instances":1,"labels":{},"maxLaunchDelaySeconds":3600,"mem":32,"gpus":0,"networks":[{"mode":"container/bridge"}],"requirePorts":false,"upgradeStrategy":{"maximumOverCapacity":1,"minimumHealthCapacity":1},"version":"2018-06-18T13:12:27.037Z","killSelection":"YOUNGEST_FIRST","unreachableStrategy":{"inactiveAfterSeconds":0,"expungeAfterSeconds":0},"tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"0b2969ac-a65d-4ff9-b7b9-f2c5cc29312f"}],"tasks":[]}

Mesos+Marathon+zk+docker建構PaaS平台

server 192.168.8.134:31581 max_fails=3 fail_timeout=90;

server 192.168.8.134:31818 max_fails=3 fail_timeout=90;

server 192.168.8.135:31814 max_fails=3 fail_timeout=90;

Mesos+Marathon+zk+docker建構PaaS平台

[root@mesos-slave1 ~]# echo "mesos-slave1" &gt;/opt/web/www/index.html

[root@mesos-slave2 ~]# echo "mesos-slave2" &gt;/opt/web/www/index.html

可以看到,在通過marathon建立了3個nginx的容器執行個體後,nginx的虛拟主機配置檔案已經被consul-template動态修改。然後通路一下nginx伺服器的IP位址,http://192.168.8.131:8085,從下圖可以看出是可以通路的:

Mesos+Marathon+zk+docker建構PaaS平台
Mesos+Marathon+zk+docker建構PaaS平台

可以看到nginx的8085負載均衡是可以正常輪詢的!!!

繼續閱讀