技術棧及文檔
資源調度框架 MESOS
應用編排平臺Marathon
nginx 動態修改 upstream dyups
nginx 動態修改 upstream upsync
使用Mesos 進行機器資源管理
首先,是機器資源的管理。在微服務的架構中,原有的單體服務被拆分成了一個個獨立單元的應用程序,這些服務體量較小,可以獨立運行在配置較小的機器上。為了故障隔離,我們會盡可能的把這些服務部署在不同的虛擬機上,這樣機器的數量會成倍增加。對于運維來說,每個新服務部署時,需要先查看現有機器的剩余資源是否滿足新服務的需求,有時可能因為評估不準確造成來回擴容、遷移,或者資源浪費。
開始時,我們的架構可能時這樣的
為了解決上面的問題,可以使用 MESOS ( 布式資源管理框架),它可以 讓我們像用一臺電腦(一個資源池)一樣使用整個數據中心。
mesos 部署時分為 master 和 agent 兩個角色,當然,你可以在同一臺機器啟動它們。
安裝Mesos 前需要安裝zookeeper,mesos 使用zk 實現高可用和選舉,包括一個 master leader 和 幾個備份 master 避免宕機。
Mesos master 負責管理各個Framework和Slave,并將Slave上的資源非配給各個Framework。
Mesos agent 負責管理本節點上的各個Mesos Task,為各個Executor分配資源 (低版本為 mesos-slave)。
$cat>/tmp/bintray-mesos-el.repo<
#bintray-mesos-el-packagesbymesosfromBintray
[bintray-mesos-el]
name=bintray-mesos-el
baseurl=https://dl.bintray.com/apache/mesos/el7/x86_64
gpgcheck=0
repo_gpgcheck=0
enabled=1
EOF
$sudomv/tmp/bintray-mesos-el.repo/etc/yum.repos.d/bintray-mesos-el.repo
$sudoyumupdate
$sudoyuminstallmesos
$tree/etc/mesos-master
/etc/mesos-master/
|--hostname
|--ip
|--log_dir
|--quorum#quorum>(numberofmasters)/2
`--work_dir
$tree/etc/mesos-agent
/etc/mesos-agent/
|--containerizers#容器類型,默認mesos,可以添加docker,如:mesos,docker
|--hostname
|--ip
|--log_dir
|--master#master地址,格式為host:port或
zk://host1:port1,host2:port2,.../path或file:///path/to/file
|--resources#設置總資源大小,可以設置小些來預留更多機器資源
`--work_dir
$cat/etc/mesos/zk#設置mesos在zk中的存儲目錄
zk://192.168.100.9:2181,192.168.100.110:2181,192.168.100.234:2181/mesos
$systemctlstartmesos-master
$systemctlstartmesos-slave
當mesos服務啟動后,agent 會向master 節點匯報機器資源,包括CPU、內存、磁盤等。當我們要發布一個服務時,只需要設置這個服務的CPU、內存、磁盤參數, mesosmaster 會自動幫我們選擇有足夠資源的機器去運行,如下圖
我們將微服務的啟動都交給 Mesos 管理,這樣我們只需要關注整體資源即可。MESOS 提供了UI界面,可以直接訪問 mesos master 的5050 端口,查看集群資源使用情況。總體使用情況 及 Agent 節點使用情況
完成以上后,我們的架構變成了這樣
使用Marathon 進行微服務管理
Marathon 是建立在 Mesos 上的私有 PaaS平臺。它能自動處理硬件或者軟件故障,并確保每個應用程序都"永遠在線"。我們使用 Marathon 管理微服務有以下優勢1. 支持容器和非容器,不受限于服務啟動類型,操作系統版本等。2. 漂亮而強大的用戶界面,可以在UI 上進行快捷方便的應用程序配置3. 支持約束條件,例如允許一個mesos agent 節點只運行一個應用程序。4. 支持健康檢查。可以配置 http、https、tcp、command 類型的監控檢查。5. 完整的REST API,易于集成和編寫腳本。這個對于后期集成來說至關重要。
#Addtherepository
$sudorpm-Uvhhttp://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-2.noarch.rpm
#Installpackages
$sudoyum-yinstallmesosmarathon
#marathonandmesoszkpath
$cat/etc/default/marathon
MARATHON_MESOS_USER="root"
MARATHON_MASTER="zk://192.168.100.9:2181,192.168.100.110:2181,192.168.100.234:2181/mesos"
MARATHON_ZK="zk://192.168.200.9:1181,192.168.100.110:2181,192.168.100.234:2181/marathon"
systemctlstartmarathon
啟動后,直接訪問 marathon 的 8080 端口,就能看到一個漂亮強大的 UI 界面。
我們以 springboot 應用為例,在 marathon 上創建一個應用程序
當我們更新應用程序時, marathon 會新建相同實例數量的應用程序,待 health check通過之后替換老節點,所以不需要擔心新的服務沒有啟動期間老的服務停掉造成線上事故。到這里為止,我們已經可以在marathon 上方便快捷的進行日常應用的創建、升級、擴容、縮容。當服務健康檢查失敗或者機器宕機后,marathon 會自動在其它節點上啟動掛掉的應用程序,大大提升了高可用性。
使用 nginx upsync/dyups 模塊進行平滑變更
當我們的微服務可以隨機分配在不同機器上時,便產生了一個新的令人頭疼的問題。nginx 并不知道后端節點的變更, 也不可能每次都去手動修改 upstream 節點, reloadnginx,這樣成本就太高了。我們的解決思路是和微服務的注冊中心打通,當服務注冊、注銷時,都會對注冊中心進行更新,利用 nginx upsync/dyups 模塊 可以動態修改 upstream 節點的能力進行同步,做到平滑變更。如果使用的注冊中心為 consul,建議使用 upsync 模塊,這樣無需開發,只需要簡單的nginx 配置,就可以實現我們想要的效果, 支持 consul kv, consul_services,consul_health, 同時 upsync 也支持 etcd。建議使用 consul_health 接口。upsync 模塊不是nginx 內置模塊,使用時需要重新編譯添加此模塊。
wget'http://nginx.org/download/nginx-1.8.0.tar.gz'
tar-xzvfnginx-1.8.0.tar.gz
cdnginx-1.8.0/
./configure--add-module=/path/to/nginx-upsync-module
make
makeinstall
配置文件示例
http{
upstreamtest{
upsync127.0.0.1:8500/v1/health/service/testupsync_timeout=6mupsync_interval=500msupsync_type=consul_healthstrong_dependency=off;
upsync_dump_path/usr/local/nginx/conf/servers/servers_test.conf;
include/usr/local/nginx/conf/servers/servers_test.conf;
}
upstreambar{
server127.0.0.1:8090weight=1fail_timeout=10max_fails=3;
}
server{
listen8080;
location=/proxy_test{
proxy_passhttp://test;
}
location=/bar{
proxy_passhttp://bar;
}
location=/upstream_show{
upstream_show;
}
}
}
當upsync無法滿足我們的需求或者注冊中心不是 consul、etcd 時,我們可以考慮使用nginx dyups 模塊。dyups 僅對外提供 upstream 的增刪查改接口,和注冊中心對比、修改的工作需要我們通過腳本的方式完成。雖然這種方式麻煩一些,但是可定制化程度高,支持 http, C,lua API,基本上可以滿足大部分的場景需求。
dyups 模塊也需要nginx 編譯時添加
$gitclonegit://github.com/yzprofile/ngx_http_dyups_module.git
#tocompileasastaticmodule
$./configure--add-module=./ngx_http_dyups_module
#tocompileasadynamicmodule
$./configure--add-dynamic-module=./ngx_http_dyups_module
示例配置
http{
includeconf/upstream.conf;
server{
listen8080;
location/{
#Theupstreamheremustbeanginxvariable
proxy_passhttp://$dyups_host;
}
}
server{
listen8088;
location/{
return200"8088";
}
}
server{
listen8089;
location/{
return200"8089";
}
}
server{
listen8081;
location/{
dyups_interface;
}
}
}
特別注意,使用dyups 時, proxy_pass 時的 upstream 必須是 nginx 變量,否則不生效,切記。
整體回顧
經過以上調整,我們得到了以下優化
1.服務器資源自動分配,合理利用
2.提升微服務的高可用性
3.減低OPS人工成本,更加便于管理和維護