參考文檔:html
mesosphere社區版:https://github.com/mesosphere/open-docsnode
mesosphere倉庫:https://github.com/mesosphere/open-docs/blob/master/downloads/mesos.mdpython
marathon: https://mesosphere.github.io/marathon/docs/mysql
chronos: https://mesos.github.io/chronos/docs/linux
consul:https://www.consul.io/ https://releases.hashicorp.com/consul/nginx
docker安裝:https://docs.docker.com/engine/installation/linux/docker-ce/centos/git
mesos 集羣資源管理框架(以集羣的形式出現,主決定資源的分配,從負責執行executor),分配資源,提供offer給framework,不負責調度資源,千言萬語都在這裏了mesos的設計結構。github
marathon 是mesos的framework,容器編排系統,保證長時間的運行任務,相似後臺執行或者supervisor。web
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運行流程:
流程步驟:
一、slave1報告給master他擁有4核cpu和4G剩餘內存,Marathon調用allocation政策模塊,告訴slave1計算框架1應該被提供可用的資源。
二、master給計算框架1發送一個在slave上可用的資源描述。
三、計算框架的調度器回覆給master運行在slave上兩個任務相關信息,任務1須要使用2個CPU,內存1G,任務2需使用1個CPU,2G內存。
四、最後,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 |
CentOS-7.5 |
mesos-master, marathon,zookeeper, consul-server, chronos |
mesos-master3 |
192.168.8.133 |
CentOS-7.5 |
mesos-master, marathon,zookeeper, consul-server, chronos |
mesos-slave1 |
192.168.8.134 |
CentOS-7.5 |
mesos-slave, docker, registrator |
mesos-slave2 |
192.168.8.135 |
CentOS-7.5 |
mesos-slave, docker, registrator |
軟件版本:
服務 |
版本 |
做用 |
zookeeper |
3.4.12 |
保持各master之間的通訊,選舉leader、HA |
mesos-master |
1.6.0 |
管理接入mesos的各個framework & slave,並將slave上的資源按照相應策略分配給framework |
mesos-slave |
1.6.0 |
任務執行節點 |
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 root@192.168.8.132:/usr/local/zk/conf/zoo.cfg
# scp -p /usr/local/zk/conf/zoo.cfg root@192.168.8.133:/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
# mkdir /usr/local/zk/logs -p
# echo "2" > /usr/local/zk/data/zk2/myid
# grep -Ev "#|^$" /usr/local/zk/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zk/data/zk2
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
# 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
# mkdir /usr/local/zk/logs -p
# echo "3" > /usr/local/zk/data/zk3/myid
# grep -Ev "#|^$" /usr/local/zk/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zk/data/zk3
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
啓動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 root@192.168.8.132:/etc/mesos/zk
# scp /etc/mesos/zk root@192.168.8.133:/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 root@192.168.8.132:/etc/mesos-master/quorum
# scp /etc/mesos-master/quorum root@192.168.8.133:/etc/mesos-master/quorum
#
主機名和ip要在hosts中寫入,最好不要使用localhost,不然會出現slave不能識別,以及marathon任務下發不正常等現象。
# 默認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
zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/mesos
# 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 root@192.168.8.132:/etc/marathon/conf/
# scp /etc/marathon/conf/master root@192.168.8.133:/etc/marathon/conf/
# scp /etc/marathon/conf/zk root@192.168.8.132:/etc/marathon/conf/
# scp /etc/marathon/conf/zk root@192.168.8.133:/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
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
_CAP_EFFECTIVE=0
_HOSTNAME=mesos-master1
SYSLOG_IDENTIFIER=marathon
_UID=998
_GID=996
_SYSTEMD_CGROUP=/system.slice/marathon.service
_SYSTEMD_UNIT=marathon.service
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
_STREAM_ID=bd3ee42018a94236baeab1e5f653171f
_PID=24962
經過上述日誌能夠看出,是找不到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
# vi /etc/mesos/zk
zk://192.168.8.131:2181,192.168.8.132:2181,192.168.8.133:2181/mesos
# 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
nginx-example:
{
"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"服務端口
}
}
}
# vi tomcat.json # tomcat
的docker鏡像要提早建立或下載
{
"id":"tomcat-1",
"cpus":0.5,
"mem":64,
"instances": 1,
"constraints": [["hostname", "CLUSTER",""]],
"container": {
"type":"DOCKER",
"docker": {
"image": "docker.io/tomcat",
"network": "BRIDGE",
"portMappings": [
{"containerPort": 8080, "hostPort": 0,"servicePort": 0, "protocol": "tcp" }
]
}
}
}
注意:json文件中的每一行內容的開頭和結尾必定不能有空格,但能夠有空行,不然手動經過curl的方式建立容器實例,會有各類各樣的報錯!!!
接着使用curl的方式調用,注意上面的tomcat.json
文件是在/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,
"instances": 1,
"container": {
"docker": {
"image": "docker.io/nginx",
"network": "BRIDGE",
"portMappings": [
{
"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,
"instances": 1,
"constraints": [["hostname", "CLUSTER",""]],
"container": {
"type":"DOCKER",
"docker": {
"image": "docker.io/nginx",
"network": "BRIDGE",
"portMappings": [
{"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
Hello world
Hello world
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是業務層次的隊列,業務隊列十一、業務隊列12和業務隊列21是具體業務下的子隊列。
拉取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
注意:時間是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」強制執行。
啓動Docker,抓取nginx鏡像,啓動chronos-nginx容器
A、建立json文件
# vi chronos-test.json
{
"container": {
"type": "DOCKER",
"image": "docker.io/nginx",
"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頁面確認任務的詳細信息,以下圖:
在節點上確認容器啓動,以下圖:
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db3165da2284 docker.io/nginx "/bin/sh -c '/usr/..." 9 minutes ago Up 9 minutes 80/tcp mesos-97cce9bb-a884-454e-aed7-dea10d68737e
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存儲、多數據中心的功能。我的比較偏心他有三點:
一、開箱即用,方便運維:安裝包僅包含一個可執行文件,方便部署,無需其餘依賴,與Docker等輕量級容器可無縫配合;
二、自帶ui界面,能夠經過web界面直接看到註冊的服務,更新K/V;
三、採用GOSSIP協議進行集羣內成員的管理和消息的傳播,使用和etcd同樣的raft協議保證數據的一致性。
Consul提供的四個關鍵特性:
一、服務發現:提供HTTP和DNS兩種發現方式。
二、健康監測: 支持多種方式,HTTP、TCP、Docker、Shell腳本定製化監控。
三、K/V存儲: Key、Value的存儲方式。
四、多數據中心: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 | |
| |更新代理的配置 | | | |
# 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,能夠寫server0二、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,
"server": true,
"datacenter": "dc",
"data_dir": "/var/consul",
"log_level": "INFO",
"enable_syslog": true,
"disable_update_check": true,
"start_join": ["192.168.8.131", "192.168.8.133"],
"ui": true
}
EOF
注意: start_join: 記錄了其餘consul server節點的IP。
在全部的mesos agent 節點上配置client配置,這些節點也就是consul集羣中的client節點
# cat > /etc/consul.d/client/config.json <<EOF
{
"server": false,
"datacenter": "dc",
"data_dir": "/var/consul",
"log_level": "INFO",
"enable_syslog": true,
"disable_update_check": true,
"start_join": ["192.168.8.131", "192.168.8.132", "192.168.8.133"],
"ui": true
}
EOF
注意:start_join: 記錄了全部的consul server的IP。
啓動Consul集羣:
在consul bootstrap節點啓動:
# consul agent -config-dir /etc/consul.d/bootstrap/ -bind=192.168.8.131 -client=0.0.0.0 >> /var/log/consul.log 2>&1 &
在全部consul server節點啓動:
# consul agent -config-dir /etc/consul.d/server/ -bind=192.168.8.132 -client=0.0.0.0 >> /var/log/consul.log 2>&1 &
在全部consul client節點啓動:
consul agent -config-dir /etc/consul.d/client/ -bind=192.168.8.134 -client=0.0.0.0 >> /var/log/consul.log 2>&1 &
注意: self_ip是本機的IP。
檢查consul集羣狀態:
在consul集羣中任意一個節點執行
consul支持dns的服務註冊:
# dig @127.0.0.1 8600 mesos-master1.node.consul +short
192.168.8.131
# dig @127.0.0.1 8600 mesos-master2.node.consul +short
192.168.8.132
# dig @127.0.0.1 8600 mesos-master3.node.consul +short
192.168.8.133
對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
服務發現與註冊
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/
# consul-template --consul-addr 192.168.8.131:8500 --template /usr/local/nginx/consul/nginx.ctmpl:/usr/local/nginx/consul/vhost.conf:"nginx -s reload" --log-level=info
2018/06/18 13:15:45.719503 [INFO] consul-template v0.19.4 (68b1da2)
2018/06/18 13:15:45.720675 [INFO] (runner) creating new runner (dry: false, once: false)
2018/06/18 13:15:45.721967 [INFO] (runner) creating watcher
2018/06/18 13:15:45.723542 [INFO] (runner) starting
2018/06/18 13:15:45.724051 [INFO] (runner) initiating run
2018/06/18 13:15:45.728395 [INFO] (runner) initiating run
2018/06/18 13:15:45.731084 [INFO] (runner) rendered "/usr/local/nginx/consul/nginx.ctmpl" => "/usr/local/nginx/consul/vhost.conf"
2018/06/18 13:15:45.732215 [INFO] (runner) executing command "nginx -s reload" from "/usr/local/nginx/consul/nginx.ctmpl" => "/usr/local/nginx/consul/vhost.conf"
2018/06/18 13:15:45.733669 [INFO] (child) spawning: nginx -s reload
--consul-addr:指定consul服務的ip和端口; ./nginx.ctmpl:這是用nginx.ctmpl這個模板來啓動進程,這是寫的相對路徑,也能夠寫絕對路徑; vhost.conf:nginx.ctmpl模板生成後的文件名,這也能夠寫絕對路徑,若是不寫絕對路徑,這個文件就在當前目錄生成(/usr/local/nginx/consul/)
因爲consul-template在前臺運行,因此咱們在打開一個終端驗證。
[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
upstream http_backend {
server {{ .Address }}:{{ .Port }} max_fails=3 fail_timeout=90;
}
server {
listen 8085;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
經過marathon建立nginx容器實例:
[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":[]}
[root@mesos-master1 ~]# cat /usr/local/nginx/consul/vhost.conf
upstream http_backend {
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;
}
server {
listen 8085;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
[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負載均衡是能夠正常輪詢的!!!