nerdctl 安装
- containerd的默认命令行工具(crictl)也不是很好用,和docker也不兼容。
- nttlabs贡献了一个名为nerdctl的containerd客户端,可以兼容docker命令行工具。于是我们就可以使用nerdctl来作为docker的替代品了。
- nerdctl不仅与docker兼容,而且还支持了更多的功能: 1:支持containerd的命名空间查看,nerdctl不仅可以管理Docker容器,也可以直接管理本地的的Kubernetes pod 2:支持将Docker Image Manifest镜像转换为OCI镜像、estargz镜像 3:支持OCIcrypt(镜像加密)
- nerdctl的代码托管地址: https://github.com/containerd/nerdctl
- 安装:
# 下载nerdctl
wget https://breezey-public.oss-cn-zhangjiakou.aliyuncs.com/softwares/linux/kubernetes/nerdctl-full-0.14.0-linux-amd64.tar.gz
# 解压nerdctl
tar xf nerdctl-full-0.14.0-linux-amd64.tar.gz -C /usr/
# 验证
nerdctl ps -a
容器管理
运行容器
- 运行一个容器示例:
# 启动一个httpd容器,使其在后台运行并将其80端口映射到宿主机80端口
nerdctl run -d -p 80:80 httpd
- 将容器在前台运行:
# 启动一个ubuntu 16.04的容器,打印完"hello world"即退出
nerdctl run ubuntu:16.04 /bin/echo " hello world "
# 在前台运行容器并进入容器与容器交互
nerdctl run ubuntu:16.04 /bin/bash
需要说明的是,容器是为任务而生的。一个容器建议只运行一个进程,而且这个进程需要在容器的前台运行,不能通过daemon的方式运行。如果进程退出,容器也会随之停止
- 容器的启动过程说明:
- 检查本地是否存在指定的镜像,如果没有就从指定的仓库下载
- 利用镜像启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个IP给容器
- 执行用户指定的程序
- 执行完毕后停止容器
- 将容器放入后台运行:
nerdctl run -d ubuntu:16.04 /bin/bash -c "while true; do echo hello world; sleep 1;done"
- nerdctl run常用选项说明
- -t:配置一个伪终端并绑定到容器的标准输入上
- -i:让容器的标准输入保持打开
- -d:将容器放入后台运行
- -p: 为容器配置端口映射
- –dns: 为容器指定dns地址
- –name: 为容器指定名称
- -e:在容器启动时为其传递环境变量
- -workdir: 指定工作目录
- –restart:指定容器退出时是否重启
- –rm: 在容器退出时,自动删除
- -v:挂载数据卷
- 查看当前节点上的容器状态
nerdctl ps #查看当前正在运行的容器
选项:
-a:查看所有容器,包括停止的
-q:只显示容器ID
- 进入容器
nerdctl exec -it <容器id/容器name> /bin/bash
- 运行容器的最佳实践
容器按用途大致可分为两类:
- 服务类容器,如webserver、database等
- 工具类容器,如curl容器、redis-cli容器等
通常而言,服务类容器需要长期运行,所以使用daemon的方式运行;而工作类环境通常是给我们提供一个临时的工作环境,所以一般以run –ti的方式在前台运行
容器的启停操作
# 容器的启动:
nerdctl start <容器id>
# 容器的停止:
nerdctl stop <容器id>
nerdctl kill <容器id>
# 容器的重启:
nerdctl restart <容器id>
# 容器的删除:
nerdctl rm <容器id>
选项:
-f:强行终止并删除一个运行中的容器
-v:删除容器挂载的数据卷
# 暂停容器:
nerdctl pause <容器id>
# 从暂停中恢复:
nerdctl unpause <容器id>
容器生命周期管理
容器资源限制
一个宿主机上会运行若干容器,每个容器都需要CPU、内存和 IO 资源。对于 KVM,VMware等虚拟化技术,用户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Contianerd也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。
内存限制
- 启动一个ubuntu容器,限制内存为200M, 内存与swap的总和为300M:
nerdctl run -it -m 200M --memory-swap 300M ubuntu:16.04
- 选项说明:
-m:允许分配的内存大小
- 下面是一个压测示例:
nerdctl run -it -m 200M progrium/stress --vm 1 --vm-bytes 180M
选项:
--vm:设置内存工作线程数
--vm-byptes:设置单个内存工作线程使用的内存大小
上面的示例中,–vm-bytes为180M,容器工作正常;如果将其修改为230M,则容器OOM退出 关于内存资源的更多限制可以参考这里:https://blog.opskumu.com/docker-memory-limit.html
CPU限制
默认情况下,所有容器可以平等的使用宿主机cpu资源且没有限制。nerdctl可以通过--cpu-shares设置容器使用的cpu的权重,默认为1024。与内存限额不同,通过 —cpu-shares设置的 cpu share 并不是 CPU 资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。 换句话说:通过cpu share可以设置容器使用CPU的优先级。
- 例如,在host中启动了两个容器:
nerdctl run --name container_A --cpu-shares 1024 ubuntu:16.04
nerdctl run --name container_B --cpu-shares 512 ubuntu:16.04
container_A的cpu share 1024,是 container_B 的两倍。当两个容器都需要 CPU 资源时,container_A可以得到的 CPU 是container_B的两倍。
需要特别注意的是,这种按权重分配CPU只会发生在CPU 资源紧张的情况下。如果container_A 处于空闲状态,这时,为了充分利用CPU资源,container_B 也可以分配到全部可用的 CPU。
- 下面是一个压测示例:
# --cpu用于设置cpu工作线程的数量,有几个核就设置为几
nerdctl run --name "container_A" --cpu-shares 1024 progrium/stress --cpu 1
nerdctl run --name "container_B" --cpu-shares 512 progrium/stress --cpu 1
两个容器运行起来之后,可以通过在宿主机上使用top查看cpu的资源消耗可以看到两个容器的cpu消耗。 除了使用–cpu-shares设置cpu权重,也可以通过--cpus设置cpu的核心数。还可以通过设置–cpuset-cpus参数设置将当前容器的进程数绑定在指定cpu上运行。
关于cpu资源的更多限制可以参考这里:https://blog.opskumu.com/docker-cpu-limit.html
镜像管理
镜像命名规范
无论我们对镜像做何种操作,首先它得有个名字。我们在前面使用docker run来运行容器的时候,就需要传递一个镜像名称,容器基于该镜像来运行。
- 一个完整的镜像名称由两部分组成:
<imageName> = <repository>:[tag]
- 其中repository包含如下内容:
[Registry/][Namespace/]<Name>
- 所以一个完整的镜像命名如下:
[Registry/][Namespace/]<Name>:[tag]
- 示例:
hub.breezey.top/op-base/openresty:1.13
hub.breezey.top/op-base/php:7.0.31-fpm-centos7
mysql:5.6
ubuntu
当没指明镜像tag时,默认为latest,但latest没有任何特殊含义,在docker hub上很多repository将latest作为最新稳定版本的别名,但这只是一种约定,不是强制规定,一个repository可以有多个tag,而多个tag也可能对应同一个镜像
镜像基本操作
- 获取镜像
nerdctl pull centos:7 #直接从docker hub获取镜像
nerdct lpull registry.cn-zhangjiakou.aliyuncs.com/breezey/mysql:5.7 #从dockerpool获取镜像
- 查看镜像信息
nerdctl image ls
nerdctl inspect centos:7 #获取镜像的详细信息
- 为镜像创建tag
nerd tag centos:7 registry.cn-zhangjiakou.aliyuncs.com/breezey/centos:7
- 删除镜像(注:如果镜像有容器生成,需要先删除容器)
#如果一个镜像有多个tag,只会删除指定的tag,镜像本身不会删除,如果docker rmi后指定镜像ID,则所有tag都会被删除
nerdctl rmi centos:7
- 通过docker commit提交一个新镜像
nerdctl commit -m "Add a new file" -a "Breeze" a925cb40b3f0 test #使用a925cb40b3f0容器生成一个名为test的镜像
-a:指定作者
-m:相关说明信息
-p:提交时暂停容器运行
附录
1. runc命令运行异常
如果在使用nerdctl运行容器时出现如下错误:
需要更新下libseccomp包:
yum install -y libseccomp-devel
参考: https://github.com/moby/moby/issues/35906
当使用cri-containerd-cni 1.5.8版本时,runc报错通过安装libseccomp-devel无法修复,此时可使用nerdctl-full包中的runc替换cri-containerd-cni包中的runc即可。