摘要:接下來(lái),我們來(lái)看一個(gè)更酷的工作流程,即通過(guò)引入來(lái)實(shí)現(xiàn)項(xiàng)目的持續(xù)集成。是一個(gè)持續(xù)集成發(fā)布平臺(tái),支持對(duì)容器進(jìn)行測(cè)試。取消對(duì)的選中狀態(tài)。
借助Docker,我們可以更容易地進(jìn)行web應(yīng)用部署,而同時(shí)不必頭疼于項(xiàng)目依賴(lài)、環(huán)境變量以及各種配置問(wèn)題,Docker可以快捷、高效地處理好這一切。
而這也是本教程所要實(shí)現(xiàn)的主要目的。
首先我們來(lái)學(xué)習(xí)使用Docker容器運(yùn)行一個(gè)Python Flask應(yīng)用,然后逐步介紹一套更酷的開(kāi)發(fā)流程,其中涵蓋了應(yīng)用的持續(xù)集成與發(fā)布…
我(Michael Herman)最初是在2015年2月8日的PyTennessee上介紹了這一工作流程,如果感興趣的話,你可以直接瀏覽我當(dāng)時(shí)使用的幻燈片。
流程在本地功能分支上完成應(yīng)用代碼。2. 在Github上發(fā)起一個(gè)到master分支的Pull Request。3. 在Docker容器上運(yùn)行自動(dòng)測(cè)試。4. 如果測(cè)試通過(guò),手動(dòng)將這個(gè)PR merge進(jìn)master分支。5. 一旦merge成功,再次運(yùn)行自動(dòng)測(cè)試。6. 如果第二次測(cè)試也通過(guò),就在Docker Hub上對(duì)應(yīng)用進(jìn)行構(gòu)建。7. 一旦構(gòu)建完成,自動(dòng)化地部署到生產(chǎn)環(huán)境。
本教程基于Mac OS X,在開(kāi)始前需要保證以下工具已正確安裝配置:Python v2.7.9, Flask v0.10.1, Docker v1.4.1, Docker Compose, v1.0.0, boot2docker 1.4.1, Redis v2.8.19
好了,讓我們開(kāi)始吧。
首先來(lái)介紹一些Docker中的基本概念:
Dockerfile中包括了一系列語(yǔ)句,用于對(duì)鏡像的行為進(jìn)行描述。
鏡像是一個(gè)模板,用來(lái)保存環(huán)境狀態(tài)并創(chuàng)建容器。
容器可以理解為實(shí)例化的鏡像,并會(huì)在其中運(yùn)行一系列進(jìn)程。
如果對(duì)Dockerfile、鏡像和容器的具體細(xì)節(jié)感興趣,那么可以從Docker的官方文檔獲取更多詳細(xì)信息。
為什么是Docker?使用Docker意味著你能在開(kāi)發(fā)機(jī)上完美地模擬生產(chǎn)環(huán)境,而不用再為任何由兩者環(huán)境、配置差異所造成的問(wèn)題而擔(dān)心,除此之外Docker帶給我們的還有:
良好的版本控制。2. 隨時(shí)便捷地發(fā)布/重建整個(gè)開(kāi)發(fā)環(huán)境。3. 一次構(gòu)建,隨處運(yùn)行,就是這么神奇!
配置Docker由于Darwin(OS X內(nèi)核)缺少運(yùn)行Docker容器的一些Linux內(nèi)核功能,所以我們需要借助boot2docker,一個(gè)用于運(yùn)行Docker的輕量級(jí)Linux發(fā)行版(啟動(dòng)一個(gè)專(zhuān)門(mén)為運(yùn)行Docker定制過(guò)的小型虛擬機(jī))。
首先為我們的Flask項(xiàng)目創(chuàng)建一個(gè)名為“fitter-happier-docker”的目錄。
接下來(lái)遵照官方文檔的步驟來(lái)完成Docker和boot2docker的安裝。
我們可以通過(guò)以下命令來(lái)驗(yàn)證安裝是否正確:
$ boot2docker version
Boot2Docker-cli version: v1.4.1
Git commit: 43241cb
Docker Compose是官方提供的容器業(yè)務(wù)流程框架(譯注:曾經(jīng)的項(xiàng)目名稱(chēng)是Fig,甚至在本譯文的初稿時(shí)依然是,進(jìn)化速度之快可見(jiàn)一斑),只需通過(guò)簡(jiǎn)單的.yml配置文件,就能完成多個(gè)容器服務(wù)的構(gòu)建和運(yùn)行。
使用pip來(lái)安裝Docker Compose,并通過(guò)如下命令來(lái)確認(rèn)安裝正確:
$ pip install docker-compose $ docker-compose --version docker-compose 1.1.0
現(xiàn)在來(lái)啟動(dòng)我們的Flask+Redis應(yīng)用(你可以從這個(gè)repo來(lái)獲取項(xiàng)目的全部源代碼),首先在項(xiàng)目根目錄下新建docker-compose.yml文件:
web: build: web volumes: - web:/code ports: - "80:5000" links: - redis command: python app.py redis: image: redis:2.8.19 ports: - "6379:6379"
可以看到我們對(duì)項(xiàng)目所含兩個(gè)服務(wù)進(jìn)行的操作:
web:我們將在web目錄下進(jìn)行容器的構(gòu)建,并且將其作為Volume掛載到容器的/code目錄中,然后通過(guò)python app.py來(lái)啟動(dòng)Flask應(yīng)用。最后將容器的5000端口暴露出來(lái),并將其映射到主機(jī)的80端口上。2. redis:我們直接使用Docker Hub上的官方鏡像來(lái)提供所需的Redis服務(wù)支持,將6379端口暴露并映射到主機(jī)上。
你一定注意到了位于web目錄下的Dockerfile文件,它用于指導(dǎo)Docker如何構(gòu)建我們的應(yīng)用鏡像(基于Ubuntu),并且保證了完備的依賴(lài)支持。
構(gòu)建并運(yùn)行接下來(lái)只需要一行簡(jiǎn)單命令,就能輕松搞定一切(鏡像的構(gòu)建及容器的啟動(dòng)運(yùn)行):
Ubuntu $ docker-compose up
這會(huì)根據(jù)Dockerfile來(lái)構(gòu)建Flask應(yīng)用的鏡像,從官方倉(cāng)庫(kù)拉取Redis鏡像,然后將一切運(yùn)行起來(lái)。
現(xiàn)在你可以去喝一杯咖啡,呃,也許是兩杯:首次運(yùn)行會(huì)花費(fèi)相對(duì)較長(zhǎng)的時(shí)間,事實(shí)上Docker會(huì)在構(gòu)建過(guò)程中,將Dockerfile中的每一步操作(更正式的說(shuō)法應(yīng)該是layer)緩存下來(lái),以后的構(gòu)建過(guò)程會(huì)因此提速很多,因?yàn)橹挥邪l(fā)生改變的步驟才會(huì)被重新執(zhí)行。
Docker Compose會(huì)并行地啟動(dòng)全部容器,每個(gè)容器都會(huì)被分配各自的名字,并且會(huì)為日志設(shè)置可讀性更高的配色方案。
好了,那么準(zhǔn)備好來(lái)測(cè)試了嗎?
打開(kāi)你的瀏覽器,輸入主機(jī)DOCKER_HOST環(huán)境變量所對(duì)應(yīng)的IP地址,例如在我這里是 http://192.168.59.103/ (運(yùn)行boot2docker ip命令可以查詢到IP地址)。
接下來(lái)你應(yīng)該會(huì)在瀏覽器中看到以下文本“Hello! This page has been seen 1 times.”:
刷新頁(yè)面,如果一切正常的話,計(jì)數(shù)器變量應(yīng)該會(huì)進(jìn)行累加。
通過(guò)Ctrl-C來(lái)終止我們的應(yīng)用進(jìn)程,然后通過(guò)以下命令讓其改為在后臺(tái)運(yùn)行:
$ docker-compose up -d
想查看應(yīng)用進(jìn)程的運(yùn)行狀態(tài)?只需要輸入以下命令就可以了:
$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------------------- fitterhappierdocker_redis_1 /entrypoint.sh redis-server Up 0.0.0.0:6379->6379/tcp fitterhappierdocker_web_1 python app.py Up 0.0.0.0:80->5000/tcp, 80/tcp
可以看到我們的兩個(gè)進(jìn)程運(yùn)行在不同的容器中,而Docker Compose將它們組織在一起!
更進(jìn)一步在確定一切正常無(wú)誤后,使用docker-compose stop命令來(lái)終止我們的應(yīng)用,然后通過(guò)boot2docker down來(lái)安全地關(guān)閉虛擬機(jī)。接下來(lái)就可以向Git提交本地修改,并推送到Github了。
那么,我們剛才都完成了什么呢?
我們建立了本地環(huán)境,通過(guò)Dockerfile詳盡描述了如何構(gòu)建鏡像,并基于該鏡像啟動(dòng)了相應(yīng)容器。我們使用Docker Compose來(lái)將這一切整合起來(lái),包括構(gòu)建和容器之間的關(guān)聯(lián)、通信(在Flask和Redis進(jìn)程之間)。
接下來(lái),我們來(lái)看一個(gè)更酷的工作流程,即通過(guò)引入CircleCI來(lái)實(shí)現(xiàn)項(xiàng)目的持續(xù)集成。
同樣的,你可以從此處獲取源代碼。
Docker Hub到目前為止我們已經(jīng)接觸過(guò)Dockerfile、鏡像以及容器(當(dāng)然,借助了Docker Compose的幫助)。
如果你很熟悉Git的工作流程,那么可以把Docker鏡像理解為Git的repo,而容器類(lèi)似于該repo的clone,如果將這個(gè)比喻繼續(xù)類(lèi)推下去,那么Docker Hub也就相當(dāng)于Github的地位了。
為了使用Docker Hub,你可以用Github賬號(hào)來(lái)完成注冊(cè)。2. 添加一個(gè)新的自動(dòng)構(gòu)建,將剛才完成的項(xiàng)目repo加入進(jìn)來(lái),一切按照默認(rèn)選項(xiàng)即可,除了將“Dockerfile Location”改為“/web”。
一旦添加完畢,Docker Hub會(huì)進(jìn)行一次初始化構(gòu)建,請(qǐng)確保一切正常。
Docker Hub和CIDocker Hub自身通過(guò)配置就可以充當(dāng)持續(xù)集成服務(wù),從而在每次推送Git提交后自動(dòng)進(jìn)行構(gòu)建。
這意味著你不能直接將鏡像推送到(通過(guò)docker push)Docker Hub上。Docker Hub會(huì)自己從repo進(jìn)行拉取并構(gòu)建鏡像,從而保證整個(gè)過(guò)程中沒(méi)有錯(cuò)誤。在你的工作流程中請(qǐng)銘記這一點(diǎn),因?yàn)樵贒ocker文檔中目前并沒(méi)有對(duì)此進(jìn)行詳細(xì)說(shuō)明。
讓我們來(lái)試一下,加入以下測(cè)試用例:
self.assertNotEqual(four, 5)
提交并推送到Github,然后就可以看到Docker Hub如何開(kāi)始一次新構(gòu)建了。
由于這是項(xiàng)目部署上線前的最后一道防線,我們當(dāng)然希望Docker Hub在構(gòu)建完成之前,能夠捕獲所有的錯(cuò)誤和異常。另外,你肯定也希望能將自己的單元測(cè)試和集成測(cè)試加入到持續(xù)集成流程中, 而這正是CircleCI的用武之地。
CircleCICircleCI是一個(gè)持續(xù)集成/發(fā)布平臺(tái),支持對(duì)Docker容器進(jìn)行測(cè)試。你只需提供一個(gè)Dockerfile,CircleCI會(huì)據(jù)此構(gòu)建鏡像,并啟動(dòng)一個(gè)新容器,然后在其中運(yùn)行你的測(cè)試。
還記得我們期望的工作流程嗎?鏈接
現(xiàn)在來(lái)看看如何完成它。
安裝CIrcleCI官方提供了很好的入門(mén)指導(dǎo)。
使用Github賬號(hào)完成注冊(cè),然后將你的Github repo添加為一個(gè)新項(xiàng)目(成功后會(huì)收到郵件通知)。這會(huì)為該repo增加一個(gè)hook,每當(dāng)你向其推送新的提交時(shí),都會(huì)觸發(fā)一次新的構(gòu)建。
接下來(lái)需要向我們的repo添加一個(gè)配置文件,用以指導(dǎo)CircleCI完成構(gòu)建。
circle.yml的文件內(nèi)容如下:
machine: services: - docker dependencies: override: - pip install -r requirements.txt test: override: - docker-compose run -d --no-deps web - python web/tests.py
實(shí)際上,我們構(gòu)建了一個(gè)新的鏡像,并啟動(dòng)了一個(gè)新容器,然后進(jìn)行測(cè)試:首先檢查web應(yīng)用是否正常啟動(dòng)運(yùn)行,然后逐一進(jìn)行單元測(cè)試。
你應(yīng)該已經(jīng)注意到我們?cè)谶@里使用了命令docker-compose run -d --no-deps web而不是docker-compose up來(lái)啟動(dòng)應(yīng)用,這是因?yàn)镃ircleCI已經(jīng)集成了可用的Redis運(yùn)行時(shí)環(huán)境,所以我們只需啟動(dòng)web應(yīng)用進(jìn)程就可以了。
當(dāng)circle.yml文件修改完成,就可以推送到Github來(lái)啟動(dòng)一次新構(gòu)建了。記住,這將同時(shí)在Docker Hub上啟動(dòng)一次構(gòu)建。
一切正常?
在繼續(xù)下去之前,需要對(duì)工作流程進(jìn)行一些調(diào)整,因?yàn)槲覀兺ǔ2幌M麑⑻峤恢苯油扑偷絤aster分支上。
功能分支工作流程如果不太熟悉這一工作流程,那么可以從此處獲得準(zhǔn)確生動(dòng)的解釋。
讓我們來(lái)快速瀏覽一個(gè)示例:
創(chuàng)建功能分支$ git checkout -b circle-test master Switched to a new branch "circle-test"
更新應(yīng)用
并在texts.py里增加一個(gè)新的斷言:
self.assertNotEqual(four, 6)
發(fā)起一個(gè)Pull Request
$ git add web/tests.py $ git commit -m "circle-test" $ git push origin circle-test
甚至在你真正發(fā)起PR之前,CircleCI就已經(jīng)啟動(dòng)了構(gòu)建。在PR創(chuàng)建完畢后,只需等待CircleCI通過(guò)所有測(cè)試,我們就可以點(diǎn)擊Merge按鈕來(lái)合并入master分支了。一旦merge成功,Docker Hub就會(huì)觸發(fā)相應(yīng)的構(gòu)建過(guò)程。
重構(gòu)工作流程如果回到本文開(kāi)頭的工作流程處,你會(huì)發(fā)現(xiàn)我們實(shí)際上希望Docker Hub在master分支上再次進(jìn)行測(cè)試后才啟動(dòng)構(gòu)建,所以讓我們來(lái)對(duì)現(xiàn)有流程進(jìn)行以一些快速的調(diào)整:
打開(kāi)你的Docker Hub倉(cāng)庫(kù),在Settings下選擇Automated Build。2. 取消對(duì)“When active we will build when new pushes occur”的選中狀態(tài)。3. 保存。4. 選擇位于Settings下的Build Triggers。5. 將status改為on。6. 復(fù)制以下curl命令:$ curl --data "build=true" -X POST https://registry.hub.docker.com/u/mjhea0/fitter-happier-docker/trigger/84957124-2b85-410d-b602-b48193853b66/
將以下代碼加入到circle.yml文件末尾:
deployment: hub: branch: master commands: - $DEPLOY
現(xiàn)在我們會(huì)在merge到master分支并通過(guò)測(cè)試之后,執(zhí)行$DEPLOY環(huán)境變量所代表的命令,我們需要將這個(gè)變量的值加入到CircleCi的環(huán)境變量中:
打開(kāi) Project Settings,選擇 Environment variables。2. 添加一個(gè)名為“Deploy”的新變量,并且將剛才復(fù)制的curl命令粘貼進(jìn)去作為該變量的值。
現(xiàn)在來(lái)檢驗(yàn)一下成果:
$ git add circle.yml $ git commit -m "circle-test" $ git push origin circle-test
發(fā)起一個(gè)新的PR,一旦其通過(guò)CirecleCI測(cè)試,將其merge到master分支,這會(huì)觸發(fā)另一次構(gòu)建。一旦再次通過(guò)測(cè)試,之前設(shè)置的curl命令就會(huì)觸發(fā)Docker Hub去啟動(dòng)一次新構(gòu)建,一切都很完美。
結(jié)論我們已經(jīng)跑通了這個(gè)基于CircleCI的持續(xù)集成工作流程(步驟1-6):
在本地功能分支上完成應(yīng)用代碼。2. 在Github上發(fā)起一個(gè)到master分支的Pull Request。3. 在Docker容器上運(yùn)行自動(dòng)測(cè)試。4. 如果測(cè)試通過(guò),手動(dòng)將這個(gè)PR merge進(jìn)master分支。5. 一旦merge成功,再次運(yùn)行自動(dòng)測(cè)試。6. 如果第二次測(cè)試也通過(guò),就在Docker Hub上對(duì)應(yīng)用進(jìn)行構(gòu)建。7. 一旦構(gòu)建完成,自動(dòng)化地部署到生產(chǎn)環(huán)境。
關(guān)于整個(gè)流程的最后一塊拼圖呢:及自動(dòng)化地將應(yīng)用發(fā)布到盛傳環(huán)境(第7步),你可以在我的另一篇博客中得到答案。
翻譯自:https://realpython.com/blog/python/docker-in-action-fitter-happier-more-productive/
譯者:李明(armyiljfe@gmail.com,https://github.com/hydRAnger )
原文:Docker實(shí)戰(zhàn):更輕松、更愉快、更高效
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/26381.html
摘要:分層存儲(chǔ)因?yàn)殓R像包含操作系統(tǒng)完整的文件系統(tǒng),其體積往往是龐大的,因此在設(shè)計(jì)時(shí),就充分利用的技術(shù),將其設(shè)計(jì)為分層存儲(chǔ)的架構(gòu)。分層存儲(chǔ)的特征還使得鏡像的復(fù)用定制變的更為容易。 什么是Docker Docker 是一個(gè)開(kāi)源的應(yīng)用容器引擎,基于 Go 語(yǔ)言 并遵從Apache2.0協(xié)議開(kāi)源。Docker 可以讓開(kāi)發(fā)者打包他們的應(yīng)用以及依賴(lài)包到一個(gè)輕量級(jí)、可移植的容器中,然后發(fā)布到任何流行的 L...
摘要:同樣地,也有命令可以刪除掛起的鏡像網(wǎng)絡(luò)和。命令提供整體磁盤(pán)使用率的概況,包括鏡像容器和本地。因此這條命令比命令更局限。鏡像新的鏡像命令也是子命令。筆者最?lèi)?ài)的命令莫過(guò)于,讓環(huán)境一直保持干凈整齊。 Docker 1.13出來(lái)已經(jīng)有一段時(shí)間了,新版本添加了許多有用的命令,本文作者從處女座的潔癖(此處有霧)出發(fā),告訴大家一些整理環(huán)境的小技巧。打掃房間再也不需費(fèi)時(shí)又費(fèi)力了,簡(jiǎn)單的命令,就可以輕松...
摘要:云幫能解決什么問(wèn)題新一代企業(yè)平臺(tái)讓開(kāi)發(fā)人員輕松地開(kāi)發(fā)部署和運(yùn)維應(yīng)用,讓架構(gòu)師和運(yùn)營(yíng)人員利用熟知和可靠技術(shù)打造一個(gè)受控的運(yùn)行環(huán)境。有助于加速企業(yè)級(jí)應(yīng)用服務(wù)于市場(chǎng),實(shí)現(xiàn)內(nèi)部資源的有效利用。 云幫是什么? 云幫 是一款基于容器技術(shù)的應(yīng)用管理平臺(tái)。社區(qū)版針對(duì)個(gè)人、企業(yè)完全免費(fèi),您可以自由的下載與傳播,但需要遵循我們的社區(qū)版協(xié)議。 云幫從哪里來(lái)? 云幫是 北京好雨科技有限公司 結(jié)合容器技術(shù)整合的...
摘要:整體基于的開(kāi)發(fā),通過(guò)反代對(duì)外提供服務(wù),之前通過(guò)配置,已經(jīng)支持了協(xié)議,但是目前還不支持協(xié)議,于是只能想別的辦法。經(jīng)過(guò)一番谷歌再次感謝偉大的谷歌以后,發(fā)現(xiàn)了,一個(gè)新一代的服務(wù)器。目前對(duì)的支持還處于實(shí)驗(yàn)性質(zhì),所以要開(kāi)啟,要加上標(biāo)志。 最近HTTP-over-QUIC 協(xié)議被正式命名為 HTTP/3,協(xié)議帶來(lái)的最大改變是協(xié)議底層將采用UDP協(xié)議,而不再是TCP協(xié)議,這樣的好處嗎,就是更低時(shí)延,...
閱讀 1009·2021-09-27 13:36
閱讀 1055·2021-09-08 09:35
閱讀 1142·2021-08-12 13:25
閱讀 1501·2019-08-29 16:52
閱讀 2989·2019-08-29 15:12
閱讀 2792·2019-08-29 14:17
閱讀 2693·2019-08-26 13:57
閱讀 1073·2019-08-26 13:51