写点什么

终于可以像使用 Docker 一样丝滑地使用 Containerd 了!

  • 2021-04-21
  • 本文字数:8805 字

    阅读完需:约 29 分钟

终于可以像使用 Docker 一样丝滑地使用 Containerd 了!

有追求的工程师一般都是有技术洁癖的,云原生的世界更是如此,Kubernetes 虽然制定了容器运行时接口(CRI)标准,但早期能用的容器运行时只有 Docker,而 Docker 又不适配这个标准,于是给 Docker 开了后门,花了大量的精力去适配它。后来有了更多的容器运行时可以选择后,Kubernetes 就不得不重新考量要不要继续适配 Docker 了,因为每次更新 Kubelet 都要考虑与 Docker 的适配问题。



标准这个东西就是这样,我定好标准,你兼容了就一起玩,不兼容就拜拜,它就像两个人在一起的底线,你可以重,你可以丑,你也可以不完善,但是你不兼容标准就真的不能一起玩了,于是 Kubernetes 就把 Docker 踢出了群聊。



最终 Kubernetes 选择了 Containerd,时至今日 Containerd 已经变成一个工业级的容器运行时了,它足够简单、健壮,可移植性也很强。


现有 CLI 的不足


虽然 Docker 能干的事情,现在 Containerd 都能干,但 Containerd 还有一个非常明显的缺陷:CLI 不够友好。它无法像 Docker 和 Podman 一样通过一条简单的命令启动一个容器,它的两个 CLI 工具 ctr[1] 和 crictl[2] 都无法实现这么一件非常简单的需求,而这个需求是大多数人都需要的,我总不能为了在本地测试容器而专门部署一个 Kubernetes 集群吧?



ctr 的设计对人类不太友好,例如缺少以下这些和 Docker 类似的功能:


  • docker run -p <PORT>

  • docker run --restart=always

  • 通过凭证文件 ~/.docker/config.json 来拉取镜像

  • docker logs


除此之外还有一个 CLI 工具叫 crictl,和 ctr 一样不太友好。

为了解决这个痛点,Containerd 官方推出了一个新的 CLI 叫 nerdctl[3]。nerdctl 的使用体验和 docker 一样顺滑,例如:


🐳  → nerdctl run -d -p 8080:80 --name=nginx --restart=always nginx
复制代码


nerdctl 只是 docker 的复制品?


nerdctl 的目标并不是单纯地复制 docker 的功能,它还实现了很多 docker 不具备的功能,例如延迟拉取镜像(lazy-pulling[4])、镜像加密(imgcrypt[5])等。



延迟拉取镜像功能可以参考这篇文章:Containerd 使用 Stargz Snapshotter 延迟拉取镜像[6]


虽然这些功能预计最终也会在 Docker 中实现,但可能需要几个月甚至几年的时间[7],因为 Docker 目前的设计只使用一小部分 Containerd 子系统。将来 Docker 有可能重构代码以使用完整的 Containerd,但目前还没看到什么实质性进展。所以 Containerd 社区决定创建一个新的 CLI 来更友好地使用 Containerd


nerdctl 试用


你可以从 nerdctl 的 release[8] 中下载最新的可执行文件,每一个版本都有两种可用的发行版:


  • nerdctl-<VERSION>-linux-amd64.tar.gz : 只包含 nerdctl。

  • nerdctl-full-<VERSION>-linux-amd64.tar.gz : 包含了 nerdctl 和相关依赖组件(containerd, runc, CNI, …)。


如果你已经安装了 Containerd,只需要选择前一个发行版,否则就选择完整版。


安装好 nerdctl 后,就可以使用 nerdctl 来运行容器了:


🐳  → nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|index-sha256:d33e9e24389d7d8b90fe2bcc2dd1bc09b4d235e916ba9d5d9a71cf52e340edb6:    done           |++++++++++++++++++++++++++++++++++++++|manifest-sha256:c1f4e1974241c3f9ddb2866b2bf8e7afbceaa42dae82aabda5e946d03f054ed2: done           |++++++++++++++++++++++++++++++++++++++|config-sha256:bfad9487e175364fd6315426feeee34bf5e6f516d2fe6a4e9b592315e330828e:   done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:29d3f97df6fd99736a0676f9e57e53dfa412cf60b26d95008df9da8197f1f366:    done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:9aae54b2144e5b2b00c610f8805128f4f86822e1e52d3714c463744a431f0f4a:    done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:a5f0adaddd5456b7c5a3753ab541b5fad750f0a6499a15f63571b964eb3e2616:    done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:5df810e1c460527fe400cdd2cab62228f5fb3da0f2dce86a6a6c354972f19b6e:    done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:345aee38d3533398e0eb7118e4323a8970f7615136f2170dfb2b0278bbd9099d:    done           |++++++++++++++++++++++++++++++++++++++|layer-sha256:e6a4c36d7c0e358e5fc02ccdac645b18b85dcfec09d4fb5f8cbdc187ce9467a0:    done           |++++++++++++++++++++++++++++++++++++++|elapsed: 5.7 s                                                                    total:  9.4 Mi (1.6 MiB/s)27b55e0b18b10c4c8f34e3ba709614e7b1760a75db061d2ce5183e8b1101ce09
复制代码

查看创建的容器:

🐳  → nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                 NAMES3b5faa266a43    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    3 minutes ago    Up        0.0.0.0:80->80/tcp    nginx
复制代码

和 Docker 一样,Containerd 也有一个子命令 network

🐳  → nerdctl network ls
NETWORK ID    NAME               FILE0             bridge              k8s-pod-network    /etc/cni/net.d/10-calico.conflist              host              none
复制代码

来看下默认的 bridge 配置:

🐳  → nerdctl network inspect bridge[    {        "CNI": {            "cniVersion": "0.4.0",            "name": "bridge",            "nerdctlID": 0,            "plugins": [                {                    "type": "bridge",                    "bridge": "nerdctl0",                    "isGateway": true,                    "ipMasq": true,                    "hairpinMode": true,                    "ipam": {                        "type": "host-local",                        "routes": [                            {                                "dst": "0.0.0.0/0"                            }                        ],                        "ranges": [                            [                                {                                    "subnet": "10.4.0.0/24",                                    "gateway": "10.4.0.1"                                }                            ]                        ]                    }                },                {                    "type": "portmap",                    "capabilities": {                        "portMappings": true                    }                },                {                    "type": "firewall"                },                {                    "type": "tuning"                }            ]        },        "NerdctlID": 0    }]
复制代码

可以看到 network 子命令背后还是 CNI 在运作,与 docker network 子命令原理不同。


构建镜像


nerdctl 也可以和 buildkit 结合使用来构建容器镜像,需要先下载 buildkit 的可执行文件:

🐳  → wget https://github.com/moby/buildkit/releases/download/v0.8.2/buildkit-v0.8.2.darwin-amd64.tar.gz
复制代码

将其解压到 $PATH 中:

🐳  → tar -C /usr/local/ -zxvf buildkit-v0.8.2.linux-amd64.tar.gz
复制代码

编写 systemd unit 文件:

# /etc/systemd/system/buildkit.service[Unit]Description=BuildKitDocumentation=https://github.com/moby/buildkit
[Service]ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true
[Install]WantedBy=multi-user.target
复制代码

启用 buildkit.service 并设置开机自动运行:

🐳  → systemctl enable --now buildkit.service
复制代码

下面以 KubeSphere[9] 项目为例,展示如何使用 nerdctl 来构建镜像。

首先克隆 KubeSphere 官方仓库:

🐳  → git clone --depth=1 https://github.com.cnpmjs.org/kubesphere/kubesphere.git
复制代码

进入仓库目录,编译二进制文件:

🐳  → cd kubesphere🐳  → make ks-apiserver
复制代码

将二进制文件拷贝到 Dockerfile 目录:

🐳  → cp bin/cmd/ks-apiserver build/ks-apiserver
复制代码

进入 Dockerfile 目录,修改 Dockerfile:

# Copyright 2020 The KubeSphere Authors. All rights reserved.# Use of this source code is governed by an Apache license# that can be found in the LICENSE file.FROM alpine:3.11
ARG HELM_VERSION=v3.5.2
RUN apk add --no-cache ca-certificates# install helmRUN wget https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz && \    tar xvf helm-${HELM_VERSION}-linux-amd64.tar.gz && \    rm helm-${HELM_VERSION}-linux-amd64.tar.gz && \    mv linux-amd64/helm /usr/bin/ && \    rm -rf linux-amd64# To speed up building process, we copy binary directly from make# result instead of building it again, so make sure you run the# following command first before building docker image#   make ks-apiserver#COPY  ks-apiserver /usr/local/bin/
EXPOSE 9090CMD ["sh"]
复制代码

构建镜像:

🐳  → cd build/ks-apiserver
🐳  → nerdctl build -t ks-apiserver .[+] Building 22.6s (9/9) FINISHED => [internal] load build definition from Dockerfile                                                                                                                                0.0s => => transferring dockerfile: 812B                                                                                                                                                0.0s => [internal] load .dockerignore                                                                                                                                                   0.0s => => transferring context: 2B                                                                                                                                                     0.0s => [internal] load metadata for docker.io/library/alpine:3.11                                                                                                                      1.0s => [1/4] FROM docker.io/library/alpine:3.11@sha256:bf5fa774f08a9ed2cb301e522b769d43d48124315a4ec50eae3228d03b9dc558                                                                7.9s => => resolve docker.io/library/alpine:3.11@sha256:bf5fa774f08a9ed2cb301e522b769d43d48124315a4ec50eae3228d03b9dc558                                                                0.0s => => sha256:9b794450f7b6db7c944ba1f4161edb68cb535052fe7db8ac06e613516c4a658d 2.10MB / 2.82MB                                                                                     21.4s => => extracting sha256:9b794450f7b6db7c944ba1f4161edb68cb535052fe7db8ac06e613516c4a658d                                                                                           0.1s => [internal] load build context                                                                                                                                                   1.0s => => transferring context: 115.87MB                                                                                                                                               1.0s => [2/4] RUN apk add --no-cache ca-certificates                                                                                                                                    2.7s => [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 => [4/4] COPY  ks-apiserver /usr/local/bin/                                                                                                                                        0.2s => exporting to oci image format                                                                                                                                                   5.9s => => exporting layers                                                                                                                                                             4.6s => => exporting manifest sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e                                                                                   0.0s => => exporting config sha256:8eb6a5187ce958e76c8d37e18221d88f25b48dd7e6672021d0fce21bb071f284                                                                                     0.0s => => sending tarball                                                                                                                                                              1.3sunpacking docker.io/library/ks-apiserver:latest (sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e)...doneunpacking overlayfs@sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e (sha256:d7eb2a90496678d11ac5c363b7743ffe2b8e23e7071b94556a5e3231f50f5a6e)...done
复制代码

查看构建好的镜像:

🐳  → nerdctl images
REPOSITORY                                                   TAG       IMAGE ID        CREATED          SIZEalpine                                                       3.11      bf5fa774f08a    3 seconds ago    2.7 MiBks-apiserver                                                 latest    d7eb2a904966    6 minutes ago    57.7 MiB
复制代码

关于 nerdctl 的更多用法,可以参考官方仓库的 README[10]


总结


从行业趋势来看,Docker 已经和 Kubernetes 社区渐行渐远,以 Containerd 为代表的实现了 CRI 接口的容器运行时将会受到 Kubernetes 的青睐。但纯粹使用 Containerd 还是有诸多困扰,比如不方便通过 CLI 来创建管理容器,有了 nerdctl 这个 CLI 工具,就就可以填补 Containerd 易用性的空缺,让你在单机上也能愉快地使用 Containerd。

脚注

[1]ctr: https://github.com/containerd/containerd/tree/master/cmd/ctr

[2]crictl: https://github.com/kubernetes-sigs/cri-tools

[3]nerdctl: https://github.com/containerd/nerdctl

[4]lazy-pulling: https://github.com/containerd/nerdctl/blob/master/docs/stargz.md

[5]imgcrypt: https://github.com/containerd/imgcrypt

[6]Containerd 使用 Stargz Snapshotter 延迟拉取镜像: https://fuckcloudnative.io/posts/startup-containers-in-lightning-speed-with-lazy-image-distribution-on-containerd/

[7]可能需要几个月甚至几年的时间: https://github.com/moby/moby/pull/41002

[8]nerdctl 的 release: https://github.com/containerd/nerdctl/releases

[9]KubeSphere: https://github.com/kubesphere/kubesphere

[10]官方仓库的 README: https://github.com/containerd/nerdctl



头图:Unsplash

作者:米开朗基杨

原文:https://mp.weixin.qq.com/s/Bjn0s5qRh2H9I__mAYh4jg

原文:终于可以像使用 Docker 一样丝滑地使用 Containerd 了!

来源:KubeSphere 云原生 - 微信公众号 [ID:gh_f5606464ef2f]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-04-21 16:068668

评论 2 条评论

发布
用户头像
但在桌面端开发时,DockerDesktop 仍是唯一选择
2021-05-20 17:53
回复
用户头像
🐳 →
这个是什么
2021-04-25 10:01
回复
没有更多了
发现更多内容

Git操作备忘录(持续更新)

IT蜗壳-Tango

git IT蜗壳教学 1月月更

悄悄告诉你,有种管理方法能让设计团队学习、产出两不误!

LigaAI

效率 技术

在线JSON转HTML工具

入门小站

工具

【逆向分析】快速查找指定代码的几种方法

H

网络安全 逆向分析

🏆【Alibaba中间件技术系列】「RocketMQ技术专题」带你一起去探索RocketMQ服务架构的线程模型分析

码界西柚

RocketMQ SpringCloud Alibaba Alibaba技术 Apache RocketMQ

04 Prometheus之配置步骤及容量规划

穿过生命散发芬芳

Prometheus 1月月更

web技术分享| css filter和getUserMedia的联合使用

anyRTC开发者

CSS 前端 Web 音视频 WebRTC

DevEco Device Tool 3.0 Beta2新版本发布,新增可视化Trace工具和Perf性能分析工具

HarmonyOS开发者

OpenHarmony

浅谈ThinkPH5.0和5.1的反序列化利用链分析

网络安全学海

黑客 网络安全 信息安全 渗透测试 安全漏洞

微博评论高性能高可用计算架构

ren

Elasticsearch 多种跨机房灾备方案对比与实战解读

Se7en

LigaAI 2021年终总结

LigaAI

团队管理 技术 成长笔记】 年度总结

区块链数字藏品平台开发,区块链+数字藏品激活传统文创

电微13828808271

“群舰效应”与商业市场大航海

脑极体

查收新年礼物 | DevEco Studio 3.0 Beta2发布,20个新变化,等你升级

HarmonyOS开发者

HarmonyOS

龙蜥社区2021年度运营委员会会议顺利召开

OpenAnolis小助手

龙蜥社区

当前端渲染遇上边缘计算

火山引擎边缘云

Spring 如何解决循环依赖问题?

CRMEB

一个cpp协程库的前世今生(十)调度的流程

SkyFire

c++ cocpp

架构实战 - 模块八

唐敏

「架构实战营」

阿里云贾少天:大规模云服务器高效使用及管理实践

阿里云弹性计算

阿里云 云栖大会 云上运维

今晚直播:展望2022,操作系统将走向何方?

OpenAnolis小助手

操作系统 国产操作系统 龙蜥社区

科尼数字科技张彬:云设计系统助力行业数字化转型

阿里云弹性计算

阿里云 弹性计算 年度峰会

(1-3/3)团队OKR的设定

mtfelix

300天创作 无限生长 2022Y300P

年度盘点|每一个ToB产品都值得被看见

ToB行业头条

找出数组中出现次数超过一半的数字

zdd

算法题

政法委重点人员联防联控平台开发,跨部门大数据系统搭建

电微13828808271

Linux之find命令的参数详解

入门小站

Linux

JVM到底该学些什么?

蝉沐风

JVM 虚拟机 学习路线

基于区块链和web3.0的全新社交协议Coo Social首发上线虎符创新区

区块链前沿News

Hoo 虎符交易所 coo Web3.0

开源实践 | 六棱镜基于 OceanBase 选型探索与实践

OceanBase 数据库

OceanBase 开源 OceanBase 社区版 客户案例

终于可以像使用 Docker 一样丝滑地使用 Containerd 了!_产品_KubeSphere_InfoQ精选文章