使用云原生buildpacks将你的代码转换成Docker Image | 技术干货
戳藍字“CSDN云計算”關注我們哦!
技術頭條:干貨、簡潔、多維全面。更多云計算精華知識盡在眼前,get要點、solve難題,統統不在話下!
?
七年前buildpack技術開源之時,我們就看到了這項技術將大大簡化應用的發布過程。當開發人員要跑一個 :git push heroku master的時候,buildpack就可以保證所有依賴以及編譯工作都會作為發布的一部分被全權打理好。
一如之前所宣布,我們正在將buildpacks成功的哲學理論運用到創立云原生buildpacks(CNB)之中,一種再也不需要dockerfile并將源代碼轉換為Docker?Image的標準。簡單地看一下CNB?是如何工作的,它是如何旨在解決許多現存于dockerfile上的問題, 以及如何以將它和最近發布的 buildpacks.io 項目 beta版本一起使用。作為這次發布的一部分,我們已經給 Ruby, Node.js, Java, Python, PHP, 以及Go建立好后可以使用CNB?工具的Heroku buildpacks builder image。
?
我們先從創造一個稻草人(假設模型)開始。通過一些比較冗長無聊但卻很根本且必須的步驟來創建一個Ruby?on Rails 應用的Dockerfile。
?
抽象泄露:遞增地來寫一個Dockerfile
?
大多開發者以寫一個dockerfile?來使用Docker,這個file會定義整個生成Docker?image的build流程。比如說, 你手里有一個的Rails?項目,并且你希望將它以一個Docker?Container來發布。你會需要從一個基本的Ruby?Image?開始, 將其他額外需要的包加入進來,以此來讓你的應用跑起來。如果你從未用過Docker,你可能要先學幾樣東西才能到這一步。
FROM ruby
RUN apt-get update -qq \
??&& apt-get install -y nodejs libpq-dev build-essential
COPY . /app
WORKDIR /app
RUN bundle install
RUN bundle exec rake assets:precompile
EXPOSE 5000
CMD bin/rails s
??
除了Ruby以外,一個Rails應用的Docker?image?也將會需要幾個額外的 Apt包。要想跑用來預編譯assets的必須要的工具, node js ?的runtime一定要被包含在其中;為了要和PostgreSQL 交流, libpq-dev也是需要的;以及為了讓gcc能夠給Ruby?gems?們build原生的插件(一個Ruby包管理器,類似Python的 pip),我們還會需要到build-essential。
?
一個Dockerfile?已經足夠用來在生產環境跑一個簡單的Rails應用,但是整個image會充滿很多非相關的緩存文件夾。你或許會想去掉那些文件,以縮減整個image大小,但這只會對本地有序性build有用。
RUN apt-get update -qq \
??&& apt-get install -y nodejs libpq-dev build-essential \
??&& apt-get clean autoclean && apt-get autoremove -y \
??&& rm -rf /var/lib/apt /var/lib/dpkg /var/lib/cache /var/lib/log
# ..
RUN bundle exec rake assets:precompile
??&& rm -rf /app/tmp/cache/assets/
?
這便突出了使用Dockerfile在速度上的短板。 它并不能適當利用那些緩存目錄,只因為一次rebuild就會要把整個image從頭build。然而,我們可以利用些聰明的小技巧來緩存依賴(dependency)的信息來加速builds。相比較每次復制整個應用,你可以如下選擇性地加入文件。
ADD Gemfile /app/
ADD Gemfile.lock ?/app/
RUN bundle install
?
復制加入Gemfile?和Gemfile.lock 可以用來取代dockerfile的緩存機制,以此來防止因為僅你更改了一行代碼而導致所有的緩存失效。
?
這些例子僅強調出了“幾個” 當使用Dockerfile構建應用時的挑戰和難點。而且你會在每次使用Dockerfile構建應用時都會重復遇見這些困難。多數情況下,最后你都會復制粘貼某個應用Dockerfile?的一部分到另外一個應用的Dockerfile,而這種行為會潛在地造成維護人員噩夢。
?
維護,是Dockerfile最大的短板。除了復制粘貼代碼,它給你帶來了一些如果你不使用Dockerfile是絕對不會關心的低等級問題。舉例來說,和很多其他編程語言一樣,Ruby有很多基本image?可以給你用來繼承使用,而且每個image都有自己的大小和安全性考量。如果有一天,Rails的生態系統系要一個新的依賴(dependency),而這個新的依賴并不存在于你現有的Dockerfile,那你就要負責根據需要更新相關的設置。如果你把你的項目分拆成多個“微服務”(microservices),同時也意味著你需要在多個位置更新你的文件。
最終來說,Dockerfile是個具有漏洞性的抽象概念。它強制開發者們要小心運作上,以及平臺的需要注意點,而在這之前這些需要注意點都已經被平臺抽象打理了。要想寫出一個好的Dockerfile,你就必須理解底層機制,以及產生image的每一步是如何工作的并以此來打理未來的更新。
所有的這些問題都源于Dockerfile缺少對應用的相對了解。如果沒有你的應用相關或所使用架構的上下文相關信息,開發者如何開發和他們使用的工具就會產生巨大的不匹配現象。
像這樣將運行和應用的關注點混合在一起就相當于給了一個希望盡量容易去寫代碼以及運輸代碼的開發者一個非常差的工具?;诖祟惒蛔阒?#xff0c;我們接下來看一下另外一種可以減少此類復雜度的替代辦法。
向Buildpacks學習
如果你曾經使用Heroku來發布你的應用你就會知道,這就像在本地跑一個 git?push?heroku?master?一樣容易。而在幕后,一個 buildpack?就會收集依賴(retrieve?dependencies),運行數據信息,打理緩存,并且給你的應用語言編譯代碼。舉例來說,有一個Rails?應用。Ruby的buildpack就會安裝Ruby和 bundler(一個Ruby的依賴管理應用)。你的gem(一系列包和文件的總稱)依賴會被提取出來,你的資源代碼會被編譯,而且緩存也會被清理干凈:
git push heroku master
remote: Compressing source files... done.
remote: Building source:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.0
remote: -----> Installing dependencies using bundler 1.15.2
remote: ???????Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
...
remote: ???????Bundle complete! 18 Gemfile dependencies, 61 gems now installed.
remote: ???????Gems in the groups development and test were not installed.
remote: ???????Bundled gems are installed into `./vendor/bundle`
remote: ???????Removing bundler (1.15.2)
remote: ???????Bundle completed (42.62s)
remote: ???????Cleaning up the bundler cache.
...
remote: ???????Asset precompilation completed (3.72s)
remote: ???????Cleaning assets
remote: ???????Running: rake assets:clean
remote: -----> Detecting rails configuration
remote: -----> Compressing...
remote: ???????Done: 41.3M
remote: -----> Launching...
remote: ???????Released v6
remote: ???????https://myapp.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
??
一個Buildpack以識別你應用代碼語言的行為慣例幫你自動處理了這些步驟。Builpacks的設計原則就是就是安裝并設置所有需要的設置以幫你達到運行你的應用的目的。站在云原生Buildpacks的角度來說,我們希望利用Docker和現代container標準,有一個相似的系統來讓我們的開發者更加注重于他們的應用,而不是拼湊一個build管道。
?
運行云原生Buildpacks
因為希望能夠將 Buildpacks?的簡潔性和可用性與container的優勢結合起來,我們開發了云原生Buildpacks(CNB),它可以產出一個 “開放容器計劃”兼容(OCI-Compliant)image, 并且這個image可以使用現存 的Docker?工具,以及更廣闊的現存容器生態系統。
Buildpacks.io項目是一個讓我們愿景成可能的開源工具之家。其中,第一個工具便是 pack?build,其行為和git?push heroku master非常相似。你可以在任意資源庫下產生一個Docker?image。以下便是一個在Rails應用上跑的Heroku云原生buildpack的例子。
?
和buildpack產生可執行的壓縮文件(slug)很相似, 一個CNB會根據你現有項目的文件識別什么東西需要被安裝。你不需要進行任何配置來識別確認你的應用的需求。因為buildpack?是應用感知的(app-aware),它能夠精準地捕捉到你所使用的編程語言以及你應用的所需依賴,在build階段也同樣會有著合理的系統默認值來處理內存的使用和處理并發。
?
CNB?進程在產生最后image的進行的步驟和現存Heroku?Buildpacks運作的不同階段非常相似:
·?CLI 偵測到你的項目使用的主要語言。比如說,如果你的源代碼目錄下有一個Gemfile,那么CNB就會將它識別為一個Ruby項目;如果有個pom.xml那么它就會被識別為一個Java項目,以此類推。
·?之后,執行環境會分析之前的build來確認其中是否有任何步驟可以在接下來build中使用。
·?CNB開始跑build,下載所需的依賴以及將應用準備好可以在production當中運行。
·?最后,它會將以上build的結果以Docker?image的形式導出。
?
產出一個image的底層幕后進程全權被buildpack所打理。如果這個進程需要被更新-比如有個漏洞被檢測到-你可以很輕松地獲取一個新的工具鏈并且用 pack?rebase重新build一個image來更新你的image而不用從頭開始build一個image, 整個過程花費不到一秒鐘。和用Dockerfile在你每一個應用上rebuild相比(一個可能耗費幾個小時的過程),這會節省大量的時間。
?
現在就來試一下云原生Buildpacks吧!
?
再也沒有比現在更好的時機來嘗試一下云原生Buildpacks(CNB)了。這個項目剛剛出了它第一個beta?版本, 它已經準備好被你使用,也希望到你的反饋!
如何開始呢?先下載 pack CLI?并且在你的應用源代碼目錄下使用我們任一buildpack(Ruby,??Node.js, Java, Python, PHP, Go)。
?
$ pack build --builder heroku/buildpacks <docker image name>
來Slack上加入我們!如果你還想生成你自己的OCI?Images,我們還有定義了使用細則的buildpack API文檔?。
Heroku 一直以來都認為切合開發者的關注和需求是非常重要的:即他們應用的源代碼。我們相信云原生Buildpacks?會因為以建立了基于容器的應用而幫助減少在運行維護上的復雜度,從而解放了開發者雙手來專注于給他們的用戶創作更多優秀的的功能和特性。?
?
福利
掃描添加小編微信,備注“姓名+公司職位”,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
推薦閱讀:
如何快速深入理解監控知識? | 技術干貨
為什么說深耕AI領域繞不開知識圖譜?
ARM 發布新一代 CPU 和 GPU,實現 20% 性能提升!
比特幣沖到9000美元, 你就能找個好工作?
1000 萬個“AI 名師”:用機器算法“解剖”應試教育
阿里面試,我掛在了第四輪……
10個爬蟲工程師必備的工具了解一下
真香,朕在看了!
總結
以上是生活随笔為你收集整理的使用云原生buildpacks将你的代码转换成Docker Image | 技术干货的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: boost的chrono模块操作时钟对象
- 下一篇: boost的chrono模块最小时间点的