通過Docker容器執行持續整合/持續部署

軒墨發表於2017-09-20
本文講的是通過Docker容器執行持續整合/持續部署【編者的話】 對於Docker主流的應用場景:持續整合和持續部署(CI/CD)大家也許並不陌生。這篇文章從獨特的視角闡述瞭如何利用各種雲平臺構建屬於自己的CI/CD容器,筆者還自己擴充套件了Gitlab CI引擎,對CI感興趣的同學對這個文章應該很感興趣。

我曾經使用Docker了一段時間,在過去的一年裡伴隨著眾多的Docker容器湧入,幫助使用者們更容易的部署Docker容器到生產環境中。一些工具是第三方公司提供,當然也包括Docker公司自己的容器工具(例如:Docker Swarm、Docker Machine和 Docker Compose)。儘管如此,最近我在測試一種新的Docker工作流,它可以允許我推送程式碼,並做測試、構建專案,還可以將程式碼部署到跑Docker的生產環境叢集中。

接下來隆重介紹我的新工具 bar service——ThreeBar①,一個可以在Heroku上執行持續整合/持續部署(CI/CD)系統。通常情況下,新開發的程式碼部署到伺服器遵循下面的流程:
  1. 建立一個本地元件
  2. 推送程式碼到git倉庫的feature/development分支
  3. Shippable,一個持續整合引擎,一旦檢測到有新的提交(commit),通過pull獲取最新的程式碼並且執行相關的測試
  4. 如果測試全都通過了等著被部署到生產環境中,就會建立一個合併(merge)分支的請求並且執行該合併(merge)
  5. Shippable一旦檢測到有新的提交到遠端master分支,同時會執行測試,並且推送原始碼到Heroku的git倉庫中
  6. Heroku 將會自動構建這個應用程式並且部署它。


這個工具真的可以方便、快捷地部署專案並且保證所有部署到生產環境的程式碼都經過了測試而且是可靠的。

儘管如此,還是有一個問題,那就是大規模部署Heroku需要花費高昂的費用。選擇使用Heroku,你將會獲得Heroku提供的免費使用優惠②,一個標準的512記憶體的由Heroku提供的Dyno容器只需要35$。公平的說,Heroku提供的虛擬主機服務已經夠實惠了,但是一些應用的複雜程度要求Heroku提供更靈活的定製化需求,收取一定費用也無可厚非。

當然Docker可以替代Heroku,提供相應的程式碼部署服務。但是上面談到的問題仍舊存在。當你的程式碼需要部署的時候,頻繁手動啟動和關閉服務是得不償失的。讓我們來比較一下不同持續整合/持續部署引擎和Docker相比有什麼不同。

尋找解決方案

Docker並不是第一個也不是最後一個端到端的持續整合工作流解決方案。因此我們需要將眾多不同的技術組合到一起用來完成我們想要的功能。下面將會介紹三個主流的提供構建引擎的服務:一個是CI/CD的測試執行引擎,一個是web容器,一個是容器介面卡。

CI/CD 伺服器,測試執行引擎

當我們選擇一個CI/CD服務,你必須確定他們必須支援Docker容器的構建。下面的這些服務都包含了這一功能:


當然還有一些其他的服務,包括大名鼎鼎的Jenkins CI server。這裡你可以自己去搜尋這些服務。一些服務在容器上執行構建,但是他們相互之間是完全獨立的。稍後你就會看到,你可以在Docker-in-Docker上執行服務,同時可以使用在Docker容器中執行的其他服務來構建你的Docker容器。

在我的試驗中,我選擇了和Gitlab 版本管理伺服器端同時執行GitLab CI 系統。通過Gitlab版本管理伺服器,我可以很清楚的看到每次commit。選擇Gitlab不僅是因為他是一個免費的開源原始碼託管倉庫和對託管在上面的專案提供的持續部署引擎,同時也是一個通過安裝gitlab執行你自己的服務的開源軟體。

如果你選擇使用Gitlab CI System搭建你的持續整合框架,你必須提供屬於自己的測試執行服務。宿主機的持續整合軟體只能執行特定的測試服務,實際上它自己並不能自己執行測試任務,通常都是啟動由本機提供相應的測試服務來執行的,你不光可以通過服務提供商啟動引擎或者你直接執行你本機上的服務(虛擬機器VM或Docker容器)。

伺服器託管提供商

當然你同時也需要一個伺服器託管提供商讓Docker守護程式可以在它之上執行。不幸的是,使用Docker意味著經常需要執行和管理自己的伺服器,也就是你將要負責這個主機的運維。但是,我想通過下面的內容說明,你可以在Docker執行一個高可用、多資料中心架構,這意味著即便是停機一個小時也不會像以前那樣對業務影響那麼巨大。

常用的伺服器託管提供商包括下面的幾個③:


業務流程

即是你有了一套構建好了的Docker容器和能夠執行Docker守護程式的伺服器。你還是需要一個能夠被輕易啟動的容器並且能夠在構建一個新映象的時候能重複部署他們。正如我最近正在使用的名叫Tutum的業務流程服務。

目前,Tutum是一個能幫助你管理你的容器部署工作流的服務形式。與此同時,你還能在各種雲平臺上快速動態增加節點,建立新服務,通過一個私有的register來部署你的應用。

此外,Tutum還為你的容器建立了一個私有網路,意味著可以通過你的Tutum賬戶你的Docker容器擁有自己的私有固定IP地址並且通過路由來訪問其他容器。無論你的物理機是否在同一個資料中心,還是通過世界各地的不同的伺服器託管提供商。它都將允許你建立一個基於多伺服器、多雲平臺的彈性的解決方案。如果你之前見過Flannel by CoreOS,Tutum的私有網路和它差不多。

我一直在尋找類似上面談到的這種服務。就在前不久,我剛做了一個實驗:在多容器Docker之間通過vpn建立一個P2P網路。這是很久之前的Docker網路配置達不到的需求,但是現在Tutum做到了。

Tutum 同時也整合了CI/CD元件,並且支援git推送(push)。當Tutum 完成功能的時候,它可能成為唯一的你需要包含的到原始碼倉庫中的其他服務。

Tutum 擁有我們需要進行CI/CD的幾個關鍵元件:

  • 一個私有的為容器映象準備的註冊中心
  • 當新的映象推送到註冊中心的時候重新部署容器
  • 簡便的容器擴容(在介面檢視上,可以通過滑動N 或M的方式調整容器大小)
  • 在Tutum的介面上新增節點


其他我們值得關注的元件:

  • 在對一個web應用容器縮放後,基於自省的方式的DNS動態解析。舉個例子,你的haproxy路由會自動發現新增容器並且新增到路由列表中。
  • 私有的網路覆蓋
  • 不再受不同雲供應商的限制,建立自己的節點


把所有東西組裝到一起

下面就挑乾貨說下我的實驗過程:

  • 宿主機使用Gitlab搭建的原始碼遠端倉庫
  • 宿主機使用Gitlab CI搭建的CI/CD引擎
  • RunAbove作為伺服器提供商對所有CI/CD執行引擎的容器託管④
  • Tutum 作為業務流程和服務的管理服務提供


當所有的事情結束,也組裝完畢,git的提交記錄活動圖,如下圖所示:

activity-flow-git-commit.png


部署Tutum 代理

正因為如此,我們事實上是使用Tutum去部署GitLab CI runners。我給你的建議是,先安裝Tutum agents。啟動所有你希望使用的服務,這樣在Tutum的儀表盤上就能看到Bring your own node 字樣的按鈕。點選它,你將會收到一個如下面所示的命令列:

curl -Ls https://get.tutum.co/ | sudo -H sh -s XXXXXXXXXXXXXXXXXXX


通常在某一個節點執行上述命令自動新增到你的Tutum賬戶,與此同時程式也會自動新增到其他節點(每次當你點選Bring your own node按鈕的時候)。

一旦Tutum agent安裝到你的所有節點上,你將會在儀表盤上看到它。在這一點上,你也許想給這個節點貼上適當的標籤。允許對應的伺服器在哪個節點上執行。舉個例子,你可能有一組節點標記為tagproduction目的是為了建立一套環境,亦或者是用來做持續整合的一個節點標記,這些只能在宿主機上執行。

你可以通過點選節點名稱來標記一個節點,新增的標記將會顯示在左側邊欄。

部署一個Gitlab CI 執行引擎

現在你可以通過Tutum來部署一個Gitlab CI執行引擎。然而,我們需要一種特殊型別的持續執行引擎——需要能夠在這個容器中執行Docker並且能夠構建我們自己的Docker映象。

你可能想,這怎麼可能呢?假如我們使用Tutum執行Gitlab CI 引擎,它只能執行在容器裡。那麼問題來了,如何在Docker容器裡執行Docker呢?

其實這完全可以做到。事實上,我們可以執行在你能想象到的更深層Docker中。我們的Docker容器架構如下圖所示:

dind-gitlab-ci-runner.png


正如你所看到的,在我們的節點的Docker容器裡Tutum執行GitLab CI引擎。此外,該GitLab CI引擎實際上使用Docker構建映象並執行測試,這意味著我們有兩個巢狀層次。

通過fork GitLab CI Runner,我已經建立了相應功能的分支。這樣就可以有效的跟蹤在github和官方Docker註冊中心的變更。

在建立你的GiLab CI runner前,確保你已經存在一個GitLab的例項倉庫,並且能夠同時執行GitLab CI引擎。正如前面提到的,你可以建立自己的例項,或者直接使用gitlab官方提供的免費託管倉庫和持續部署服務。

一旦你註冊了Gitlab倉庫。你所做的只需要通過點選連結你的Gitlab CI 賬號。在你關聯了Gitlab CI賬號之後,你將會通過Gitlab的儀表盤看到你的Gitlab倉庫列表,並且通過點選”Add project to CI” 按鈕來新增你的專案到Gitlab CI 引擎中。點選完畢後,你就會Gitlab的儀表盤上看到你新新增的專案資訊了。如下圖所示:

gitlab-ci-dashboard.png


如果你輕戳Gitlab的使用者介面,你將會注意到一個選單標題為“Runners”。在這個頁面有一個註冊標記,同時還有如何建立一個新的“Runner”的功能說明。在下面的例子中,我將會使用Tutum部署我們的Gitlab CI 映象。確定你已經複製了註冊標記和Gitlab CI的url地址——一會你將會用到他們。

在你的Tutum介面上,建立一個新的服務。在Tutum中服務的概念是一個Docker容器組,他們使用相同的軟體並執行著相同配置。

每個服務可以有零個或者多個容器在同一時間執行,並且Tutum將會管理你所有節點的協調和縮放工作。

在啟動向導的第一個介面,你將會看到幾個標籤,讓你選擇不同來源的Docker映象源。Tutum擁有一個內建的、私有的註冊中心,通過搜尋其他註冊中心同時支援一些具有特定功能的映象,當然這裡也包括Docker的官方映象。切換到“公共映象”選項卡,搜尋“wizardapps/dind-gitlab-ci-runner”映象,這就是我前面描述的在github上fork的GitLab CI 引擎原始碼倉庫中我自己建立的分支。

你一旦確定選擇了映象,你將會看到一個介面上面你對兩個容器之間排程的功能選項和一些基本配置,對於部署策略,雖然預設的設定也可以執行持續整合,但是我建議還是通讀下Tutum官方的說明文件.除非你想做平行構建,否則將容器數量設定為1。如果你先前已經對部署在Tutum的節點打了對應的標籤,請確保在“Delpoy Tags”輸入框輸入了正確的標籤名稱。從本質上講,Tutum會努力尋找所有滿足你要求“Delpoy Tags”中宣告的標籤,並且部署他們到一個節點。

下圖說明當你第一次必須要改動的一個重要的配置資訊,這是在“Advanced Options”部分的“Privileged Mode”選項,Docker需要選中這個選項,這樣保證Tutum可以很容易的獲得該資訊。

tutum-privileged-mode.png


在配置好私有模式後,你將會看到下一個螢幕-有關環境變數配置資訊。
像Docker命令列一樣,Tutum允許你宣告一個環境變數使之可以在你的Docker容器裡使用。

不僅如此,在Tutum中,每一個部署的容器都可以使用這個環境變數。儘管我們不會再Gitlab CI 引擎上使用link功能,我們使用的是Tutum提供的動態link,容器依然允許使用其他容器中的環境變數。

下面是三種需要設定的重要的環境變數:

  • REGISTRATION_TOKEN: 註冊資訊就是之前我們在Gilab CI 中拷貝的“Runner”。
  • CI_SERVER_URL:在Gitlab CI頁面上之前提供給我們的url地址,如果你使用的是官方提供的gitlab CI服務,直接填寫“https://ci.gitlab.com/”。
  • GITLAB_SERVER_FQDN:這裡宣告的是gitlab 的域名,這是用來執行一個ssh-keyscan。如果你用的是官方的託管服務,請填寫 “ci.gitlab.com”。


在配置完這些變數之後,終於可以“建立並部署”我們的服務了。

一旦你的容器啟動完畢, 你可以返回GitLab CI的“Runners”頁面並且你看到一個新的入口。現在你可以著手準備建立 GitLab CI 任務吧。

建立一個GitLab CI 任務

終於到最後一步了,我們在Gitlab CI 上新增一個實際的指令碼目的是建立一個 持續整合/持續部署的工作流。現在,這將取決於你的實際專案的種類,但大體方向應該是相同的,你會使用Docker映象來構建Docker容器,然後上傳到你的映象庫。在這種情況下,將會上傳到Tutum提供的私有映象庫。

在“工作”選項卡中,Gitlab CI工作可以進行修改。在這個部分,有兩個不同的子選項-“test”和“deploy”。正如他們名字所暗示的,測試指令碼通常用來執行單元和整合測試。部署指令碼只執行一旦測試完成後的特定分支。這樣就可以允許你在每次提交(commit)後執行你的測試指令碼,與此同時部署指令碼當且僅當所有測試全部通過的時候部署遠端master分支。

下面是指令碼例項:

docker login-u[USERNAME]-e[EMAIL]-p="[PASSWORD]"tutum.co

Build the Docker image and tag it for Tutum

docker build-twizardapps/app.
docker tag-fwizardapps/app tutum.co/wizardapps/app:latest

上面的測試指令碼並沒有實際執行任何測試,但是他確能為我們的應用程式構建Docker映象並打上對應的標籤。如果你在初始化階段使用自己的指令碼,請確保你的使用者、郵箱、密碼和Tutum上的註冊資訊報紙一致。因為Tutum提供的是一個私有Docker註冊中心,確保你的測試指令碼能通過相應的校驗⑤。

然後,我們還可以建立一個部署指令碼,實際上是推送我們的映象到Tutum的註冊中心,並開始構建。

docker push tutum.co/wizardapps/app


自動部署

到了這一步,你的系統應該已經構建成功並執行,新程式碼應該可以持續整合並上傳到Tutum的註冊中心。剩下的工作就是在Tutum上建立你自己的服務,確保重啟後還可以繼續使用。

這和我們建立Gitlab CI 服務類似,所不同的是我們讓服務“私有化”,我們只需要開啟“Auto Redeploy”開關即可。配置所有的服務埠,環境變數,連結和卷標,然後點選一下部署即可。

恭喜你,你現在已經擁有了只有在經過測試後,可以快速進行持續部署,自動化部署的Docker應用程式。

其他資源

GitLab CI Multi-Runner 地址: https://github.com/ayufan/gitlab-ci-multi-runner

我們通過在Tutum裡建立每個專案上都需要的持續整合 “服務”,可以很快上手。作為一種替代方案,你可以嘗試使用GitLab CI Multi-Runner,這個專案通過一個配置檔案允許多個專案同時進行構建。

①. 我有一些很酷的東西和大家分享,這就是ThreeBar——一個遠遠超出你想象的工具。一旦你做好準備加入,你將會發現Docker持續-部署-應用的強大功能。
②. Heroku 運營模式,您只需要按小時支付使用費。每一個“虛擬機器”執行你的程式碼被稱之為“Dyno”,你可以僅僅通過執行一個命令就可以做到一鍵部署,例如web伺服器或者其他請求佇列服務。你將會每個月獲得750小時的“Dyno”免費使用權。這意味著如果你願意的話可以在Heroku上執行一個免費的web伺服器。
③. 我個人使用了以下所有的伺服器提供商,我也通過部落格連結點選獲得了一些收入。但是,很可惜,任何一個伺服器提供商都不會允許你在建立你自己Docker服務並執行在Linux例項上。
④. RunAbove的沙箱是一個偉大的實驗,因為在它上面有大量的RAM,SSD儲存,並且花費極低——每月只有3美金在一個2G記憶體的伺服器上。儘管如此,在那個時候他們不被SAL所接受,因此你只能選擇其他的服務提供商。
⑤. 此時此刻,你必須把你的Tutum的賬號和密碼直接扔到指令碼中。很不幸的是,utum不提供這樣的單獨密碼登錄檔API,所以這個方案也因此留下一個潛在的安全漏洞。

原文連結:CI/CD with Docker Containers(翻譯:隋鑫 校對:魏小紅)

原文釋出時間為:2015-06-25
本文作者:jeffsui 
本文來自雲棲社群合作伙伴DockerOne,瞭解相關資訊可以關注DockerOne。
原文標題:通過Docker容器執行持續整合/持續部署


相關文章