<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>源碼下載>集成開發環境源碼>

使用Docker實現持續集成

大?。?/span>0.8 MB 人氣: 2017-10-10 需要積分:1
本文轉載自《程序員》,謝絕轉載,更多精彩,請訂閱2016年《程序員》
  持續集成(Continuous Integration,簡稱CI)作為先進的項目實踐之一,近年來逐漸受到國內軟件公司的重視;但對于許多朋友來說,可能從未聽說過持續集成這個詞,抑或只是了解概念但并沒有實踐過。
  什么是持續集成?它對軟件開發有哪些好處呢?
  持續集成的概念
  隨著軟件開發復雜度的不斷提高,團隊開發成員間如何更好地協同工作以確保軟件開發的質量已經慢慢成為開發過程中不可回避的問題。尤其是近些年來,敏捷(Agile)在軟件工程領域越來越紅火,如何能在不斷變化的需求中快速適應和保證軟件質量也顯得尤其重要。
  持續集成正是針對這類問題的一種軟件開發實踐:它倡導團隊開發成員必須經常集成他們的工作,甚至每天都可能發生多次。而每次集成都是通過自動化的構建來驗證,包括自動編譯、發布和測試,從而盡快地發現集成錯誤,讓團隊能夠更快的開發產品。
  讓我們以A項目為例描述一普通團隊是如何使用CI的:
  首先,解釋下集成:所有的項目代碼都托管在SVN或者Git服務器上(以下簡稱代碼服務器)。每個項目都有若干單元測試和集成測試。集成測試是單元測試的邏輯擴展:在單元測試的基礎上,將所有模塊按照設計要求組裝成為子系統或系統進行集成測試。實踐表明,一些模塊雖然能夠單獨地工作,但并不能保證連接起來也能正常工作。一些局部反映不出來的問題,在全局上很可能暴露出來(關于單元測試及集成測試的詳述,讀者可以查閱相關文檔)。
  簡單來說,集成測試就是把所有的單元測試跑一遍,以及其他能自動完成的測試。只有通過了集成測試的代碼才能上傳到代碼服務器,確保上傳的代碼沒有問題。集成一般指集成測試。持續,顯而易見就是長期對代碼進行的集成測試。既然是長期進行,那么最好是自動執行,否則人工執行既沒保證,而且耗人力。
  基于此種目的,我們需要有一臺服務器,它將定期從代碼服務器中拉取,并進行編譯,然后自動運行集成測試;并且每次集成測試的結果都會記錄在案。
  在A項目中,設定執行這個工作的周期是1天。也就是說服務器每天都會準時地對代碼服務器上的最新代碼自動進行一次集成測試。
  持續集成的特點
  它是一個自動化的周期性的集成測試過程,從拉取代碼、編譯構建、運行測試、結果記錄、測試統計等都是自動完成的,無需人工干預;
  需要有專門的集成服務器來執行集成構建;
  需要有代碼托管工具支持。
  持續集成的作用
  保證團隊開發人員提交代碼的質量,減輕了軟件發布時的壓力;
  任何一個環節都是自動完成的,無需太多的人工干預,有利于減少重復過程以節省時間、費用和工作量;
  筆者在實踐的過程中總結出了以下心得:
  代碼越早push出去,用戶能越早用到,快就是商業價值;
  用戶越早用到就越早反饋,團隊越早得到反饋,好壞都是有價值的輸入;
  用戶不反饋,說明我們做了用戶不想要的東西(通過用例跟蹤)或者市場沒做好,能幫助產品市場人員調整策略;
  代碼庫存越是積壓,就越得不到生產檢驗,積壓越多,代碼間交叉感染的概率越大,下個release的復雜度和風險越高;
  代碼庫存越多,workflow的包袱越重,管理成本越大。
  了解了持續集成的優點,讀者是不是有立馬部署一套的沖動呢?然而,部署持續集成環境,并不簡單。
  從一個Java項目持續集成的典型場景為例。我們只要建立一個基于Jenkins + Maven + Git(SVN) 的持續集成環境,再加上持續集成所要求的測試和流程就可以大致運行。
  但在搭建好一整套持續集成的流水線之后,卻發現它并不像想象中絲般順滑,甚至比在本地開發測試的效率還低。為什么會出現這樣的情況?
  目前常見的在持續集成過程中遇到的問題有如下幾種:
  編譯時依賴和運行時依賴
  從字面上不難理解這兩種依賴。雖然編譯時依賴通常也是運行時依賴,但并不能由此判定編譯時依賴一定是運行時依賴。例如,在開發過程中需要某些提供API的Jar包,但在運行時可能需要的是具體API實現的Jar包。其次,被依賴的包會有它自身的依賴,這樣的情況下,項目會對這些包產生間接依賴(運行時依賴),依此類推,最終形成一個依賴樹。當項目運行時,這些依賴樹上的包必須全部就位,否則項目無法運行。
  Maven在POM中通過scope來判定依賴的類型,從而幫助開發和運維人員擺脫手動處理依賴樹的工作,然而運行時所有依賴包最終是要安裝到生產環境的,這部分工作Maven并不能自動完成。因此,一個常用方式是將運行時所依賴的包拷貝到項目文件中,比如Java Web應用的WEB-INF/lib,然后將項目全部打成一個包。在安裝項目包后,修改環境變量,將這些依賴包所在的路徑加入相應的環境變量中,如ClassPath。
  再舉個典型的例子,目前的操作系統和其他系統框架都考慮到了運行時依賴樹的處理問題,比如Ubuntu的apt-get,CentOS的yum,Ruby的RubyGem,Node的npm等等,在安裝某個軟件包時,系統會自動將所需的依賴包按順序下載并安裝。
  依賴時的復雜度
  項目除了對程序包的依賴,對于運行環境也有些具體的要求。比如,Web應用需要安裝和配置Web服務器、應用服務器、數據服務器等,企業應用中可能需要消息隊列、緩存、定時作業,或是對其他系統以Web Service或API的方式暴露服務等。這些可以看成項目在系統層面對外部的依賴。這些依賴有些可以由項目自行處理,而有些則是項目無法處理的,比如運行容器,操作系統等,這些是項目的運行環境。
  總之,依賴的復雜度主要有兩個:
  依賴包間的版本兼容性問題。兼容性問題是軟件開發者的噩夢。
  間接依賴,或多重依賴問題。例如:A依賴于Python 2.7,A還依賴于B,但B卻依賴于Python 3,苦逼的是Python 2.7和Python 3不兼容。依賴中最痛苦的事莫過于此。
  不一致的環境
  簡單項目中,開發和運行環境都由開發人員搭建,當公司變大時,系統的運行環境將由運維人員搭建,而開發測試環境如果由運維人員搭建則工作量太大,由開發人員自己搭建則操作復雜又容易產生不一致的情況。假設公司為項目A和項目B開發了新版本。但環境和軟件升級不是同步進行,出錯的可能性非常大(想一想間接依賴和多重依賴的情況)。大家對這樣的場景有沒有印象:當新版本部署時,發現問題,測試或部署人員說:“版本有問題,無法運行!”開發人員卻說:“我這里沒問題啊,運行正常!”
  泛濫的部署
  如果項目簡單,沒有任何歷史項目和代碼的拖累,且各項目之間也沒有任何的關聯,只需進行資源方面的管理:分配機器,初始化系統,分配IP地址等。各個項目的運行環境、數據庫、開發環境等都由具體項目的開發人員手動完成,這樣的環境出問題怎么辦?很簡單,涼拌——重裝系統。
  理想很豐滿,現實很骨感,歷史遺留問題往往對現在的項目有很大影響:多語言(Java,PHP、C ),多系統(各種Windows、Linux),多構建工具版本(Java7、8),各種配置文件和各種黑科技補丁腳本散落在系統的各個角落,沒人能找得到,也沒人搞得懂。配置被誰改掉了,服務宕掉了,根本無從管理。
  問題分析完了,我們又該如何克服這些問題,使用什么工具和方法,從而達到絲般順滑的持續集成呢?下面就是要介紹的主角:Docker、AppoSoar及AppHouse。
  Docker如今在國內已經如火如荼,Docker可以做到一次構建,處處運行;各種實踐和生產部署也紛紛上馬,Docker的基本知識和好處筆者也就不在這里科普了。
  AppSoar,以Docker為基礎,以企業應用為導向,以安全穩定為目標,打造專業、簡單易用的企業級容器云解決方案。它提供了企業應用商店、友好圖形化界面管理、多環境管理、混合云支持、容器持久存儲、容器網絡模式、容器可擴展性、容器負載均衡與調度、API接口支持、系統高可用等一系列強大功能。
  AppHouse為容器運行平臺提供了一種集鏡像管理、鏡像安全、鏡像高可用及鏡像高速訪問為一體的企業級鏡像倉庫管理方案。AppHouse支持HTTPS訪問;基于角色的權限控制;系統高可用;部署靈活;一鍵安裝,一鍵升級;友好的圖形化界面,LDAP/AD用戶集成;支持swift/Glusterfs/公有云存儲接入;提供豐富的API接口;支持連接Git源碼倉庫,代碼自動構建;提供webhook接口,支持持續部署。解決了docker build、push、pull的一攬子問題。
  言歸正傳,既然為了達到順滑的持續集成要求,那么為什么選擇用Docker、AppSoar、AppHouse來部署?
  上面我們提到了傳統方式搭建持續集成平臺經常遇到4個問題:編譯和運行時依賴、依賴時的復雜度、不一致的環境和泛濫的部署,接下來我們來分析下Docker+AppSoar+AppHouse組合如何解決這些問題。
  首先,Docker可以讓你非常容易和方便地以“容器化”的方式去部署應用。 它就像集裝箱一樣,打包了所有依賴,再在其他服務器上部署很容易,不至于換服務器后發現各種配置文件散落一地,這樣就解決了編譯時依賴和運行時依賴的問題。
  其次,Docker的隔離性使得應用在運行時就像處于沙箱中,每個應用都認為自己是在系統中唯一運行的程序,就像剛才例子中,A依賴于python 2.7,同時A還依賴于B,但B卻依賴于Python 3,這樣我們可以在系統中部署一個基于Python 2.7的容器和一個基于Python 3的容器,這樣就可以很方便地在系統中部署多種不同環境來解決依賴復雜度的問題。這里有些朋友可能會說,虛擬機也可以解決這樣的問題。誠然,虛擬化確實可以做到這一點,但是這需要硬件支持虛擬化及開啟BIOS中虛擬化相關的功能,同時還需要在系統中安裝兩套操作系統,虛擬機的出現是解決了操作系統和物理機的強耦合問題。但Docker就輕量化很多,只需內核支持,無需硬件和BIOS的強制要求,可以輕松迅速地在系統上部署多套不同容器環境,容器的出現解決了應用和操作系統的強耦合問題。正因為Docker是以應用為中心,鏡像中打包了應用及應用所需的環境,一次構建,處處運行。這種特性完美解決了傳統模式下應用遷移后面臨的環境不一致問題。
  同時,Docker壓根不管內部應用怎么啟動,你自己愛咋來咋來,我們用docker start或run作為統一標準。這樣應用啟動就標準化了,不需要再根據不同應用而記憶一大串不同啟動命令。
  基于Docker的特征,現在常見的利用Docker進行持續集成的流程如下:
  開發者提交代碼;
  觸發鏡像構建;
  構建鏡像上傳至私有倉庫;
  鏡像下載至執行機器;
  鏡像運行。
  其基本拓撲結構如圖1所示。
  使用Docker實現持續集成
  圖1 利用 Docker 進行持續集成基本拓撲結構
  熟悉Docker的朋友都知道,Docker啟動非???,可以說是秒啟。在上述的五步中,1和5的耗時較短,整個持續集成主要耗時集中在中間的3個步驟,也就是docker build、docker push、docekr pull這樣還是無法達到順滑的極致要求,下來我們來分析下build、push、pull的耗時和解決方法:
  docker build
  網絡優化
  dockerhub的官方鏡像在國外,由于眾所周知的原因,在國內進行構建時網絡會是很大的瓶頸,甚至某些公司的環境是無Internet連接的。 在這種情況下,建議使用國內的鏡像源,或者自己搭建私有倉庫,保存項目需要的基礎鏡像,把構建過程中的網絡傳輸都控制在國內或者內網,這樣就不用再考慮網絡方面的問題。
  使用 .dockerignore文件
  dockerignore文件的設計是為了在docker build的過程中排除不需要用到的文件以及目錄,目的是為了docker build這個過程可以盡可能地快速高效以及構建出來的image沒有多余的“垃圾”。
  最小化鏡像層數(layers
  把鏡像層數減到最少,能加快容器的啟動速度,但是這里也要權衡另一個問題:dockerfile的可讀性。你可以把一個dockerfile寫得很復雜以達到構建出最小層數的鏡像,但同時你的dockerfile可讀性也降低了。所以我們要在鏡像層數和dockerfile可讀性之間做出妥協。
  docker push
  docker registry升級到v2后加入了很多安全相關檢查,在v2中的鏡像的存儲格式變成了gzip ,鏡像在壓縮過程中占用的時間也比較多。我們簡單分解一下docker push的流程。
  buffer to disk,將該層文件系統壓縮成本地的一個臨時文件;
  上傳文件至registry;
  本地計算壓縮包digest,刪除臨時文件,digest傳給registry;
  registry計算上傳壓縮包digest并進行校驗;
  registry將壓縮包傳輸至后端存儲文件系統;
  重復1-5直至所有層傳輸完畢;
  計算鏡像的manifest并上傳至registry重復 3-5。
  這樣設計導致push會很慢,如果采用官方dockerhub,需要考慮docker build一節中提及的網絡方面影響,dockerhub公有鏡像庫還需考慮安全方面因素。
  同時docker和registry設置了過多的安全防范措施(如雙向證書認證等),主要是為了防止在公有云的環境下鏡像的偽造和越權獲取。但是在一個可信的環境內,如果build和push過程都是自己掌控,很多措施都是多余的。
  docker pull
  docker pull 鏡像的速度對服務啟動速度至關重要,好在registry v2后可以并行pull了,速度有了很大改善。但是依然有一些小的問題影響了啟動的速度:
  下載鏡像和解壓鏡像是串行的;
  串行解壓,由于v2都是gzip要解壓,盡管并行下載了還是串行解壓,內網的話解壓時間比網絡傳輸都要長;
  和registry通信, registry在pull的過程中并不提供下載內容只是提供下載url和鑒權,這一部分加長了網絡傳輸,而且一些metadata還是要去后端存儲獲取,延時還是有一些的。
  通過剛才的分析,大家可以看到,其實docker build、push、pull其實主要耗時是在網絡傳輸(主要)及安全防范措施(輕微)上,整個傳輸過程甚至大大超過了其他所有步驟的時間;這樣可以借助我們的AppHouse方便的搭建本地企業級鏡像倉庫,將網絡傳輸轉移至內網,同時完全掌控了 build、push和pull的過程,這樣提高效率的同時也解決了安全問題,可謂一舉兩得。
  經過Docker、AppHouse的幫助,我們距極致追求的如絲般順滑的持續集成目標只有一步之遙,Docker解決了依賴和環境問題,AppHouse解決了鏡像安全快速傳輸的問題,接下來就是容器的部署和管理問題。
  Docker實現了底層技術的創新,它的出現將開發者從與系統的糾纏中釋放了出來,但是阻礙企業使用Docker的問題是容器的大規模部署、管理問題和缺少企業級容器工具及系統。
  鏡像創建完成后,需要把它發布到測試和生產環境。因為Docker占用資源小,在單個服務器上部署成百上千個容器也不足為奇。這個階段中如何更合理地使用Docker也是一個難點,開發團隊需要考慮如何打造一個可伸縮擴展的分發環境。
  AppSoar提供人性化的Web管理界面,豐富的Compose文件格式和功能完備的API接口,通過Compose實現以十分簡單的文件描述復雜的應用結構,讓部署變得更簡單。并且,AppSoar還提供豐富的企業應用商店,讓在一鍵創建服務成為可能。這樣可以快速搭建應用場景,開發者只需要關注開發本身即可。

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
      <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
      <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
      <acronym id="s8ci2"></acronym>
      <acronym id="s8ci2"><center id="s8ci2"></center></acronym>