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
:
# 下载地址
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
“来指定。
nerdctl images --namespace=k8s.io
nerdctl -n=k8s.io images
或者在 nerdctl
配置文件中指定 nerdctl
默认使用 k8s.io namespace
mkdir /etc/nerdctl/
cat >> /etc/nerdctl/nerdctl.toml << EOF
namespace = "k8s.io"
EOF
Run&Exec
nerdctl run和 docker run
类似可以使用 nerdctl run
命令运行容器,例如:
$ 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
命令执行容器相关命令,例如:
$ nerdctl exec -it nginx /bin/sh
/ # date
Wed Aug 9 08:12:10 UTC 2023
/ # ls
容器管理
nerdctl ps:列出容器
使用 nerdctl ps
命令可以列出所有容器。
$ 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
来获取日志数据:
$ 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
命令可以为一个镜像创建一个别名镜像:
$ 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
压缩包。
$ 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
命令可以将上面导出的镜像再次导入:
$ 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
这样的镜像构建命令。