成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

云計(jì)算 云原生
與腳本化 Dockerfile 相比,聲明式云原生 buildpack 支持一些新場(chǎng)景。

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

容器無(wú)處不在

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

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

圖片

Dockerfiles

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

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

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

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

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" ]

編寫(xiě)高質(zhì)量的 Dockerfile 需要相當(dāng)多的努力,有時(shí) Dockerfile 通常只是其他項(xiàng)目的 Dockerfile 的副本。這會(huì)導(dǎo)致 Dockerfile 碎片化,對(duì)于擁有多個(gè)容器的組織來(lái)說(shuō),這很快就會(huì)變得難以管理。

Buildpacks

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

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

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

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

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

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

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

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

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

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

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

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

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

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

改進(jìn)的重建速度和緩存

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

使用 buildpacks,每個(gè) buildpack 都會(huì)為容器鏡像貢獻(xiàn)一個(gè)層。如果 buildpack 的輸入沒(méi)有改變,則 buildpack 層不會(huì)改變,無(wú)論前面的層是否改變。此外,使用 buildpack 可以替換每個(gè)層,而不會(huì)影響其他 buildpack 生成的層。

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

圖片

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

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

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

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

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

使用 Buildpack 時(shí)的角色

當(dāng)使用 buildpacks 構(gòu)建容器時(shí),有兩個(gè)角色:

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

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

圖片

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

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

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

下面是來(lái)自 NodeJS 項(xiàng)目的 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 來(lái)保護(hù)軟件是對(duì)使用容器鏡像掃描儀的有力補(bǔ)充。由于 SBOM 是由 buildpacks 創(chuàng)建的,因此它將精確且清楚地識(shí)別交付鏈。容器鏡像掃描儀將不得不從容器的實(shí)際內(nèi)容中扣除這個(gè)版本,這將不太精確。

如何使用 Buildpacks?

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

圖片

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

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

圖片

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

結(jié)論

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

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

圖片

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

buildpacks 完美嗎?

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

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

責(zé)任編輯:趙寧寧 來(lái)源: 進(jìn)擊云原生
相關(guān)推薦

2020-11-25 14:40:48

機(jī)器學(xué)習(xí)人工智能微分方程

2015-07-13 10:23:23

Java圖解

2022-08-25 11:38:38

GolangDockerfile

2022-05-09 11:15:05

RocketMQPULL 模式PUSH 模式

2021-04-21 12:05:45

分析數(shù)據(jù)運(yùn)營(yíng)

2022-07-29 16:28:19

Kubernetes通信服務(wù)通信

2021-11-29 07:47:56

RocketMQ分布式消息

2025-05-08 07:38:36

模型上下文協(xié)議MCPAI模型

2021-05-27 11:30:54

SynchronizeJava代碼

2022-02-28 11:10:42

ZGCG1收集器

2021-08-11 22:05:26

加密貨幣比特幣數(shù)字貨幣

2024-08-30 08:51:17

MavenGradleJava

2024-08-01 20:08:17

2017-03-03 15:04:19

2024-07-03 08:28:44

HWKafkaLEO

2021-04-25 10:45:59

Docker架構(gòu)Job

2022-07-11 11:06:11

RocketMQ函數(shù).消費(fèi)端

2012-08-15 09:47:05

服務(wù)器虛擬化

2009-02-21 16:21:16

2023-04-11 08:35:22

RocketMQ云原生
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 免费在线观看一区二区三区 | 日本中文字幕一区 | 91传媒在线观看 | 久久久夜 | 成人一区av偷拍 | 91.色| 日韩精品视频在线 | 黄色网址大全在线观看 | 青青操91 | 成人国产精品免费观看 | 久久激情视频 | 国产美女精品视频 | 爱爱综合网 | 九九色综合 | 粉嫩粉嫩芽的虎白女18在线视频 | 欧美二区三区 | 亚洲国产一区二区在线 | 伊人看片| 亚洲精品视频三区 | 青青久草 | 精品国产一区二区三区四区在线 | 日韩欧美在线视频观看 | 久久精品播放 | 九九热在线免费视频 | 国产特级毛片aaaaaa | 亚洲一av | 国产区精品 | 欧美一级淫片免费视频黄 | 午夜丁香视频在线观看 | 亚洲一区二区精品视频 | 犬夜叉在线观看 | av国产在线观看 | 国产最好的av国产大片 | 波多野结衣中文字幕一区二区三区 | 99免费在线观看 | 手机在线不卡av | 看亚洲a级一级毛片 | 在线毛片网 | 欧美伊人久久久久久久久影院 | 国产精品日女人 | 日韩成人在线视频 |