參考文檔:
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架構:
架構圖可以看出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運作流程:
流程步驟:
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叢集各節點狀态:
zk各節點端口:
由此可見,叢集已經正常運作。
用戶端可以通過nc或telnet連接配接ZooKeeper Server送出指令。
ZooKeeper Client 簡單操作:
9個基本操作指令:
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" >/etc/mesos-master/hostname
# echo "192.168.8.131" >/etc/mesos-master/ip
# echo "192.168.8.131" >/etc/marathon/conf/hostname
# echo "192.168.8.131" >/etc/marathon/conf/ip
mesos-master2:
# echo "192.168.8.132" >/etc/mesos-master/hostname
# echo "192.168.8.132" >/etc/mesos-master/ip
# echo "192.168.8.132" >/etc/marathon/conf/hostname
# echo "192.168.8.132" >/etc/marathon/conf/ip
mesos-master3:
# echo "192.168.8.133" >/etc/mesos-master/hostname
# echo "192.168.8.133" >/etc/mesos-master/ip
# echo "192.168.8.133" >/etc/marathon/conf/hostname
# echo "192.168.8.133" >/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 & >>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" >/etc/mesos-slave/containerizers
# echo "192.168.8.134">/etc/mesos-slave/ip
# echo "192.168.8.134" >/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/#/
1. 從首頁可以看到mesos-agent:activated狀态的agent有2個;
2. mesos-master管理的2個agent的資源已彙總。
1. 在mesos架構中,marathon架構已經被識别,marathon的leader是:mesos-master2;
2. 雖然mesos-master與marathon的leader相同,但兩者的leader是zookeeper獨立選舉的,并沒有直接關系,是可以不同的。
1.在Agnets中能看到2個agent;
2.同時能看到每個agent的資源;
點選上面2個slave中的任意一個,也能看出它的master是mesos-master2
通路marathon的管理頁面,http://master_ip:8080
這裡的master_ip就是在上面通路mesos頁面Frameworks中識别出的marathon,即192.168.8.132:8080
或者直接點選mesos通路頁面Frameworks中識别出的marathon也可以。
浏覽器通路:http://192.168.8.132:5050/master/state
比如建立一個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"模式裡,然後直接點選建立。
登陸marathon界面檢視是在哪一台slave機器上建立的docker容器執行個體(這個是随機的),點選"running"。(如果容器建立失敗,即非"running"狀态,可以嘗試重新開機slave節點的docker服務)
然後登陸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上建立應用。
如以上截圖中可知,這個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"裡有容器建立任務時,才說明此容器真正建立成功了)
3)圖形化建立并運作容器
然後填寫建立容器的配置資訊,如下圖,可以點選"New Application"建立頁面右上角的"JSON Mode"模式,将上面建立nginx容器的json檔案複制到這裡。
剩下以上紅框中的配置選項暫時先不配置,待以後測試。
4)删除marathon建立的docker執行個體。如下圖,點選"Destory"即可删除
Marathon還可以對App應用實作手動擴縮的功能,選擇"Scale Application"進行快速擴容。如下圖,對上面已建立的tomcat應用容器進行擴充到2個Task(注意:這裡有2個slave節點,那麼擴充的Task執行個體最好是2個,即2個Instances;如果擴充多個Task,會發現多餘的建立失敗,這時候可以點選"Configuration"修改,修改成2個)。
點選下面的日志"stderr"和"stdout"就會下載下傳到本地。
也可以到mesos頁面檢視或下載下傳。點選下面mesos頁面對應容器任務後面的"Sandbox"
具體配置可以參考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"
# mkdir -p /opt/web/www //如上圖在192.168.8.135(mesos-slave2)節點上建立使用的卷目錄(volumes,即映射的主控端目錄)
# echo "test" > /opt/web/www/index.html //映射的主控端目錄下建立測試檔案
注意事項:
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端口了(如下)
在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' >> /mnt/test ; sleep 5 ; done",
"cpus": 0.1,
"mem": 10.0,
"instances": 1
在marathon界面裡添加應用,采用"JSON Mode "模式,如下:
不采用"JSON Mode"模式,即将上面的json檔案内容粘貼進去後,去掉右上方的"JSON Mode"模式,也就是隻配置"General"選向,其他選項都不配置。注意:marathon裡的應用是一個長運作服務,是以shell腳本裡要配置長運作動作。
然後到192.168.8.135這台slave節點機上檢查,發現每隔5秒鐘,就會輸出"hello world"到/mnt/test檔案中。如果這台節點機出現故障,就會輸出到其他節點機上。
# tail -f /mnt/test
Hello world
***************當你發現自己的才華撐不起野心時,就請安靜下來學習吧!**************
下圖是chronos任務排程系統的基本結構圖:
整體上來看,該系統由業務隊列、業務排程器、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資源的容量配置示例:
在該示意圖中,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
3、在Chronos頁面,點選“ADD JOB”建立任務
注意:時間是UTC時間
Name: 作業名稱
Command: 實際需要執行的指令
Schedule: 作業的排程規則,遵循ISO8601規範。由三部分組成,通過”/“符号分割。例如”R10/2012-10-01T05:52:00Z/PT2S”的三部分内容如下:
1> 重複執行作業務次數,如果隻有一個R,則代表無限次執行。
2> 開始啟動作業的時間,如果為空,則表示立即執行,其遵循ISO8601規範。
3> 執行頻率(即間隔多長時間執行一次),其定義方式如下:
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: 作業是否在背景運作。
chronos任務如果正常排程并執行的話,在mesos的web頁面上的“Active Tasks”下會有任務執行相關的資訊,如下圖:
也可以在Chronos的任務頁面,點選「Run」強制執行。
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頁面确認任務的詳細資訊,如下圖:
在節點上确認容器啟動,如下圖:
db3165da2284 docker.io/nginx "/bin/sh -c '/usr/..." 9 minutes ago Up 9 minutes 80/tcp mesos-97cce9bb-a884-454e-aed7-dea10d68737e
5、确認nginx網頁可以通路
consul的架構圖如下所示:
啟動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”等。
通過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
==> 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 &
bootstrap_expect > 0: expecting 3 servers
==> Starting Consul agent...
==> 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 & //注意:此處的-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 &
很×××台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 &
[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 &
[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 <all>
mesos-master2 192.168.8.132:8301 alive server 1.1.0 2 dc <all>
mesos-master3 192.168.8.133:8301 alive server 1.1.0 2 dc <all>
mesos-slave1 192.168.8.134:8301 alive client 1.1.0 2 dc <default>
mesos-slave2 192.168.8.135:8301 alive client 1.1.0 2 dc <default>
[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 > /etc/consul.d/bootstrap/config.json <<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 > /etc/consul.d/server/config.json <<EOF
"bootstrap": false,
"start_join": ["192.168.8.131", "192.168.8.133"],
注意: start_join: 記錄了其他consul server節點的IP。
在所有的mesos agent 節點上配置client配置,這些節點也就是consul叢集中的client節點
# cat > /etc/consul.d/client/config.json <<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. 具體流程
服務注冊中心:作為整個架構中的核心,要支援分布式、持久化存儲,注冊資訊變動實時通知消費者。
服務提供者:服務以容器化方式部署(實作服務端口的動态生成),可以通過 的方式來管理。通過 檢測到 程序資訊以完成服務的自動注冊。
服務消費者:要使用服務提供者提供的服務,和服務提供者往往是動态互相轉位置的。
一個較為完整的服務注冊與發現流程如下:
注冊服務:服務提供者到注冊中心注冊;
訂閱服務:服務消費者到注冊中心訂閱服務資訊,對其進行監聽;
緩存服務清單:本地緩存服務清單,減少與注冊中心的網絡通信;
調用服務:先查找本地緩存,找不到再去注冊中心拉取服務位址,然後發送服務請求;
變更通知:服務節點變動時 (新增、删除等),注冊中心将通知監聽節點,更新服務資訊。
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:
利用chronos的任務排程在所有的mesos-slave上運作registrator:
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和端口。
服務注冊前:
通過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":[]}
服務注冊後:
從上圖可以看出,剛才建立的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":[]}
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;
[root@mesos-slave1 ~]# echo "mesos-slave1" >/opt/web/www/index.html
[root@mesos-slave2 ~]# echo "mesos-slave2" >/opt/web/www/index.html
可以看到,在通過marathon建立了3個nginx的容器執行個體後,nginx的虛拟主機配置檔案已經被consul-template動态修改。然後通路一下nginx伺服器的IP位址,http://192.168.8.131:8085,從下圖可以看出是可以通路的:
可以看到nginx的8085負載均衡是可以正常輪詢的!!!