<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          是時(shí)候跟Docker說(shuō)再見(jiàn)了

          共 7834字,需瀏覽 16分鐘

           ·

          2021-01-13 17:35


          作者 | Martin Heinz

          譯者 | 王者
          策劃 | Tina
          原文鏈接:https://towardsdatascience.com/its-time-to-say-goodbye-to-docker-5cfec8eff833

          在容器的遠(yuǎn)古時(shí)代 (差不多就是 4 年前),Docker 是這場(chǎng)游戲的唯一玩家。但現(xiàn)在情況已經(jīng)不一樣了,Docker 不再是唯一玩家,而只是一個(gè)容器引擎而已。我們可以用 Docker 構(gòu)建、運(yùn)行、拉取、推送或檢查容器鏡像,但對(duì)于這里的每一項(xiàng)任務(wù),都有其他可替代的工具,它們可能比 Docker 做得更好。所以,讓我們來(lái)探究一下它們,然后卸載和忘掉 Docker……

          為什么說(shuō)不要用 Docker 了?

          如果你已經(jīng)使用 Docker 很長(zhǎng)時(shí)間了,那么要說(shuō)服你考慮使用其他的工具可能需要費(fèi)點(diǎn)唇舌。

          首先,Docker 是一個(gè)整體性的工具,它試圖做所有的事情,但這通常不是最好的方法。大多數(shù)情況下,選擇一種專(zhuān)門(mén)的工具會(huì)更好,它可能只做一件事,但會(huì)做到最好。

          如果你害怕使用不同的工具,可能是因?yàn)槟阋獙W(xué)習(xí)使用不同的 CLI、不同的 API 或接受不同的概念。不過(guò)請(qǐng)放心,選擇本文介紹的工具都是完全無(wú)縫銜接的,因?yàn)樗鼈?(包括 Docker) 都遵循 OCI (Open Container Initiative) 規(guī)范。OCI 包含了容器運(yùn)行時(shí)、容器分發(fā)和容器鏡像的規(guī)范,涵蓋了使用容器所需的所有特性。

          多虧了 OCI,你可以選擇一套最適合自己的工具,同時(shí)又能夠繼續(xù)使用與 Docker 一樣的 API 和 CLI 命令。

          所以,如果你愿意嘗試新的工具,那么就讓我們來(lái)比較一下 Docker 和其他工具的優(yōu)缺點(diǎn)和特性,看看是否有必要考慮放棄 Docker,并轉(zhuǎn)向其他一些新的工具。

          容器引擎

          在比較 Docker 和其他工具時(shí),我們需要將其分解為組件,首先我們要討論的是容器引擎。容器引擎是一種工具,它為處理鏡像和容器提供了用戶(hù)界面,這樣你就不需要處理 SECCOMP 規(guī)則或 SELinux 策略之類(lèi)的事情。它的工作還包括從遠(yuǎn)程存儲(chǔ)庫(kù)提取鏡像并將其解壓到磁盤(pán)。它似乎也運(yùn)行容器,但實(shí)際上它的工作是創(chuàng)建容器清單和包含了鏡像層的目錄。然后它將它們傳到容器運(yùn)行時(shí),例如使用 runc 或 crun(稍后我們將討論這個(gè))。

          目前有很多可用的容器引擎,不過(guò) Docker 最突出的競(jìng)爭(zhēng)對(duì)手是由 Red Hat 開(kāi)發(fā)的 Podman。與 Docker 不同,Podman 不需要守護(hù)進(jìn)程,也不需要 root 特權(quán),這是 Docker 長(zhǎng)期以來(lái)一直存在的問(wèn)題。從它的名字就可以看出來(lái),Podman 不僅可以運(yùn)行容器,還可以運(yùn)行 Pod。Pod 是 Kubernetes 的最小計(jì)算單元,由一個(gè)或多個(gè)容器 (主容器和所謂的邊車(chē)) 組成,Podman 用戶(hù)在以后可以更容易地將他們的工作負(fù)載遷移到 Kubernetes。以下演示了如何在一個(gè) Pod 中運(yùn)行兩個(gè)容器:

          ~ $ podman pod create --name mypod~ $ podman pod listPOD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID211eaecd307b mypod Running 2 minutes ago 1 a901868616a5~ $ podman run -d --pod mypod nginx # First container~ $ podman run -d --pod mypod nginx # Second container~ $ podman ps -a --podCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD POD NAME3b27d9eaa35c docker.io/library/nginx:latest nginx -g daemon o... 2 seconds ago Up 1 second ago brave_ritchie211eaecd307b mypodd638ac011412 docker.io/library/nginx:latest nginx -g daemon o... 5 minutes ago Up 5 minutes ago cool_albattani211eaecd307b mypoda901868616a5 k8s.gcr.io/pause:3.2 6 minutes ago Up 5 minutes ago 211eaecd307b-infra 211eaecd307b mypod
          Podman 提供了與 Docker 完全相同的 CLI 命令,因此你只需執(zhí)行 alias Docker=Podman,然后就像什么都沒(méi)有發(fā)生改變一樣。

          除了 Docker 和 Podman 之外,還有其他容器引擎,但我認(rèn)為它們沒(méi)有出路或者都不適合用于本地開(kāi)發(fā)。不過(guò)如果你想要對(duì)容器引擎有一個(gè)較為完整的了解,我們可以列出一些:

          • LXD——是 LXC (Linux 容器) 的容器管理器 (守護(hù)進(jìn)程)。這個(gè)工具提供了運(yùn)行系統(tǒng)容器的能力,這些系統(tǒng)容器提供了類(lèi)似于 VM 的容器環(huán)境。它比較小眾,沒(méi)有很多用戶(hù),所以除非你有特定的用例,否則最好使用 Docker 或 Podman。

          • CRI-O——如果你在網(wǎng)上搜索 cri-o 是什么東西,你可能會(huì)發(fā)現(xiàn)它被描述為一種容器引擎。不過(guò),它實(shí)際上是一種容器運(yùn)行時(shí)。除了不是容器引擎之外,它也不適合用于“一般”的情況。我的意思是,它是專(zhuān)門(mén)為 Kubernetes 運(yùn)行時(shí) (CRI) 而構(gòu)建的,并不是給最終用戶(hù)使用的。

          • rkt——rkt(“rocket”) 是由 CoreOS 開(kāi)發(fā)的容器引擎。這里提到這個(gè)項(xiàng)目只是為了清單的完整性,因?yàn)檫@個(gè)項(xiàng)目已經(jīng)結(jié)束了,它的開(kāi)發(fā)也停止了——因此它不應(yīng)該再被使用。

          鏡像的構(gòu)建

          從容器引擎方面來(lái)說(shuō),除了 Docker 之外只有一種選擇。但是,在構(gòu)建鏡像方面,我們有很多選擇。

          首先是 Buildah(https://buildah.io)。Buildah 是 Red Hat 開(kāi)發(fā)的一款工具,可以很好地與 Podman 配合使用。如果你已經(jīng)安裝了 Podman,可能會(huì)注意到 podman build 子命令,它實(shí)際上是經(jīng)過(guò)包裝的 Buildah。

          在特性方面,Buildah 遵循了與 Podman 相同的路線——它是無(wú)守護(hù)進(jìn)程的,可以生成符合 OCI 的像,并保證以相同的方式來(lái)運(yùn)行使用 Docker 構(gòu)建的鏡像。它還能基于 Dockerfile 或 Containerfile(它們實(shí)際上是同一個(gè)東西,只是叫法不一樣)構(gòu)建鏡像。除此之外,Buildah 還提供了對(duì)鏡像層更精細(xì)的控制,支持提交大量的變更到單個(gè)層。在我看來(lái),它與 Docker 之間有一個(gè)出乎人意料的區(qū)別,使用 Buildah 構(gòu)建的鏡像是特定于用戶(hù)的,因此你可以只列出自己構(gòu)建的鏡像。

          你可能會(huì)問(wèn),既然 Buildah 已經(jīng)被包含在 Podman CLI 中,為什么還要使用單獨(dú)的 Buildah CLI?buildah CLI 是 podman build 所包含的命令的超集,你可能不需要使用 buildah CLI,但是通過(guò)使用它,你可能會(huì)發(fā)現(xiàn)一些額外有用的特性?(有關(guān) podman build 和 buildah 之間的差異的細(xì)節(jié),請(qǐng)參考 https://podman.io/blogs/2018/10/31/podman-buildah-relationship.html)。

          我們來(lái)看看一個(gè)小演示:

          ~ $ buildah bud -f Dockerfile .~ $ buildah from alpine:latest  # Create starting container - equivalent to "FROM alpine:latest"
          Getting image source signatures
          Copying blob df20fa9351a1 done
          Copying config a24bb40132 done
          Writing manifest to image destination
          Storing signatures
          alpine-working-container # Name of the temporary container
          ~ $ buildah run alpine-working-container -- apk add --update --no-cache python3 # equivalent to "RUN apk add --update --no-cache python3"


          fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz


          fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz


          ...


          ~ $ buildah commit alpine-working-container my-final-image # Create final image
          Getting image source signatures
          Copying blob 50644c29ef5a skipped: already exists
          Copying blob 362b9ae56246 done
          Copying config 1ff90ec2e2 done
          Writing manifest to image destination
          Storing signatures
          1ff90ec2e26e7c0a6b45b2c62901956d0eda138fa6093d8cbb29a88f6b95124c
          ~ # buildah images
          REPOSITORY TAG IMAGE ID CREATED SIZE
          localhost/my-final-image latest 1ff90ec2e26e 22 seconds ago 51.4 MB

          從上面的腳本可以看到,你可以直接使用 buildah bud 構(gòu)建鏡像,其中 bud 表示使用 Dockerfile 來(lái)構(gòu)建鏡像,你也可以使用其他更多的命令,如 from、run 和 copy,它們分別對(duì)應(yīng) Dockerfile 中的 FROM、RUN、COPY。

          第二個(gè)工具是谷歌的 Kaniko

          (https://github.com/GoogleContainerTools/kaniko)。Kaniko 也基于 Dockerfile 構(gòu)建容器鏡像,而且與 Buildah 類(lèi)似,它也不需要守護(hù)進(jìn)程。與 Buildah 的主要區(qū)別在于,Kaniko 更專(zhuān)注于在 Kubernetes 中構(gòu)建鏡像。

          Kaniko 本身是作為鏡像 (gcr.io/kaniko-project/executor) 運(yùn)行的,這對(duì)于 Kubernetes 來(lái)說(shuō)是沒(méi)有問(wèn)題,但對(duì)于本地構(gòu)建來(lái)說(shuō)不是很方便,并且在某種程度上違背了構(gòu)建鏡像的目的,因?yàn)槟阈枰褂?Docker 來(lái)運(yùn)行 Kaniko 鏡像來(lái)構(gòu)建鏡像。如果你正在尋找在 Kubernetes 集群中構(gòu)建鏡像的工具 (例如在 CI/CD 管道中),那么 Kaniko 可能是一個(gè)不錯(cuò)的選擇,因?yàn)樗菬o(wú)守護(hù)進(jìn)程的,而且 (可能) 更安全。

          從我個(gè)人的經(jīng)驗(yàn)來(lái)看——我在 Kubernetes/OpenShift 集群中使用了 Kaniko 和 Buildah 來(lái)構(gòu)建鏡像,我認(rèn)為兩者都能很好地完成任務(wù),但在使用 Kaniko 時(shí)會(huì)隨機(jī)出現(xiàn)構(gòu)建故障,在將鏡像推送到注冊(cè)表時(shí)也會(huì)隨機(jī)地出現(xiàn)失敗的情況。

          第三個(gè)是 buildkit(https://github.com/moby/buildkit),也可以稱(chēng)之為下一代 docker build。它是 Moby 項(xiàng)目的一部分,在運(yùn)行 Docker 時(shí)通過(guò) DOCKER_BUILDKIT=1 docker build 就可以啟用它,作為 Docker 的一個(gè)實(shí)驗(yàn)性特性。那么,這到底會(huì)給你帶來(lái)什么呢?它帶來(lái)了很多改進(jìn)和很酷的特性,包括并行構(gòu)建步驟、跳過(guò)未使用的階段、更好的增量構(gòu)建和無(wú)根構(gòu)建。但是,它仍然需要運(yùn)行守護(hù)進(jìn)程 (buildkitd)。所以,如果你不想擺脫 Docker,同時(shí)又想要一些新的特性和更好的改進(jìn),那么使用 buildkit 可能是最好的選擇。

          跟之前的章節(jié)一樣,這里也將提及一些工具,它們滿(mǎn)足了一些特定的使用場(chǎng)景,但并不是我的首選:

          • Source-To-Image (S2I,https://github.com/openshift/source-to-image) 是一個(gè)不使用 Dockerfile 直接從源代碼構(gòu)建鏡像的工具包。這個(gè)工具在簡(jiǎn)單可預(yù)期的場(chǎng)景和工作流中表現(xiàn)良好,但如果你需要多一些定制化,或者你的項(xiàng)目沒(méi)有預(yù)期的結(jié)構(gòu),那么它就會(huì)變得煩人和笨拙。如果你對(duì) Docker 還不是很有信心,或者如果你在 OpenShift 集群上構(gòu)建鏡像,可能可以考慮使用 S2I,因?yàn)槭褂?S2I 構(gòu)建鏡像是它的一個(gè)內(nèi)置特性。

          • Jib(https://github.com/GoogleContainerTools/jib)是谷歌開(kāi)發(fā)的一款工具,專(zhuān)門(mén)用于構(gòu)建 Java 鏡像。它提供了 Maven 和 Gradle 插件,可以讓你輕松地構(gòu)建鏡像,不需要理會(huì) Dockerfile。

          • 最后一個(gè)是 Bazel(https://github.com/bazelbuild/bazel),它是谷歌的另一款工具。它不僅用于構(gòu)建容器鏡像,而且是一個(gè)完整的構(gòu)建系統(tǒng)。如果你只是想構(gòu)建鏡像,那么使用 Bazel 可能有點(diǎn)大材小用,但這絕對(duì)是一個(gè)很好的學(xué)習(xí)體驗(yàn),所以如果你愿意,可以將 rules_docker

            (https://github.com/bazelbuild/rules_docker) 為入手點(diǎn)。

          容器運(yùn)行時(shí)

          最后一個(gè)是負(fù)責(zé)運(yùn)行容器的容器運(yùn)行時(shí)。容器運(yùn)行時(shí)是整個(gè)容器生命周期的一部分,除非你對(duì)速度、安全性等有一些非常具體的要求,否則你很可能不會(huì)對(duì)其加以干擾。所以,如果你已經(jīng)感到厭倦了,可以跳過(guò)這一部分。但是,如果你想知道有哪些可選擇的容器運(yùn)行時(shí),可以看看以下這些:

          runc(https://github.com/opencontainers/runc)是符合 OCI 容器運(yùn)行時(shí)規(guī)范的容器運(yùn)行時(shí)。Docker(通過(guò) containerd)、Podman 和 CRI-O 都在使用它,它是 (幾乎) 所有東西的默認(rèn)配置,所以即使你在閱讀本文后放棄使用 Docker,很可能仍然會(huì)使用 runc。

          runc 的另一種替代品是 crun(https://github.com/containers/crun)。這是 Red Hat 開(kāi)發(fā)的一款工具,完全用 C 語(yǔ)言開(kāi)發(fā) (runc 是用 Go 開(kāi)發(fā)的),所以它比 runc 更快,內(nèi)存效率更高。因?yàn)樗彩羌嫒?OCI 的運(yùn)行時(shí),所以你應(yīng)該可以很容易上手。盡管它現(xiàn)在還不是很流行,但作為 RHEL 8.3 版本的技術(shù)預(yù)覽,它將作為一個(gè)可選的 OCI 運(yùn)行時(shí),又因?yàn)樗?Red Hat 的產(chǎn)品,它可能最終會(huì)成為 Podman 或 CRI-O 的默認(rèn)配置。

          前面我說(shuō)過(guò),CRI-O 實(shí)際上不是容器引擎,而是容器運(yùn)行時(shí)。這是因?yàn)?CRI-O 沒(méi)有提供諸如鏡像推送之類(lèi)的特性,而這些特性是容器引擎應(yīng)該具備的。CRI-O 在內(nèi)部使用 runc 來(lái)運(yùn)行容器。你不應(yīng)該在自己的機(jī)器上嘗試使用這個(gè)運(yùn)行時(shí),因?yàn)樗亲鳛檫\(yùn)行在 Kubernetes 節(jié)點(diǎn)上的運(yùn)行時(shí)而設(shè)計(jì)的,并被描述為“Kubernetes 所需的運(yùn)行時(shí)”。因此,除非你正在運(yùn)行 Kubernetes 集群 (或 OpenShift 集群——CRI-O 已經(jīng)是默認(rèn)設(shè)置了),否則不應(yīng)該接觸這個(gè)。

          最后一個(gè)是 containerd(https://containerd.io),它是 CNCF 的一個(gè)畢業(yè)項(xiàng)目。它是一個(gè)守護(hù)進(jìn)程,作為各種容器運(yùn)行時(shí)和操作系統(tǒng)的 API 外觀。在后臺(tái),它依賴(lài) runc,是 Docker 引擎的默認(rèn)運(yùn)行時(shí)。谷歌 Kubernetes 引擎 (GKE) 和 IBM Kubernetes 服務(wù) (IKS) 也在使用它。它是 Kubernetes 容器運(yùn)行時(shí)接口的一個(gè)實(shí)現(xiàn) (與 CRI-O 一樣),因此它是 Kubernetes 集群運(yùn)行時(shí)的一個(gè)很好的候選對(duì)象。

          鏡像的檢查與分發(fā)

          最后一部分內(nèi)容是鏡像的檢查與分發(fā),主要是替代 docker inspect,并 (可選地) 增加遠(yuǎn)程注冊(cè)表之間復(fù)制鏡像的能力。

          我這里要提到的一個(gè)可以完成這些任務(wù)的工具是 Skopeo(https://github.com/containers/skopeo)。它由 Red Hat 公司開(kāi)發(fā),可以與 Buildah、Podman 和 CRI-O 配套使用。除了基本的 inspect 之外,Skopeo 還提供了 skopeo copy 命令來(lái)復(fù)制鏡像,可以直接在遠(yuǎn)程注冊(cè)表之間復(fù)制鏡像,無(wú)需將它們拉取到本地注冊(cè)表。如果你使用了本地注冊(cè)表,這個(gè)命令也可以作為拉取 / 推送的替代方案。

          另外,我還想提一下 Dive(https://github.com/wagoodman/dive),這是一個(gè)檢查、探索和分析鏡像的工具。它對(duì)用戶(hù)更友好一些,提供了更可讀的輸出,可以更深入地挖掘鏡像,并分析和衡量其效率。它也適合被用在 CI 管道中,用于衡量你的鏡像是否“足夠高效”,或者換句話說(shuō)——它是否浪費(fèi)了太多空間。

          結(jié)? ? ? 論

          本文的目的并不是要說(shuō)服你完全拋棄 Docker,而是向你展示構(gòu)建、運(yùn)行、管理和分發(fā)容器及其鏡像的整個(gè)場(chǎng)景和所有可選項(xiàng)。包括 Docker 在內(nèi)的每一種工具都有其優(yōu)缺點(diǎn),評(píng)估哪一組工具最適合你的工作流程和場(chǎng)景才是最重要的,希望本文能在這方面為你提供一些幫助。

          良許個(gè)人微信


          添加良許個(gè)人微信即送3套程序員必讀資料


          → 精選技術(shù)資料共享

          → 高手如云交流社群





          本公眾號(hào)全部博文已整理成一個(gè)目錄,請(qǐng)?jiān)诠娞?hào)里回復(fù)「m」獲取!

          推薦閱讀:

          Linux系統(tǒng)inodes資源耗盡問(wèn)題

          如何從一張外國(guó)軍車(chē)照片,判斷它要去哪里?

          如何辨別二逼互聯(lián)網(wǎng)公司!?


          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹(shù)莓派,等等。在公眾號(hào)內(nèi)回復(fù)「1024」,即可免費(fèi)獲取!!


          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人操碰 | 天堂网在线最新版www中文网 | 热久久思思热 | 污网址在线 | 黄视频免费 |