Containerd 命令行工具 nerdctl

2023-10-17 15:26:35 浏览数 (2)

Containerd 命令行工具 nerdctl

王先森2023-08-092023-08-09

Containerd 命令行工具 nerdctl

前面我们介绍了可以使用 ctr 操作管理 containerd 镜像容器,但是大家都习惯了使用 docker cli,ctr 使用起来可能还是不太顺手,为了能够让大家更好的转到 containerd 上面来,社区提供了一个新的命令行工具:nerdctl。nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容 docker compose 的语法的,这就大大提高了直接将 containerd 作为本地开发、测试或者单机容器部署使用的效率。

安装

安装nerdctl

同样直接在 GitHub Release 页面下载对应的压缩包解压到 PATH 路径下即可:

代码语言:javascript复制
cd /server/tools
# 如果没有安装 containerd,则可以下载 nerdctl-full-<VERSION>-linux-amd64.tar.gz 包进行安装
wget https://github.com/containerd/nerdctl/releases/download/v1.5.0/nerdctl-1.5.0-linux-amd64.tar.gz
tar xf nerdctl-1.5.0-linux-amd64.tar.gz
mv nerdctl /bin/
# 检查结果
$ nerdctl version            
WARN[0000] unable to determine buildctl version: exec: "buildctl": executable file not found in $PATH 
Client:
 Version:       v1.5.0
 OS/Arch:       linux/amd64
 Git commit:    b33a58f288bc42351404a016e694190b897cd252
 buildctl:
  Version:

Server:
 containerd:
  Version:      v1.7.3
  GitCommit:    7880925980b188f4c97b462f709d0db8e8962aff
 runc:
  Version:      1.1.8
  GitCommit:    v1.1.8-0-g82f18fe0

安装buildkit

在镜像构建时需要我们安装 buildctl 并运行 buildkitd,这是因为 nerdctl build 需要依赖 buildkit 工具。

buildkit 项目也是 Docker 公司开源的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:

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

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

所以接下来我们先来安装 buildkit

代码语言:javascript复制
# 下载地址
wget https://github.com/moby/buildkit/releases/download/v0.12.1/buildkit-v0.12.1.linux-amd64.tar.gz

# 解压文件
cd /server/tools
mkdir /opt/buildkit && tar -zxvf buildkit-v0.12.1.linux-amd64.tar.gz -C /opt/buildkit/
ln -s /opt/buildkit/bin/buildctl /usr/local/bin/
ln -s /opt/buildkit/bin/buildkitd /usr/local/bin/

#使用Systemd来管理buildkitd,创建如下所示的systemd unit文件
cat >> /etc/systemd/system/buildkit.service <<EOF
[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
EOF

# 启动buildkitd
systemctl daemon-reload
systemctl enable buildkit --now
systemctl status buildkit

# 验证 nerdctl与buildctl
$ nerdctl version
Client:
 Version:       v1.5.0
 OS/Arch:       linux/amd64
 Git commit:    b33a58f288bc42351404a016e694190b897cd252
 buildctl:
  Version:      v0.12.1
  GitCommit:    bb857a0d49f45aa0ce9cd554b78d4075553e20f9

Server:
 containerd:
  Version:      v1.7.3
  GitCommit:    7880925980b188f4c97b462f709d0db8e8962aff
 runc:
  Version:      1.1.8
  GitCommit:    v1.1.8-0-g82f18fe0

常用nerdctl命令

k8s 默认使用k8s.io,而 nerdctl 默认使用 default namspace。如果需要查看 k8s 相关镜像需要加上”--namespace=k8s.io“来指定。

代码语言:javascript复制
nerdctl images --namespace=k8s.io
nerdctl -n=k8s.io images

或者在 nerdctl 配置文件中指定 nerdctl 默认使用 k8s.io namespace

代码语言:javascript复制
mkdir  /etc/nerdctl/
cat >> /etc/nerdctl/nerdctl.toml << EOF
namespace = "k8s.io"
EOF

Run&Exec

nerdctl rundocker run 类似可以使用 nerdctl run 命令运行容器,例如:

代码语言:javascript复制
$ nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0

可选的参数使用和 docker run 基本一直,比如 -i-t--cpus--memory 等选项,可以使用 nerdctl run --help 获取可使用的命令选项。

nerdctl exec

同样也可以使用 exec 命令执行容器相关命令,例如:

代码语言:javascript复制
$ nerdctl exec -it nginx /bin/sh
/ # date
Wed Aug  9 08:12:10 UTC 2023
/ # ls

容器管理

nerdctl ps:列出容器

使用 nerdctl ps 命令可以列出所有容器。

代码语言:javascript复制
$ nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                 NAMES
883a46df6f58    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    5 minutes ago    Up        0.0.0.0:80->80/tcp    nginx

同样可选的参数使用和 docker ps 基本一直,比如 -q-n 等选项,可以使用 nerdctl ps --help 获取可使用的命令选项。

nerdctl inspect:获取容器的详细信息。

代码语言:javascript复制
$ nerdctl inspect nginx

[
    {
        "Id": "883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0",
        "Created": "2023-08-09T08:09:23.347598372Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": true,
            "Pid": 2814,
            "ExitCode": 0,
            "Error": "",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "docker.io/library/nginx:alpine",
        "ResolvConfPath": "/var/lib/nerdctl/1935db59/containers/default/883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0/resolv.conf",
        "HostnamePath": "/var/lib/nerdctl/1935db59/containers/default/883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0/hostname",
        "LogPath": "/var/lib/nerdctl/1935db59/containers/default/883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0/883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0-json.log",
        "Name": "nginx",
        "RestartCount": 0,
        "Driver": "overlayfs",
        "Platform": "linux",
        "AppArmorProfile": "",
                "nerdctl/ports": "[{"HostPort":80,"ContainerPort":80,"Protocol":"tcp","HostIP":"0.0.0.0"}]",
                "nerdctl/state-dir": "/var/lib/nerdctl/1935db59/containers/default/883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0"
            }
        },
        "NetworkSettings": {
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "80"
                    }
                ]
            },
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "10.4.0.2",
            "IPPrefixLen": 24,
            "MacAddress": "4a:5b:f3:cf:cf:eb",
            "Networks": {
                "unknown-eth0": {
                    "IPAddress": "10.4.0.2",
                    "IPPrefixLen": 24,
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "4a:5b:f3:cf:cf:eb"
                }
            }
        }
    }
]

可以看到显示结果和 docker inspect 也基本一致的。

nerdctl logs:获取容器日志

查看容器日志是我们平时经常会使用到的一个功能,同样我们可以使用 nerdctl logs 来获取日志数据:

代码语言:javascript复制
$ nerdctl logs -f nginx
10.4.0.1 - - [09/Aug/2023:08:09:46  0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"

同样支持 -f-t-n--since--until 这些选项。

nerdctl stop:停止容器

代码语言:javascript复制
# stop属于重启重启
$ nerdctl stop nginx
nginx
$ nerdctl ps
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
$ nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS                 NAMES
883a46df6f58    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    15 minutes ago    Up        0.0.0.0:80->80/tcp    nginx
# kill 属于停止容器 容器状态属于为创建
$ nerdctl kill nginx
883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0
$ nerdctl ps 
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
$ nerdctl ps -a
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS     PORTS                 NAMES
883a46df6f58    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    17 minutes ago    Created    0.0.0.0:80->80/tcp    nginx

nerdctl rm:删除容器

代码语言:javascript复制
$ nerdctl rm nginx
container 883a46df6f5875a6afae26414b498f396ea5e8ca1c24f91f97a2695c7b187ec0 is in running status. unpause/stop container first or force 
$ nerdctl rm -f nginx

如果要强制删除同样可以使用 -f--force 选项来操作。

镜像管理

erdctl images:镜像列表

代码语言:javascript复制
$ nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED         PLATFORM       SIZE        BLOB SIZE
nginx         alpine    1713c88213a0    25 hours ago    linux/amd64    43.0 MiB    16.2 MiB
$ nerdctl -n=k8s.io images

nerdctl tag:镜像标签

使用 tag 命令可以为一个镜像创建一个别名镜像:

代码语言:javascript复制
$ nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED         PLATFORM       SIZE        BLOB SIZE
nginx         alpine    1713c88213a0    25 hours ago    linux/amd64    43.0 MiB    16.2 MiB
$ nerdctl tag nginx:alpine harbor.boysec.cn/course/nginx:alpine
$ nerdctl images
REPOSITORY                       TAG       IMAGE ID        CREATED          PLATFORM       SIZE        BLOB SIZE
nginx                            alpine    1713c88213a0    25 hours ago     linux/amd64    43.0 MiB    16.2 MiB
harbor.boysec.cn/course/nginx    alpine    1713c88213a0    6 seconds ago    linux/amd64    43.0 MiB    16.2 MiB

nerdctl pull:拉取镜像

代码语言:javascript复制
$ nerdctl pull docker.io/library/busybox:latest

nerdctl push:推送镜像

当然在推送镜像之前也可以使用 nerdctl login 命令登录到镜像仓库,然后再执行 push 操作。

可以使用 nerdctl login --username xxx --password xxx 进行登录,使用 nerdctl logout 可以注销退出登录。

nerdctl save:导出镜像

使用 save 命令可以导出镜像为一个 tar 压缩包。

代码语言:javascript复制
$ nerdctl save -o busybox.tar.gz busybox:latest
$ ls -lh busybox.tar.gz
-rw-r--r-- 1 root root 2.2M Aug  9 16:40 busybox.tar.gz

nerdctl rmi:删除镜像

代码语言:javascript复制
$ nerdctl rmi busybox
Untagged: docker.io/library/busybox:latest@sha256:3fbc632167424a6d997e74f52b878d7cc478225cffac6bc977eedfe51c7f4e79
Deleted: sha256:3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f

nerdctl load:导入镜像

使用 load 命令可以将上面导出的镜像再次导入:

代码语言:javascript复制
$ nerdctl load -i busybox.tar.gz
$ nerdctl images
REPOSITORY                       TAG       IMAGE ID        CREATED          PLATFORM       SIZE        BLOB SIZE
busybox                          latest    3fbc63216742    7 seconds ago    linux/amd64    4.1 MiB     2.1 MiB

使用 -i--input 选项指定需要导入的压缩包。

镜像构建

镜像构建是平时我们非常重要的一个需求,我们知道 ctr 并没有构建镜像的命令,而现在我们又不使用 Docker 了,那么如何进行镜像构建了,幸运的是 nerdctl 就提供了 nerdctl build 这样的镜像构建命令。

0 人点赞