<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 一個通用應用運維管控平臺的設計實現

          一個通用應用運維管控平臺的設計實現

          作者: 時間:2018-07-24 來源:網絡 收藏

          2)遠程服務器執(zhí)行模式;遠程服務器執(zhí)行模式就是比較常規(guī)的將腳本發(fā)送到遠程服務器上,并在遠程服務器上執(zhí)行的模式,這種模式需要選擇所需要執(zhí)行服務器列表,這里就需要依靠資源管理系統(tǒng)中的物理機管理功能了,可以通過某種方式對服務器進行手動分組或自動分組,然后執(zhí)行的時候可以按照不同的維度(比如按ip選擇,按機房選擇,按業(yè)務選擇,或按自定義組名選擇)選擇所需的服務器組,進而將腳本下發(fā)到這些服務器上執(zhí)行。

          本文引用地址:http://www.ex-cimer.com/article/201807/383696.htm

          總結一下,腳本執(zhí)行功能比較基礎,同時還包含三個子功能,這三個子功能放到配置管理里面去,后面會具體闡述:

          1)腳本管理功能;用于管理用戶上傳的腳本和常用的基礎腳本。

          2)賬戶管理功能;用于管理具體的執(zhí)行用戶。

          3)服務器分組功能;用于基于資源管理系統(tǒng)的物理機管理數據按照某種方式劃分成一定的服務器組。

          說完具體的功能之后,我們需要確定具體的方式,準確的說,方式有兩種:

          1)SSH遠程執(zhí)行;可以通過封裝ssh和paramiko的方式實現,python中的ansible和fabric包也都支持遠程SSH執(zhí)行的功能。Shell就用ssh命令即可。

          該方式對中心節(jié)點要求比較高,每一個遠程執(zhí)行命令都會在中心節(jié)點啟動一個進程(線程)來執(zhí)行,對中心機的壓力較大,同時由于是基于SSH的原理,故命令執(zhí)行的效率較差,命令執(zhí)行時間長。

          2)Agent執(zhí)行;在每臺服務器上部署一個Agent,用戶執(zhí)行管控系統(tǒng)發(fā)送的腳本。這種方式的優(yōu)點是可以采用拉的方式,由各個子節(jié)點訂閱分給自己的任務,執(zhí)行完成后再講結果推給中心節(jié)點的數據;當然也可以像SSH方式通過推的方式由中心節(jié)點將任務發(fā)給遠程的Agent,然后Agent去執(zhí)行,并將結果反饋給中心節(jié)點。這種方式的執(zhí)行效率會比較高,可擴展性強,將來甚至可以通過該Agent進行配置或運行數據上報,對于配置管理也比較方便,缺點是需要開發(fā)Agent,Agent需要支持異步非阻塞模式,且需要維護每臺服務器的Agent,包括部署和管理。

          Python的saltstack軟件就是通過Agent的方式實現的,需要在每臺物理機上部署一個saltstack minion進程用于接受任務和執(zhí)行任務,在每個中心機上部署saltstack master進程用于下發(fā)任務,saltstack master通過將任務下發(fā)到zeromq中從而實現各個minion獲取任務并執(zhí)行,同時saltstack也支持將任務執(zhí)行結果存儲到Redis等數據庫中,便于后續(xù)的跟蹤和查看。

          不過Agent也可以通過自行開發(fā)的方式實現,線上所有的Agent大多都是這種原理,也都是自己實現的,不過具有一定的開發(fā)難度。

          因此對于腳本執(zhí)行的實現方式來看總結如下:

          1)如果用SSH的方式,使用python的ansible api或fabric。

          2)如果用Agent的方式,可以考慮使用Python的saltstack minion Agent。

          3)如果用自研Agent的方式,可以使用golang。上面兩種方式相對快速容易實現,這種方式會有一點的時間消耗,不過可以積累一定的開發(fā)經驗。

          2. 文件分發(fā):

          文件分發(fā)是除了腳本執(zhí)行的另一個基礎功能,該功能的技術描述就是將某臺服務器上的某個或某些文件,傳輸到其他的某個或某些服務器的某個位置上。

          文件分發(fā)功能分為以下兩個子功能,相關文件和模板的管理工作放到配置管理中去實現,這里只介紹如何實現文件分發(fā):

          1)普通文件分發(fā),如代碼包,鏡像文件,軟件包等。

          2)模板文件分發(fā),如配置文件等。

          模板文件分發(fā)與普通文件分發(fā)不同的區(qū)別是模板文件中存儲變量替換的邏輯,這里普通文件的管理和模板文件的管理以及配置變量的管理都放到配置管理系統(tǒng)中去實現,用戶選擇文件下發(fā)的時候可以選擇是普通文件還是模板文件,如果是模板文件就會自動去加載配置管理中的變量管理生成臨時的普通文件并下發(fā)。

          具體的下發(fā)方式也分為兩種:

          1)管理機文件下發(fā)到普通的業(yè)務物理機上。

          其實大部分的文件分發(fā)場景應該都是這一種,也就是我們將基礎文件或模板文件放到管理機上,作為我們的基準文件,比如我們的部署代碼,軟件包等等,我們只要保證管理機上的文件版本的一致性,就可以保證普通的業(yè)務物理機上面的文件和管理機上的文件一致,也就是配置管理功能的中的文件版本一致性管理。

          這種模式下的文件可能相對容量較小,比如小文件(幾k),軟件包(幾M),或者稍大文件(幾G),文件從管理機下發(fā)到某些業(yè)務物理機上面臨的問題是并發(fā)導致的傳輸速度問題,小文件情況下還可以忽略,基本可以在秒級完成,但稍大文件的傳輸就會有時間問題,隨著業(yè)務物理機的個數增加而增加,因此這種情況會有并發(fā)和流量的控制。

          另外文件的傳輸會提前進行文件md5的對比判斷,如果文件的md5值相同,那就沒有再傳輸文件的必要,在稍大文件情況下可以節(jié)省較多的時間。

          文件傳輸,可以使用ansible的copy模塊,或者salt的文件file模塊,當然也可以自研方式中封裝rsync的方式,rsync支持文件md5值校驗以及斷點續(xù)傳等方式。

          2)物理機之間的文件互傳。

          物理機之間的文件互傳準確的來說是反配置管理邏輯的,這種方式就和我們現在的文件傳輸方式很類似,也就是從一臺服務器scp文件到另一臺服務器上。對于配置文件和小文件、軟件包等需要配置管理的文件來說,我們需要明確禁止使用這種方式。但這種方式的好處就是可以用來P2P的傳輸較大的文件,比如幾百G的鏡像文件。

          對于幾百G的鏡像文件來說,如果使用第一種管理機管理的方式,只能1對多的傳輸將會造成傳輸時間的極大占用,而使用這種P2P的方式,即可以極大的提升文件傳輸的速度。

          物理機之間的文件互傳使用rsync即可,由于文件較大,且可能出現斷點,rsync是比較方便的解決大文件傳輸的方法,需要在每臺服務器上的Agent上對rsync功能進行封裝,支持Agent之間的rsync文件互傳。

          物理機文件中需要管理的文件列表,可以通過Agent匯報到配置管理系統(tǒng)中,用戶選擇文件分發(fā)的時候,可以選擇配置管理系統(tǒng)中的點對點大文件傳輸功能,配置管理系統(tǒng)中可以自動選擇傳輸源,針對被傳輸物理機的個數,實現真正的點對點傳輸,不需要用戶自己去選擇源文件服務器,可以節(jié)省大量的人為運維操作。

          3. 批量執(zhí)行:

          所謂的批量執(zhí)行功能就是上面兩個基礎功能中在選擇目的服務器的個數的時候支持多個服務器,而不是只能選擇單個服務器。



          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();