av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

七張圖理解DockerfilesvsBuildpacks,二者如何選擇?

七張圖理解 Dockerfiles vs buildpacks,二者如何選擇?

作者:Michael Vittrup 2022-07-20 11:05:24

云計算

云原生 與腳本化 Dockerfile 相比,聲明式云原生 buildpack 支持一些新場景。

為企業(yè)提供網(wǎng)站制作、成都做網(wǎng)站、網(wǎng)站優(yōu)化、全網(wǎng)整合營銷推廣、競價托管、品牌運營等營銷獲客服務(wù)。創(chuàng)新互聯(lián)擁有網(wǎng)絡(luò)營銷運營團隊,以豐富的互聯(lián)網(wǎng)營銷經(jīng)驗助力企業(yè)精準獲客,真正落地解決中小企業(yè)營銷獲客難題,做到“讓獲客更簡單”。自創(chuàng)立至今,成功用技術(shù)實力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營銷”三大難題,同時降低了營銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認可!

與腳本化 Dockerfile 相比,聲明式云原生 buildpack 支持一些新場景。

容器無處不在

容器在大多數(shù)軟件交付管道中無處不在,有時不是直接可見的,但它們存在于幕后。無論我們是在 Kubernetes、普通 Docker 主機、serverless functions 還是許多其他編排平臺上運行軟件,容器都代表了不可變的可運行軟件工件。

將應(yīng)用程序源代碼轉(zhuǎn)換為正在運行的應(yīng)用程序需要一個中間容器構(gòu)建階段,而將軟件轉(zhuǎn)換為容器的一種非常流行的方法是通過 Dockerfile。

Dockerfiles

從 Dockerfile 構(gòu)建容器是一種腳本化方法,Dockerfile 中的大部分 內(nèi)容基本上是構(gòu)建軟件、安裝依賴項等所需的命令。這也意味著學(xué)習(xí)如何使用 Dockerfile 的學(xué)習(xí)曲線很淺,并且現(xiàn)有構(gòu)建腳本可以毫不費力地將其移植到 Dockerfile 中。

然而,事實證明,制作高質(zhì)量的容器鏡像并非易事?;ヂ?lián)網(wǎng)上充滿了制作小型、安全、最佳實踐鏡像的指南。通常圍繞:

  • 確保正確處理信號,例如SIGTERM是容器合約的一部分。
  • 不要使用 root 用戶運行應(yīng)用程序。
  • 不要在容器中包含不必要的工具、機密或構(gòu)建工件。
  • 按照優(yōu)化緩存的順序添加層,例如首先更改最少的層。
  • 正確標記和簽署鏡像。

下面說明了一個 Dockerfile,它為 NodeJS 應(yīng)用程序?qū)崿F(xiàn)了其中的一些建議;使用兩階段構(gòu)建生成一個小鏡像,以非 root 身份運行,并仔細排序操作以改進緩存:

FROM node:16.13.1-alpine3.14 AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY tsconfig.json .
COPY src src
RUN npm run build
RUN npm prune — production
FROM node:16.13.1-alpine3.14
WORKDIR /usr/src/app
USER node
ENV NODE_ENV production
COPY — from=builder /usr/src/app/node_modules/ ./node_modules
COPY — from=builder /usr/src/app/dist/ ./dist
EXPOSE 8000
CMD [ "node", "/usr/src/app/dist/main.js" ]

編寫高質(zhì)量的 Dockerfile 需要相當多的努力,有時 Dockerfile 通常只是其他項目的 Dockerfile 的副本。這會導(dǎo)致 Dockerfile 碎片化,對于擁有多個容器的組織來說,這很快就會變得難以管理。

Buildpacks

Buildpacks 源于這樣一種想法,即對于給定類型的大多數(shù)應(yīng)用程序,將應(yīng)用程序源代碼轉(zhuǎn)換為容器或多或少是相同的。這意味著我們可以為這個過程設(shè)計可重用的程序。這個概念自 Heroku 發(fā)起并被 Cloud Foundry、Google App engine、Gitlab、CircleCI 等采用以來,已經(jīng)發(fā)展超過 10 年。

社區(qū)努力確保它們提供高質(zhì)量的容器鏡像構(gòu)建,而不是為每個應(yīng)用程序使用碎片化 Dockerfiles,并具有不同級別的安全和最佳實踐。

構(gòu)建容器鏡像的聲明式方法

使用 buildpacks 時,我們需要了解 buildpacks 如何構(gòu)建容器。與其編寫腳本如何使用 Dockerfiles 構(gòu)建容器,不如聲明我們期望在容器中打包的內(nèi)容,并讓 buildpacks 找出細節(jié)。

Buildpacks 實現(xiàn)了許多階段,其中兩個是:

  • Detect:每個 buildpack 檢測它是否可以參與容器構(gòu)建。例如,對于 NodeJS 應(yīng)用程序,_npm_ buildpack 可能會查找package.json文件。如果找到,buildpack 將通知構(gòu)建器它可以參與構(gòu)建并貢獻依賴項。Python buildpack 會查找requirements.txt文件,但是,不會在 NodeJS 應(yīng)用程序中找到它,因此不會參與構(gòu)建。
  • Build:在這個階段,所有表明它們可以參與構(gòu)建的 Buildpacks 都將被執(zhí)行以實現(xiàn)構(gòu)建。如上所述,重要的是我們知道 Buildpacks 如何檢測應(yīng)該構(gòu)建的內(nèi)容。即 NodeJS 應(yīng)用程序的開發(fā)人員應(yīng)確保項目包含一個 package.json 文件。此外,如果我們期望某個版本的 Node 運行時或其他依賴項,則應(yīng)在 package.json 文件中明確說明,例如:
{
"engines": {
"node": "16.13.1",
"npm": "8.1.2"
},
"dependencies": {
"express": "4.17.2"
}
...
}

容器鏡像攜帶多種形式的元數(shù)據(jù),Buildpacks 通常使用環(huán)境變量來聲明元數(shù)據(jù)設(shè)置。以下是使用環(huán)境變量設(shè)置標準org.opencontainers.description標簽的示例,該標簽使用Paketo image-labels buildpack在容器鏡像上。環(huán)境變量的配置是通過 project.toml 文件完成的,這是聲明構(gòu)建配置的常用格式:

[[build.env]]
name = "BP_OCI_DESCRIPTION"
value = "Sample NodeJS from https://github.com/MichaelVL/buildpacks"

了解 Buildpacks 的這種聲明性 API 對開發(fā)人員來說是必不可少的。開發(fā)人員不應(yīng)該關(guān)心 Dockerfile,他們應(yīng)該知道 buildpacks 的聲明式 API。

可復(fù)制的構(gòu)建、交付鏈安全

Buildpacks 努力實現(xiàn)可重現(xiàn)的構(gòu)建。構(gòu)建過程是完全確定的,并且在使用相同的輸入執(zhí)行時會產(chǎn)生相同的輸出。這使我們能夠準確地驗證將哪個應(yīng)用程序二進制文件或源打包到容器中,并且可以保護軟件交付鏈免受惡意應(yīng)用程序被打包到容器中。

當使用 Dockerfiles 構(gòu)建鏡像時,容器鏡像(及其哈希值 sha256 摘要)在每次重建鏡像時都會發(fā)生變化,即使提供完全相同的輸入也是如此。

可重現(xiàn)的構(gòu)建是軟件工件供應(yīng)鏈級別第 4 級的要求,而 Buildpacks 是提高容器鏡像供應(yīng)鏈安全性的重要工具。

可重現(xiàn)的構(gòu)建也是一種避免不必要的容器層重建的有效機制。

改進的重建速度和緩存

Dockerfile 中的每一行基本上都會為最終的容器鏡像貢獻一層。除非先前的圖層發(fā)生更改,否則圖層會被緩存并重用。當前面的層更改時,所有后續(xù)層都將重新構(gòu)建和更改,因為 Docker 不應(yīng)用可重現(xiàn)的構(gòu)建。

使用 buildpacks,每個 buildpack 都會為容器鏡像貢獻一個層。如果 buildpack 的輸入沒有改變,則 buildpack 層不會改變,無論前面的層是否改變。此外,使用 buildpack 可以替換每個層,而不會影響其他 buildpack 生成的層。

如果需要更新容器基礎(chǔ)鏡像(例如由于安全問題),我們可以在容器鏡像中重新設(shè)置該層,而無需重建任何其他應(yīng)用程序?qū)?。這將很難使用基于 Dockerfile 的工作流來實現(xiàn)。

單層 rebase 不僅是容器鏡像構(gòu)建時間的顯著改進,而且對于容器的部署也是如此。想象一下有 10 個服務(wù)使用某個基礎(chǔ)鏡像。如果安全問題導(dǎo)致我們更新此基礎(chǔ)鏡像,則基于 Dockerfile 的構(gòu)建將導(dǎo)致重建所有鏡像的所有層。這會消耗構(gòu)建時間并下載完整的 10 個新鏡像。使用 buildpack rebase 方法,我們只需要檢索一個新的共享基礎(chǔ)鏡像。

容器已經(jīng) 42 歲了?

如果使用 buildpacks 構(gòu)建容器,您將遇到意想不到的時間戳:

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
sample-app latest 4713a8f7d9bb 42 years ago 202MB

這是可重現(xiàn)構(gòu)建的副作用。為了實現(xiàn)可重現(xiàn)的構(gòu)建,時間被凍結(jié)在一個固定點,以避免任何與時間相關(guān)的數(shù)據(jù)導(dǎo)致容器鏡像差異。Buildpacks 構(gòu)建具有1980 年 00:00:01 的時間戳來源的鏡像,這是為了與舊文件格式的兼容而選擇的。

使用 Buildpack 時的角色

當使用 buildpacks 構(gòu)建容器時,有兩個角色:

  • 應(yīng)用程序開發(fā)人員:開發(fā)人員的重點應(yīng)該是以應(yīng)用程序為中心,他們與容器構(gòu)建相關(guān)的主要職責是提供應(yīng)用程序源、依賴版本(例如 NodeJS 應(yīng)用程序的package.json)和應(yīng)用程序名稱和版本等元數(shù)據(jù)。對于構(gòu)建容器,他們將完全控制權(quán)委托給組織策劃的構(gòu)建器/Buildpacks。要將大多數(shù)問題委托給平臺運營商,開發(fā)人員應(yīng)該使用最新構(gòu)建器/Buildpacks,而不是修復(fù)構(gòu)建器版本。
  • 構(gòu)建平臺運營商:構(gòu)建平臺運營商的職責是為開發(fā)人員提供一個精選的構(gòu)建器和一組 Buildpacks,以申請構(gòu)建容器。這主要包括利用像Paketo buildpacks這樣的社區(qū)構(gòu)建器,但運營商可以選擇添加額外的,可能是自行設(shè)計的 buildpacks 用于公司特定目的。這可以是例如添加與公司相關(guān)的元數(shù)據(jù)。構(gòu)建平臺運營商的主要關(guān)注點還在于:容器運行鏡像(容器基礎(chǔ)鏡像)的更新和安全性。

這種關(guān)注點分離對于維護多個容器鏡像的組織非常有價值,因為這允許平臺構(gòu)建操作員控制容器鏡像。例如,如果在運行鏡像中發(fā)現(xiàn)安全問題,則可以通過更改構(gòu)建器運行鏡像,使用新的運行鏡像重建所有容器。如上所述,這將是一個非常有效的層變基。使用 Dockerfile,這將需要更新所有應(yīng)用程序 Dockerfile 中的基礎(chǔ)鏡像,并會觸發(fā)所有容器鏡像層的重建。

容器里有什么軟件材料清單

buildpacks 增強 Dockerfile 構(gòu)建過程的一個示例是如何將構(gòu)建相關(guān)的元數(shù)據(jù)附加到容器鏡像。軟件項目包含許多依賴項,并且有關(guān)這些依賴項的信息在鏡像構(gòu)建期間嵌入到容器鏡像中。

軟件物料清單 (SBOM) 是進入容器鏡像的組件的結(jié)構(gòu)化列表。這可用于通過將 SBOM 與已知安全問題進行比較,來確保僅使用安全軟件。SBOM 還可用于驗證哪個軟件許可證管理軟件等。CycloneDX和SPDX是結(jié)構(gòu)化 SBOM 數(shù)據(jù)的兩個通用標準。

下面是來自 NodeJS 項目的 SBOM 的摘錄,我們可以從 SBOM 中看到所使用的 Node 引擎的確切版本,以及提供它的 buildpack:

{
{
"name": "Node Engine",
"metadata": {
"source": {
"checksum": {
"hash": "34b23965457fb0587cda6fa898e5d030211f5f374cb6"
},
"uri": "https://nodejs.org/.../node-v16.13.1.tar.gz"
},
"version": "16.13.1"
},
"buildpacks": {
"id": "paketo-buildpacks/node-engine",
"version": "0.11.2"
}
}
}

使用 SBOM 來保護軟件是對使用容器鏡像掃描儀的有力補充。由于 SBOM 是由 buildpacks 創(chuàng)建的,因此它將精確且清楚地識別交付鏈。容器鏡像掃描儀將不得不從容器的實際內(nèi)容中扣除這個版本,這將不太精確。

如何使用 Buildpacks?

使用云原生 Buildpacks,構(gòu)建過程和 Buildpacks 包含在兩個容器鏡像中:一個構(gòu)建器鏡像和一個運行鏡像。在某種程度上,它可以被看作是一個改進的 Dockerfile 兩階段構(gòu)建。下圖說明了兩階段 Dockerfile 構(gòu)建如何映射到 Buildpacks。請注意 NodeJS 應(yīng)用程序的構(gòu)建邏輯如何映射到buildpack(通常這種應(yīng)用程序構(gòu)建將分布在多個 buildpack 中)

構(gòu)建器鏡像包含一組有序的 Buildpacks 構(gòu)建事物的邏輯、一個生命周期組件 Buildpacks 的編排器和對運行鏡像的引用。Dockerfile 與生命周期組件沒有并行性,因為 Dockerfile 是線性處理的。在檢測階段,Buildpacks 將選擇加入或退出構(gòu)建,生命周期組件對此進行管理。

最后,需要一個工具來觸發(fā)生命周期組件:非常類似于 docker build 命令。為此,存在許多工具,其中最廣為人知的是 pack 和 Tekton,然而,像 CircleCI 和 Gitlab 這樣的商業(yè)持續(xù)集成供應(yīng)商也支持使用 buildpacks 進行構(gòu)建。

可以在此處找到使用pack 的 Github actions 工作流示例。

結(jié)論

雖然經(jīng)驗豐富的 Dockerfile 作者在從 Dockerfiles 遷移到 buildpacks 時可能會感到失去了對細節(jié)的控制,但上面概述的優(yōu)勢有望意味著使用 buildpacks 時會以開放的心態(tài)來對待。我相信大多數(shù)開發(fā)人員都會喜歡 buildpacks。構(gòu)建容器和維護 Dockerfile 從來不是他們的主要關(guān)注點,而是部署應(yīng)用程序所需的必要步驟。構(gòu)建平臺操作員、SRE 和安全團隊應(yīng)該喜歡 buildpacks,因為它恢復(fù)了對容器鏡像和容器鏡像中內(nèi)置工件的控制。

用云原生 buildpack 替換 Dockerfile 會改變我們構(gòu)建容器鏡像的方式:

對于開發(fā)人員和組織而言,重點關(guān)注聲明性部分很重要。學(xué)習(xí)如何聲明容器應(yīng)該如何構(gòu)建以及正在構(gòu)建什么將是最重要的。

buildpacks 完美嗎?

不完全是。在寫這篇文章時,我嘗試復(fù)制一開始提出的兩階段 Dockerfile 的精益容器構(gòu)建,但是,這并不完全可行(使用 Paketo 構(gòu)建器)生成的容器的大小要大一些。但是,我預(yù)計 buildpacks 會在未來改進。

還有一些應(yīng)用程序很難用 buildpacks 打包到容器中。例如,如果沒有自定義 Buildpacks,打包在容器(VM 風格的容器)中的遺留單體應(yīng)用程序?qū)㈦y以實現(xiàn)。此類應(yīng)用程序不能很好地與 buildpacks 配合使用,并且可能需要對 Dockerfile 進行低級控制,這些應(yīng)用程序可能是容器打包應(yīng)該注意的問題。


標題名稱:七張圖理解DockerfilesvsBuildpacks,二者如何選擇?
當前網(wǎng)址:http://uogjgqi.cn/article/cdipieo.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流