終於可以像使用 Docker 一樣絲滑地使用 Containerd 了!

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有追求的工程師一般都是有技術潔癖的,雲原生的世界更是如此,"},{"type":"codeinline","content":[{"type":"text","text":"Kubernetes"}]},{"type":"text","text":" 雖然制定了容器運行時接口("},{"type":"codeinline","content":[{"type":"text","text":"CRI"}]},{"type":"text","text":")標準,但早期能用的容器運行時只有 "},{"type":"codeinline","content":[{"type":"text","text":"Docker"}]},{"type":"text","text":",而 "},{"type":"codeinline","content":[{"type":"text","text":"Docker"}]},{"type":"text","text":" 又不適配這個標準,於是給 "},{"type":"codeinline","content":[{"type":"text","text":"Docker"}]},{"type":"text","text":" 開了後門,花了大量的精力去適配它。後來有了更多的容器運行時可以選擇後,Kubernetes 就不得不重新考量要不要繼續適配 Docker 了,因爲每次更新 Kubelet 都要考慮與 Docker 的適配問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/06\/062b6ad6c3b81b544ff04b0fcea52313.gif","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"標準這個東西就是這樣,我定好標準,你兼容了就一起玩,不兼容就拜拜,它就像兩個人在一起的底線,你可以重,你可以醜,你也可以不完善,但是你不兼容標準就真的不能一起玩了,於是 Kubernetes 就把 Docker 踢出了羣聊。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f5\/f55e5c1cff02c328d45d35a3bf49c45f.gif","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最終 Kubernetes 選擇了 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":",時至今日 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 已經變成一個工業級的容器運行時了,它足夠簡單、健壯,可移植性也很強。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"現有 CLI 的不足"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然 Docker 能幹的事情,現在 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 都能幹,但 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 還有一個非常明顯的缺陷:"},{"type":"text","marks":[{"type":"strong"}],"text":"CLI 不夠友好"},{"type":"text","text":"。它無法像 Docker 和 Podman 一樣通過一條簡單的命令啓動一個容器,它的兩個 CLI 工具 "},{"type":"text","marks":[{"type":"strong"}],"text":"ctr"},{"type":"sup","content":[{"type":"text","text":"[1]"}],"marks":[{"type":"strong"}]},{"type":"text","text":" 和 "},{"type":"text","marks":[{"type":"strong"}],"text":"crictl"},{"type":"sup","content":[{"type":"text","text":"[2]"}],"marks":[{"type":"strong"}]},{"type":"text","text":" 都無法實現這麼一件非常簡單的需求,而這個需求是大多數人都需要的,我總不能爲了在本地測試容器而專門部署一個 Kubernetes 集羣吧?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/b6\/b63089c51a1f4b3c531e97a4c6f827f4.gif","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ctr 的設計對人類不太友好,例如缺少以下這些和 Docker 類似的功能:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"docker run -p "}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"docker run --restart=always"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過憑證文件 "},{"type":"codeinline","content":[{"type":"text","text":"~\/.docker\/config.json"}]},{"type":"text","text":" 來拉取鏡像"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"docker logs"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除此之外還有一個 CLI 工具叫 "},{"type":"codeinline","content":[{"type":"text","text":"crictl"}]},{"type":"text","text":",和 "},{"type":"codeinline","content":[{"type":"text","text":"ctr"}]},{"type":"text","text":" 一樣不太友好。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了解決這個痛點,Containerd 官方推出了一個新的 CLI 叫 "},{"type":"text","marks":[{"type":"strong"}],"text":"nerdctl"},{"type":"sup","content":[{"type":"text","text":"[3]"}],"marks":[{"type":"strong"}]},{"type":"text","text":"。nerdctl 的使用體驗和 docker 一樣順滑,例如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → nerdctl run -d -p 8080:80 --name=nginx --restart=always nginx"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"nerdctl 只是 docker 的複製品?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"nerdctl"}]},{"type":"text","text":" 的目標並不是單純地複製 docker 的功能,它還實現了很多 docker 不具備的功能,例如延遲拉取鏡像("},{"type":"text","marks":[{"type":"strong"}],"text":"lazy-pulling"},{"type":"sup","content":[{"type":"text","text":"[4]"}],"marks":[{"type":"strong"}]},{"type":"text","text":")、鏡像加密("},{"type":"text","marks":[{"type":"strong"}],"text":"imgcrypt"},{"type":"sup","content":[{"type":"text","text":"[5]"}],"marks":[{"type":"strong"}]},{"type":"text","text":")等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/e4\/e474dc7547ee35fd88dfc0e9e7896fac.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"延遲拉取鏡像功能可以參考這篇文章:"},{"type":"text","marks":[{"type":"strong"}],"text":"Containerd 使用 Stargz Snapshotter 延遲拉取鏡像"},{"type":"sup","content":[{"type":"text","text":"[6]"}],"marks":[{"type":"strong"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然這些功能預計最終也會在 Docker 中實現,但"},{"type":"text","marks":[{"type":"strong"}],"text":"可能需要幾個月甚至幾年的時間"},{"type":"sup","content":[{"type":"text","text":"[7]"}],"marks":[{"type":"strong"}]},{"type":"text","text":",因爲 Docker 目前的設計只使用一小部分 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 子系統。將來 Docker 有可能重構代碼以使用完整的 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":",但目前還沒看到什麼實質性進展。所以 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 社區決定創建一個新的 CLI 來更友好地使用 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"nerdctl 試用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你可以從 "},{"type":"text","marks":[{"type":"strong"}],"text":"nerdctl 的 release"},{"type":"sup","content":[{"type":"text","text":"[8]"}],"marks":[{"type":"strong"}]},{"type":"text","text":" 中下載最新的可執行文件,每一個版本都有兩種可用的發行版:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"nerdctl--linux-amd64.tar.gz"}]},{"type":"text","text":" : 只包含 nerdctl。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"nerdctl-full--linux-amd64.tar.gz"}]},{"type":"text","text":" : 包含了 nerdctl 和相關依賴組件(containerd, runc, CNI, …)。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你已經安裝了 Containerd,只需要選擇前一個發行版,否則就選擇完整版。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"安裝好 nerdctl 後,就可以使用 nerdctl 來運行容器了:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine\n\ndocker.io\/library\/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|\nindex-sha256:d33e9e24389d7d8b90fe2bcc2dd1bc09b4d235e916ba9d5d9a71cf52e340edb6:    done           |++++++++++++++++++++++++++++++++++++++|\nmanifest-sha256:c1f4e1974241c3f9ddb2866b2bf8e7afbceaa42dae82aabda5e946d03f054ed2: done           |++++++++++++++++++++++++++++++++++++++|\nconfig-sha256:bfad9487e175364fd6315426feeee34bf5e6f516d2fe6a4e9b592315e330828e:   done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:29d3f97df6fd99736a0676f9e57e53dfa412cf60b26d95008df9da8197f1f366:    done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:9aae54b2144e5b2b00c610f8805128f4f86822e1e52d3714c463744a431f0f4a:    done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:a5f0adaddd5456b7c5a3753ab541b5fad750f0a6499a15f63571b964eb3e2616:    done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:5df810e1c460527fe400cdd2cab62228f5fb3da0f2dce86a6a6c354972f19b6e:    done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:345aee38d3533398e0eb7118e4323a8970f7615136f2170dfb2b0278bbd9099d:    done           |++++++++++++++++++++++++++++++++++++++|\nlayer-sha256:e6a4c36d7c0e358e5fc02ccdac645b18b85dcfec09d4fb5f8cbdc187ce9467a0:    done           |++++++++++++++++++++++++++++++++++++++|\nelapsed: 5.7 s                                                                    total:  9.4 Mi (1.6 MiB\/s)\n27b55e0b18b10c4c8f34e3ba709614e7b1760a75db061d2ce5183e8b1101ce09\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看創建的容器:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → nerdctl ps\n\nCONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                 NAMES\n3b5faa266a43    docker.io\/library\/nginx:alpine    \"\/docker-entrypoint.…\"    3 minutes ago    Up        0.0.0.0:80->80\/tcp    nginx"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和 Docker 一樣,Containerd 也有一個子命令 "},{"type":"codeinline","content":[{"type":"text","text":"network"}]},{"type":"text","text":":"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → nerdctl network ls\n\nNETWORK ID    NAME               FILE\n0             bridge\n              k8s-pod-network    \/etc\/cni\/net.d\/10-calico.conflist\n              host\n              none"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來看下默認的 bridge 配置:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"🐳  → nerdctl network inspect bridge\n[\n    {\n        \"CNI\": {\n            \"cniVersion\": \"0.4.0\",\n            \"name\": \"bridge\",\n            \"nerdctlID\": 0,\n            \"plugins\": [\n                {\n                    \"type\": \"bridge\",\n                    \"bridge\": \"nerdctl0\",\n                    \"isGateway\": true,\n                    \"ipMasq\": true,\n                    \"hairpinMode\": true,\n                    \"ipam\": {\n                        \"type\": \"host-local\",\n                        \"routes\": [\n                            {\n                                \"dst\": \"0.0.0.0\/0\"\n                            }\n                        ],\n                        \"ranges\": [\n                            [\n                                {\n                                    \"subnet\": \"10.4.0.0\/24\",\n                                    \"gateway\": \"10.4.0.1\"\n                                }\n                            ]\n                        ]\n                    }\n                },\n                {\n                    \"type\": \"portmap\",\n                    \"capabilities\": {\n                        \"portMappings\": true\n                    }\n                },\n                {\n                    \"type\": \"firewall\"\n                },\n                {\n                    \"type\": \"tuning\"\n                }\n            ]\n        },\n        \"NerdctlID\": 0\n    }\n]\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到 "},{"type":"codeinline","content":[{"type":"text","text":"network"}]},{"type":"text","text":" 子命令背後還是 CNI 在運作,與 docker network 子命令原理不同。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"構建鏡像"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"nerdctl"}]},{"type":"text","text":" 也可以和 "},{"type":"codeinline","content":[{"type":"text","text":"buildkit"}]},{"type":"text","text":" 結合使用來構建容器鏡像,需要先下載 buildkit 的可執行文件:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → wget https:\/\/github.com\/moby\/buildkit\/releases\/download\/v0.8.2\/buildkit-v0.8.2.darwin-amd64.tar.gz"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將其解壓到 "},{"type":"codeinline","content":[{"type":"text","text":"$PATH"}]},{"type":"text","text":" 中:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → tar -C \/usr\/local\/ -zxvf buildkit-v0.8.2.linux-amd64.tar.gz"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編寫 systemd unit 文件:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# \/etc\/systemd\/system\/buildkit.service\n[Unit]\nDescription=BuildKit\nDocumentation=https:\/\/github.com\/moby\/buildkit\n\n[Service]\nExecStart=\/usr\/local\/bin\/buildkitd --oci-worker=false --containerd-worker=true\n\n[Install]\nWantedBy=multi-user.target"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"啓用 buildkit.service 並設置開機自動運行:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → systemctl enable --now buildkit.service"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面以 "},{"type":"text","marks":[{"type":"strong"}],"text":"KubeSphere"},{"type":"sup","content":[{"type":"text","text":"[9]"}],"marks":[{"type":"strong"}]},{"type":"text","text":" 項目爲例,展示如何使用 "},{"type":"codeinline","content":[{"type":"text","text":"nerdctl"}]},{"type":"text","text":" 來構建鏡像。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先克隆 KubeSphere 官方倉庫:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → git clone --depth=1 https:\/\/github.com.cnpmjs.org\/kubesphere\/kubesphere.git"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入倉庫目錄,編譯二進制文件:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → cd kubesphere\n🐳  → make ks-apiserver"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"將二進制文件拷貝到 "},{"type":"codeinline","content":[{"type":"text","text":"Dockerfile"}]},{"type":"text","text":" 目錄:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → cp bin\/cmd\/ks-apiserver build\/ks-apiserver"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進入 "},{"type":"codeinline","content":[{"type":"text","text":"Dockerfile"}]},{"type":"text","text":" 目錄,修改 Dockerfile:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# Copyright 2020 The KubeSphere Authors. All rights reserved.\n# Use of this source code is governed by an Apache license\n# that can be found in the LICENSE file.\nFROM alpine:3.11\n\nARG HELM_VERSION=v3.5.2\n\nRUN apk add --no-cache ca-certificates\n# install helm\nRUN wget https:\/\/get.helm.sh\/helm-${HELM_VERSION}-linux-amd64.tar.gz && \\\n    tar xvf helm-${HELM_VERSION}-linux-amd64.tar.gz && \\\n    rm helm-${HELM_VERSION}-linux-amd64.tar.gz && \\\n    mv linux-amd64\/helm \/usr\/bin\/ && \\\n    rm -rf linux-amd64\n# To speed up building process, we copy binary directly from make\n# result instead of building it again, so make sure you run the\n# following command first before building docker image\n#   make ks-apiserver\n#\nCOPY  ks-apiserver \/usr\/local\/bin\/\n\nEXPOSE 9090\nCMD [\"sh\"]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"構建鏡像:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → cd build\/ks-apiserver\n\n🐳  → nerdctl build -t ks-apiserver .\n[+] Building 22.6s (9\/9) FINISHED\n => [internal] load build definition from Dockerfile                                                                                                                                0.0s\n => => transferring dockerfile: 812B                                                                                                                                                0.0s\n => [internal] load .dockerignore                                                                                                                                                   0.0s\n => => transferring context: 2B                                                                                                                                                     0.0s\n => [internal] load metadata for docker.io\/library\/alpine:3.11                                                                                                                      1.0s\n => [1\/4] FROM docker.io\/library\/alpine:3.11@sha256:bf5fa774f08a9ed2cb301e522b769d43d48124315a4ec50eae3228d03b9dc558                                                                7.9s\n => => resolve docker.io\/library\/alpine:3.11@sha256:bf5fa774f08a9ed2cb301e522b769d43d48124315a4ec50eae3228d03b9dc558                                                                0.0s\n => => sha256:9b794450f7b6db7c944ba1f4161edb68cb535052fe7db8ac06e613516c4a658d 2.10MB \/ 2.82MB                                                                                     21.4s\n => => extracting sha256:9b794450f7b6db7c944ba1f4161edb68cb535052fe7db8ac06e613516c4a658d                                                                                           0.1s\n => [internal] load build context                                                                                                                                                   1.0s\n => => transferring context: 115.87MB                                                                                                                                               1.0s\n => [2\/4] RUN apk add --no-cache ca-certificates                                                                                                                                    2.7s\n => [3\/4] RUN wget https:\/\/get.helm.sh\/helm-v3.5.2-linux-amd64.tar.gz &&     tar xvf helm-v3.5.2-linux-amd64.tar.gz &&     rm helm-v3.5.2-linux-amd64.tar.gz &&     mv linux-amd64  4.7s\n => [4\/4] COPY  ks-apiserver \/usr\/local\/bin\/                                                                                                                                        0.2s\n => exporting to oci image format                                                                                                                                                   5.9s\n => => exporting layers                                                                                                                                                             4.6s\n => => exporting manifest sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e                                                                                   0.0s\n => => exporting config sha256:8eb6a5187ce958e76c8d37e18221d88f25b48dd7e6672021d0fce21bb071f284                                                                                     0.0s\n => => sending tarball                                                                                                                                                              1.3s\nunpacking docker.io\/library\/ks-apiserver:latest (sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e)...done\nunpacking overlayfs@sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e (sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e)...done"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看構建好的鏡像:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"🐳  → nerdctl images\n\nREPOSITORY                                                   TAG       IMAGE ID        CREATED          SIZE\nalpine                                                       3.11      bf5fa774f08a    3 seconds ago    2.7 MiB\nks-apiserver                                                 latest    d7eb2a904966    6 minutes ago    57.7 MiB"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 nerdctl 的更多用法,可以參考"},{"type":"text","marks":[{"type":"strong"}],"text":"官方倉庫的 README"},{"type":"sup","content":[{"type":"text","text":"[10]"}],"marks":[{"type":"strong"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從行業趨勢來看,Docker 已經和 Kubernetes 社區漸行漸遠,以 "},{"type":"codeinline","content":[{"type":"text","text":"Containerd"}]},{"type":"text","text":" 爲代表的實現了 "},{"type":"codeinline","content":[{"type":"text","text":"CRI"}]},{"type":"text","text":" 接口的容器運行時將會受到 Kubernetes 的青睞。但純粹使用 Containerd 還是有諸多困擾,比如不方便通過 CLI 來創建管理容器,有了 "},{"type":"codeinline","content":[{"type":"text","text":"nerdctl"}]},{"type":"text","text":" 這個 CLI 工具,就就可以填補 Containerd 易用性的空缺,讓你在單機上也能愉快地使用 Containerd。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"腳註"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[1]ctr: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/containerd\/tree\/master\/cmd\/ctr"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[2]crictl: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/kubernetes-sigs\/cri-tools"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[3]nerdctl: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/nerdctl"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[4]lazy-pulling: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/nerdctl\/blob\/master\/docs\/stargz.md"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[5]imgcrypt: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/imgcrypt"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[6]Containerd 使用 Stargz Snapshotter 延遲拉取鏡像: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/fuckcloudnative.io\/posts\/startup-containers-in-lightning-speed-with-lazy-image-distribution-on-containerd\/"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[7]可能需要幾個月甚至幾年的時間: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/moby\/moby\/pull\/41002"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[8]nerdctl 的 release: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/nerdctl\/releases"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[9]KubeSphere: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/kubesphere\/kubesphere"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[10]官方倉庫的 README: "},{"type":"text","marks":[{"type":"italic"}],"text":"https:\/\/github.com\/containerd\/nerdctl"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頭圖:Unsplash"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作者:米開朗基楊"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:https:\/\/mp.weixin.qq.com\/s\/Bjn0s5qRh2H9I__mAYh4jg"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文:終於可以像使用 Docker 一樣絲滑地使用 Containerd 了!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來源:KubeSphere雲原生 - 微信公衆號 [ID:gh_f5606464ef2f]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轉載:著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章