像使用 Docker 一样使用 Containerd,替代工具:nerdctl


总结
1.先yum安装Containerd
2.下载压缩包,安装nerdctl,cni-plugins,buildkit

或者直接下载nerdctl-full,里面包含nerdctl,containerd, runc, CNI,buildkit等

wget https://github.com/containerd/nerdctl/releases/download/v0.17.1/nerdctl-full-0.17.1-linux-amd64.tar.gz
tar -zxv -f nerdctl-full-0.15.0-linux-amd64.tar.gz -C /usr/local
cp /usr/local/lib/systemd/system/*.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable buildkit containerd
systemctl start buildkit containerd
systemctl status buildkit containerd

现有 CLI 的不足

虽然 Docker 能干的事情,现在Containerd 都能干,但 Containerd 还有一个非常明显的缺陷:CLI不够友好。它无法像Docker 和Podman 一样通过一条简单的命令启动一个容器,它的两个 CLI 工具 [ctr] 和 [crictl] 都无法实现这么一件非常简单的需求,而这个需求是大多数人都需要的.

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

  • docker run -p
  • docker run --restart=always
  • 通过凭证文件 ~/.docker/config.json 来拉取镜像
  • docker logs

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

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

nerdctl run -d -p 8080:80 --name=nginx --restart=always nginx

nerdctl 使用

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

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

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

下载地址:https://github.com/containerd/nerdctl/releases

下载最新版本的nerdctl,解压到/usr/local/bin里:

tar zxvf nerdctl-0.17.1-linux-amd64.tar.gz -C /usr/local/bin/

# ls /usr/local/bin/
containerd-rootless-setuptool.sh  containerd-rootless.sh  nerdctl

# chmod a+x *

# nerdctl version
Client:
 Version:       v0.17.1
 Git commit:    20233c26d26f11ca73a9a775fba87ca884ab14d2

Server:
 containerd:
  Version:      1.4.13
  GitCommit:    9cc61520f4cd876b86e77edfeb88fbcd536d1f9d

使用教程文档地址:https://github.com/containerd/nerdctl

安装网络插件CNI

到 https://github.com/containernetworking/plugins/releases 下载最新版本CNI插件,解压放在/opt/cni/bin目录中。

mkdir -p /opt/cni/bin/
tar zxf cni-plugins-linux-amd64-v1.1.0.tgz -C /opt/cni/bin/

# cd /opt/cni/bin/ && ll
-rwxr-xr-x 1 root root 3780654 2月  24 01:01 bandwidth
-rwxr-xr-x 1 root root 4221823 2月  24 01:01 bridge
-rwxr-xr-x 1 root root 9738322 2月  24 01:01 dhcp
-rwxr-xr-x 1 root root 4345726 2月  24 01:01 firewall
-rwxr-xr-x 1 root root 3811793 2月  24 01:01 host-device
-rwxr-xr-x 1 root root 3241605 2月  24 01:01 host-local
-rwxr-xr-x 1 root root 3922560 2月  24 01:01 ipvlan
-rwxr-xr-x 1 root root 3295519 2月  24 01:01 loopback
-rwxr-xr-x 1 root root 3959868 2月  24 01:01 macvlan
-rwxr-xr-x 1 root root 3679140 2月  24 01:01 portmap
-rwxr-xr-x 1 root root 4092460 2月  24 01:01 ptp
-rwxr-xr-x 1 root root 3484284 2月  24 01:01 sbr
-rwxr-xr-x 1 root root 2818627 2月  24 01:01 static
-rwxr-xr-x 1 root root 3379564 2月  24 01:01 tuning
-rwxr-xr-x 1 root root 3920827 2月  24 01:01 vlan
-rwxr-xr-x 1 root root 3523475 2月  24 01:01 vrf

设置nerdctl子命令可以使用tab键

在/etc/profile里添加source <(nerdctl completion bash),如下:

# head -2 /etc/profile

# /etc/profile
source <(nerdctl completion bash)

# source /etc/profile

使用教程

# 拉取镜像
# nerdctl pull nginx:alpine

# 查看镜像
# nerdctl image ls         
REPOSITORY    TAG       IMAGE ID        CREATED          PLATFORM       SIZE         BLOB SIZE
nginx         alpine    da9c94bec1da    3 hours ago      linux/amd64    25.2 MiB     9.7 MiB

# 给镜像打tag
# nerdctl tag docker.io/library/nginx:alpine jdd.io/cka/nginx:v1

# nerdctl image ls
REPOSITORY          TAG       IMAGE ID        CREATED          PLATFORM       SIZE         BLOB SIZE
nginx               alpine    da9c94bec1da    3 hours ago      linux/amd64    25.2 MiB     9.7 MiB
jdd.io/cka/nginx    v1        da9c94bec1da    1 second ago     linux/amd64    25.2 MiB     9.7 MiB

# 创建容器
# nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
eca0bdc6ab6ffbb63216c1b975010959f1953fa4c95337d13a9d6ceceb489f77

# 查看创建的容器
# nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS                 NAMES
eca0bdc6ab6f    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    26 seconds ago    Up        0.0.0.0:80->80/tcp    nginx

# 进入容器内部
# nerdctl exec -it nginx /bin/sh

# 和 Docker 一样,Containerd 也有一个子命令network:
# nerdctl network ls
NETWORK ID    NAME      FILE
0             bridge    
              host      
              none 

# 查看默认的 bridge 配置 (可以看到 network 子命令背后还是 CNI 在运作,与 docker network 子命令原理不同。)
# nerdctl network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "0",
        "IPAM": {
            "Config": [
                {
                    "Subnet": "10.4.0.0/24",
                    "Gateway": "10.4.0.1"
                }
            ]
        },
        "Labels": {}
    }
]

构建镜像

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

需要安装 buildctl 并运行 buildkitd,这是因为 nerdctl build 需要依赖 buildkit 工具。
buildkit 项目也是 Docker 公司开源的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:

  • 服务端 buildkitd:当前支持 runc 和 containerd 作为 worker,默认是 runc,我们这里使用 containerd
  • 客户端 buildctl:负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求

buildkit 是典型的 C/S 架构,客户端和服务端是可以不在一台服务器上,而 nerdctl 在构建镜像的时候也作为 buildkitd 的客户端,所以需要安装并运行 buildkitd。

地址:https://github.com/moby/buildkit/releases

wget https://github.com/moby/buildkit/releases/download/v0.9.3/buildkit-v0.9.3.linux-amd64.tar.gz

将其解压到/usr/local里:

# tar -zxv -f buildkit-v0.9.3.linux-amd64.tar.gz -C /usr/local/
# cd /usr/local/bin && ls
-rwxr-xr-x 1 root root 25845982 10月 21 2015 buildctl
-rwxr-xr-x 1 root root 38767973 10月 21 2015 buildkitd
-rwxr-xr-x 1 root root  5024816 10月 21 2015 buildkit-qemu-aarch64
-rwxr-xr-x 1 root root  4009104 10月 21 2015 buildkit-qemu-arm
-rwxr-xr-x 1 root root  3662408 10月 21 2015 buildkit-qemu-i386
-rwxr-xr-x 1 root root  4554864 10月 21 2015 buildkit-qemu-mips64
-rwxr-xr-x 1 root root  4546672 10月 21 2015 buildkit-qemu-mips64el
-rwxr-xr-x 1 root root  4111432 10月 21 2015 buildkit-qemu-ppc64le
-rwxr-xr-x 1 root root  3844552 10月 21 2015 buildkit-qemu-riscv64
-rwxr-xr-x 1 root root  3444936 10月 21 2015 buildkit-qemu-s390x
-rwxr-xr-x 1 root root 20522896 10月 21 2015 buildkit-runc
-rwxr-xr-x 1 root root    18692 3月   3 18:21 containerd-rootless-setuptool.sh
-rwxr-xr-x 1 root root     6972 3月   3 18:21 containerd-rootless.sh
-rwxr-xr-x 1 root root 27738112 3月   3 18:22 nerdctl

编写 systemd unit 文件:

# cat /etc/systemd/system/buildkit.service
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit

[Service]
ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now buildkit.service # 启用 buildkit.service 并设置开机自动运行
[root@myrabbit3 jre_docker]# ll
总用量 12
-rw-r--r-- 1 root root 450 9月  27 17:06 Dockerfile
-rw-r--r-- 1 root root 556 4月  22 2021 localtime
-rw-r--r-- 1 root root  14 4月  22 2021 timezone

# nerdctl build -t jre_docker .
[+] Building 288.7s (13/13) FINISHED                                                                                                                                     
 => [internal] load build definition from Dockerfile                                                                                                                0.0s
 => => transferring dockerfile: 489B                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                   15.1s
 => [1/8] FROM docker.io/library/alpine:latest@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300                                              0.1s
 => => resolve docker.io/library/alpine:latest@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300                                              0.0s
 => => extracting sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3                                                                           0.1s
 => [internal] load build context                                                                                                                                   0.0s
 => => transferring context: 645B                                                                                                                                   0.0s
 => [2/8] COPY localtime /etc/localtime                                                                                                                             0.0s
 => [3/8] COPY timezone /etc/timezone                                                                                                                               0.0s
 => [4/8] RUN echo "https://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories                                                                  0.3s
 => [5/8] RUN echo "https://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories                                                            0.2s
 => [6/8] RUN ["apk","update"]                                                                                                                                      9.6s
 => [7/8] RUN ["apk","add","curl"]                                                                                                                                  4.5s
 => [8/8] RUN ["apk","add","openjdk8-jre"]                                                                                                                        253.1s
 => exporting to oci image format                                                                                                                                   5.6s 
 => => exporting layers                                                                                                                                             3.9s 
 => => exporting manifest sha256:6a86c31cf2017581ac44f201ed0f01fde75b1bcdb84ae78fd1e8781f66aaad06                                                                   0.0s 
 => => exporting config sha256:d7c7db923c7d874de7fbc83bf5887ad66373205e7572a74c5f013469deabb74c                                                                     0.0s 
 => => sending tarball                                                                                                                                              1.7s 
unpacking docker.io/library/jre_docker:latest (sha256:6a86c31cf2017581ac44f201ed0f01fde75b1bcdb84ae78fd1e8781f66aaad06)...done                                    


# 查看镜像
# nerdctl image ls
REPOSITORY          TAG       IMAGE ID        CREATED           PLATFORM       SIZE         BLOB SIZE
jre_docker          latest    6a86c31cf201    51 seconds ago    linux/amd64    109.2 MiB    70.3 MiB
nginx               alpine    da9c94bec1da    4 hours ago       linux/amd64    25.2 MiB     9.7 MiB
jdd.io/cka/nginx    v1        da9c94bec1da    24 minutes ago    linux/amd64    25.2 MiB     9.7 MiB