使用Docker,Chef和Amazon OpsWorks进行集群范围的Java / Scala应用程序部署
Docker非常適合在單個(gè)節(jié)點(diǎn)上運(yùn)行隔離的容器。 但是,大多數(shù)軟件系統(tǒng)都在多個(gè)節(jié)點(diǎn)上運(yùn)行,因此,除了Docker之外,我們還需要某種方法來(lái)指定哪些容器應(yīng)在哪些節(jié)點(diǎn)上運(yùn)行。
我要解決的特定問題如下:我有兩個(gè)Scala守護(hù)程序,我想在多個(gè)節(jié)點(diǎn)上運(yùn)行(取決于配置,每個(gè)節(jié)點(diǎn)可以運(yùn)行一個(gè)或兩個(gè)守護(hù)程序)。 我想要一種在集群中部署修改后的二進(jìn)制文件的快速方法。 我也不想花費(fèi)太多時(shí)間來(lái)設(shè)置服務(wù)器。 (我的Gentoo日子已經(jīng)過去了。)
我到達(dá)的最終解決方案涉及Docker , OpsWorks , Chef和Vagrant 。 但是,一步一步來(lái)。
順便說一句-您將如何解決上述問題? 請(qǐng)?jiān)u論。
打包Java / Scala應(yīng)用程序
首先,我需要能夠打包和上傳二進(jìn)制文件。 在這里,Docker非常完美。 我編寫了一個(gè)簡(jiǎn)單的Dockerfile ,其中:
- 基于受信任的ubuntu + java7映像–無(wú)需在服務(wù)器上安裝Java!
- 將胖子從我的磁盤復(fù)制到映像
- 指定使用復(fù)制的jar運(yùn)行Java的入口點(diǎn)
完整的Dockerfile可以在這里找到: https ://gist.github.com/adamw/166b82ec04c9c0f67453。
有了這樣的映像,我可以將其推送到(公共或私有) Docker注冊(cè)表中 ,群集中的節(jié)點(diǎn)可以將其下載。
如果需要,我還可以安裝我的應(yīng)用程序需要的任何其他操作系統(tǒng)級(jí)別的依賴項(xiàng),而不必?fù)?dān)心版本沖突并在實(shí)際服務(wù)器上進(jìn)行設(shè)置。
如果看一下Dockerfile,您可能會(huì)注意到有兩個(gè)jar。 這樣做是為了最小化每次代碼更改后必須上傳的Docker映像的大小。 第一個(gè)jar僅包含依賴項(xiàng)(Scala庫(kù),日志記錄庫(kù),框架等)。 第二個(gè)jar包含已編譯的應(yīng)用程序代碼。 從Dockerfile構(gòu)建Docker映像時(shí),將創(chuàng)建一系列中間映像,每個(gè)步驟之后一個(gè)。 對(duì)于涉及相同文件的相同命令,不會(huì)創(chuàng)建新映像,但會(huì)從Docker緩存中重新使用映像。
依賴關(guān)系很少更改,因此通常dep-jar保持不變,因此緩存的版本會(huì)被重用(并且中間映像會(huì)上傳一次)。 另一方面,應(yīng)用程序代碼始終會(huì)更改。 重要的是,首先將依賴項(xiàng)jar添加到映像,以便中間映像包含deps,但不包含應(yīng)用程序代碼(更改后的代碼)。 最后,通常只需要上傳2-3MB。
不過,這里要注意一件事。 在確定是否可以在ADD命令(該命令將文件從本地磁盤復(fù)制到該映像)之后重新使用該映像時(shí),Docker僅檢查該文件的最后修改時(shí)間戳。 這將導(dǎo)致依賴項(xiàng)fat-jar在每次重新構(gòu)建時(shí)都被重新添加,即使它們是相同的。 因此,我創(chuàng)建了一個(gè)簡(jiǎn)單的bash腳本,僅當(dāng)其md5校驗(yàn)和發(fā)生更改時(shí),該腳本才會(huì)復(fù)制dockerfile旁邊的fat-jar(作為Docker上下文的一部分從該文件上傳): https : //gist.github.com/adamw/ ba5d8b79ff553fba83fd 。
如何用SBT創(chuàng)建這樣兩個(gè)單獨(dú)的jar? 非常簡(jiǎn)單。 只需使用SBT Assembly插件并更改其設(shè)置即可:
assemblyOption in assembly ~= { _.copy(includeBin = true, includeScala = false, includeDependency = false) }然后, assemblyPackageDependency目標(biāo)將創(chuàng)建僅依賴項(xiàng)的jar,而assembly將創(chuàng)建僅應(yīng)用程序的jar。
設(shè)置服務(wù)器
隨著包含我們應(yīng)用程序的Docker映像在云中(在Docker集線器上)等待,現(xiàn)在是時(shí)候設(shè)置服務(wù)器了,Docker守護(hù)程序?qū)⒃谄渲羞\(yùn)行容器。
為了配置服務(wù)器,我選擇了Amazon OpsWorks的Chef,這有兩個(gè)原因:可以使用Stacks和Layers清楚地分離和組織EC2實(shí)例,這些服務(wù)器與Chef具有現(xiàn)成的集成,并且使用自定義廚師食譜非常容易。 完全不需要手動(dòng)實(shí)例設(shè)置!
以下步驟部分是摘要,部分是ShopIgniter博客上描述的內(nèi)容的擴(kuò)展。
Chef安裝程序(由OpsWorks運(yùn)行)將是最少的,并且僅包含運(yùn)行Docker所需的內(nèi)容。
首先,我們需要?jiǎng)?chuàng)建一個(gè)具有更新內(nèi)核的基于Ubuntu 12.04的AMI(14.04尚不能與OpsWorks配合使用)–有關(guān)詳細(xì)信息,請(qǐng)參閱ShopIgniter的博客。
其次,我們將使用自定義的廚師食譜; 為此,您需要?jiǎng)?chuàng)建一個(gè)專用的存儲(chǔ)庫(kù)(例如在GitHub上)。 食譜非常基本和簡(jiǎn)單: https : //gist.github.com/adamw/792f8c22abb09699b6d5 。
總結(jié)一下:
- docker::setup安裝Docker
- docker::kill_containers殺死并刪除所有正在運(yùn)行的容器
- docker::myapp從Docker注冊(cè)表中提取myapp映像并運(yùn)行一個(gè)容器,該容器具有例如Chef-JSON配置文件的每個(gè)應(yīng)用程序部分中指定的命令行參數(shù)和環(huán)境變量(此處我們的應(yīng)用程序使用單個(gè)命令-line參數(shù),并且需要環(huán)境中的AWS憑證):
配置OpsWorks
要配置OpsWorks,我們需要使用自定義Chef食譜和自定義配置JSON創(chuàng)建一個(gè)Stack,例如上面的示例(對(duì)于要運(yùn)行的每個(gè)應(yīng)用程序/容器類型,我們需要在配置JSON中有一個(gè)部分)。 其次,對(duì)于我們要部署的每個(gè)應(yīng)用程序(容器),我們需要?jiǎng)?chuàng)建一個(gè)圖層。 由于這些層將僅運(yùn)行Docker,因此我們不使用任何預(yù)先配置的層,而使用“自定義”層。
該層將包含我們的自定義配方:在Setup階段,我們需要使用docker::setup配方,在Deploy階段,我們需要使用docker::kill_containers和docker::kill_containers docker::myapp配方。
現(xiàn)在,每次在該層上運(yùn)行Deploy階段時(shí),Docker都會(huì)提取映像并運(yùn)行指定的容器! 通過創(chuàng)建具有適當(dāng)配方的圖層,我們可以在任何節(jié)點(diǎn)上啟動(dòng)容器的任何組合。
運(yùn)行部署階段
要一次單擊即可實(shí)際運(yùn)行“ Deploy階段,我們需要?jiǎng)?chuàng)建一個(gè)虛擬的OpsWorks應(yīng)用程序:只需選擇“類型:其他”和“存儲(chǔ)庫(kù)類型:其他”。 現(xiàn)在,每次要在服務(wù)器上部署應(yīng)用程序(運(yùn)行更新的Docker容器)時(shí),只需將此虛擬應(yīng)用程序部署在所需的實(shí)例或?qū)由霞纯伞?
這也可以通過API調(diào)用來(lái)完成(就像AWS上的一切一樣)! 因此,構(gòu)建應(yīng)用程序,創(chuàng)建Docker映像,推送該映像以及在OpsWorks上運(yùn)行部署的整個(gè)過程可以非常容易地實(shí)現(xiàn)自動(dòng)化-例如在成功構(gòu)建之后。
一切就緒后,我們現(xiàn)在可以將新實(shí)例添加到圖層,啟動(dòng)和停止它們,并讓多節(jié)點(diǎn)集群運(yùn)行我們的應(yīng)用程序! 要更新應(yīng)用程序,只需將二進(jìn)制文件推送到注冊(cè)表即可。
在本地測(cè)試廚師
雖然Chef的食譜非常少,但仍然可以在本地對(duì)其進(jìn)行測(cè)試仍然很有用。 使用Vagrant可以輕松實(shí)現(xiàn)。 使用Vagrant,我們可以輕松地創(chuàng)建安裝了Chef的VM,該VM可以運(yùn)行我們的配方,從而可以運(yùn)行Docker容器。 此特定情況的Vagrantfile在這里: https ://gist.github.com/adamw/bf6fa803b6b13fd7430b。
Vagrantfile包含對(duì)我們正在開發(fā)的Chef食譜的引用(通過chef.cookbooks_path ),并且具有與我們?cè)贠psWorks中使用的相同的配置JSON。
發(fā)布vagrant up ,我們將運(yùn)行虛擬機(jī)。 更改食譜或上載新容器后,我們可以通過使用vagrant provision --provision-with chef_solo輕松地重新運(yùn)行Chef食譜。
加起來(lái)
我們最終得到以下關(guān)注點(diǎn)分離:
- Docker-在隔離的容器中運(yùn)行應(yīng)用程序,具有所有必需的依賴項(xiàng)
- Chef –在定義的節(jié)點(diǎn)上設(shè)置docker,運(yùn)行并鏈接具有指定參數(shù)/環(huán)境的容器
- OpsWorks –管理實(shí)例,觸發(fā)部署
- 流浪漢–整個(gè)設(shè)置的本地測(cè)試
盡管在上述整個(gè)過程中肯定有一些事情需要簡(jiǎn)化(我希望Atomic項(xiàng)目能夠做到這一點(diǎn)!)最后,在集群中輕松地部署新版本的修改后的應(yīng)用程序非常容易,而且很輕松,開發(fā)環(huán)境。
翻譯自: https://www.javacodegeeks.com/2014/06/cluster-wide-javascala-application-deployments-with-docker-chef-and-amazon-opsworks.html
總結(jié)
以上是生活随笔為你收集整理的使用Docker,Chef和Amazon OpsWorks进行集群范围的Java / Scala应用程序部署的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 下头了是什么意思梗 下头了是啥意思梗
- 下一篇: Java SE 8新特性导览:使用Lam