cntr

cntr

便携式容器调试工具 轻松挂载开发环境

cntr是一款容器调试工具,能够将宿主机或其他容器的文件系统挂载到目标容器中,无需修改容器本身。这使开发人员可以在调试时使用所需工具,同时保持生产容器的精简。cntr支持Docker、Podman、LXC等多种容器引擎,提供命令行界面。它利用FUSE文件系统创建嵌套容器,实现高效的文件访问。cntr为容器开发和调试提供了灵活的解决方案,适用于各种容器环境。

cntr容器命令行工具调试文件系统Github开源项目

cntr

不要在容器中使用 $ apt install vimcntrdocker exec 的替代品,可以让你带上所有开发工具。 它通过使用 FUSE 文件系统创建嵌套容器,将一个容器或主机的文件系统挂载到目标容器中。 这样可以在生产环境中使用最小化的运行时镜像,并限制漏洞利用的表面。

Cntr 还发表在 Usenix ATC 2018 上。 引用请参见 bibtex

演示

在这个两分钟的录像中,你可以学习 cntr 的所有基础知识:

asciicast

特性

  • 为了方便,cntr 原生支持以下容器引擎的容器名称/标识符:
    • docker
    • podman
    • LXC
    • LXD
    • rkt
    • systemd-nspawn
    • containerd
  • 对于其他容器引擎,cntr 也可以使用进程 ID (PID) 而不是容器名称。

安装

Cntr 只支持 Linux。

预编译的静态链接二进制文件

对于 linux x86_64,我们为每个发布版本构建静态二进制文件。可以根据需求添加更多平台。 预编译的压缩包可以在发布页面找到。 运行时只需要相关容器引擎的命令行工具。

从源码构建

编译只需要 rust + cargo。 查看 rustup.rs 了解如何获取可用的 rust 工具链。 然后运行:

方法一:

$ cargo install cntr

或者安装最新的主分支:

$ cargo install --git https://github.com/Mic92/cntr

对于离线构建,我们还提供了一个包含所有依赖的压缩包,可以在这里找到,用于使用 cargo-vendor 进行编译。

使用方法

Cntr 主要提供两个子命令:attachexec

  • attach:允许你使用自己的本地 shell/命令附加到容器。 Cntr 会将容器挂载到 /var/lib/cntr。 容器本身将不受影响地运行,因为挂载更改对容器进程不可见。
    • 示例:cntr attach <container_id>,其中 container_id 可以是容器标识符或进程 ID(参见下面的示例)。
  • exec:一旦进入容器,你还可以运行容器文件系统中的命令。由于这些命令可能需要它们的原生挂载布局在 / 而不是 /var/lib/cntr,cntr 提供 exec 子命令再次 chroot 到容器,并重置可能被 shell 更改的环境变量。
    • 示例:cntr exec <command>,其中 command 是容器中的可执行文件

注意:Cntr 需要在与容器相同的主机上运行。如果容器在虚拟机中运行而 cntr 在虚拟机管理程序上运行,则无法工作。

$ cntr --help Cntr 1.5.1 Jörg Thalheim <joerg@thalheim.io> 进入或在容器中执行命令 用法: cntr <子命令> 选项: -h, --help 打印帮助信息 -V, --version 打印版本信息 子命令: attach 进入容器 exec 在容器文件系统中执行命令 help 打印此消息或给定子命令的帮助
$ cntr attach --help cntr-attach 1.5.1 Jörg Thalheim <joerg@thalheim.io> 进入容器 用法: cntr attach [选项] <id> [命令]... 选项: -h, --help 打印帮助信息 --effective-user <EFFECTIVE_USER> 应该成为主机上新创建文件所有者的有效用户名 -t, --type <TYPE> 要尝试的容器类型(用','分隔)。[默认:除 command 外的所有类型] [可能的值:process_id, rkt, podman, docker, nspawn, lxc, lxd, containerd, command] 参数: <id> 容器 ID、容器名称或进程 ID <命令>... 附加后要执行的命令及其参数。考虑在前面加上 '-- ' 以防止解析 '-x' 类的标志。[默认:$SHELL]
$ cntr exec --help cntr-exec 1.5.1 Jörg Thalheim <joerg@thalheim.io> 在容器文件系统中执行命令 用法: cntr exec [命令]... 选项: -h, --help 打印帮助信息 -V, --version 打印版本信息 参数: <命令>... 附加后要执行的命令及其参数。考虑在前面加上 '-- ' 以防止解析 '-x' 类的标志。[默认:$SHELL]

Docker

1: 找出容器名称/容器 ID:

$ docker run --name boxbusy -ti busybox $ docker ps 容器 ID 镜像 命令 创建时间 状态 端口 名称 55a93d71b53b busybox "sh" 22 秒前 运行中 boxbusy

可以提供容器 ID...

$ cntr attach 55a93d71b53b [root@55a93d71b53b:/var/lib/cntr]# echo "我在一个容器里!" [root@55a93d71b53b:/var/lib/cntr]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@55a93d71b53b:/var/lib/cntr]# vim etc/resolv.conf

...或容器名称。 使用cntr exec来执行容器原生命令(在cntr shell中运行时)。

$ cntr attach boxbusy [root@55a93d71b53b:/var/lib/cntr]# cntr exec -- sh -c 'busybox | head -1'

你也可以使用此仓库中的Dockerfile来构建一个带有cntr的docker容器:

$ docker build -f Dockerfile . -t cntr # boxbusy是要附加到的目标容器的名称 $ docker run --pid=host --privileged=true -v /var/run/docker.sock:/var/run/docker.sock -ti --rm cntr attach boxbusy /bin/sh

Podman

参见docker用法,只需将docker替换为podman命令。

LXD

1: 创建一个容器并启动它

$ lxc image import images:/alpine/edge $ lxc launch images:alpine/edge $ lxc list +-----------------+---------+------+------+------------+-----------+ | 名称 | 状态 | IPV4 | IPV6 | 类型 | 快照数量 | +-----------------+---------+------+------+------------+-----------+ | amazed-sailfish | RUNNING | | | PERSISTENT | 0 | +-----------------+---------+------+------+------------+-----------+

2: 使用cntr附加到容器

$ cntr attach amazed-sailfish $ cat etc/hostname amazed-sailfish

LXC

1: 创建一个容器并启动它

$ lxc-create --name ubuntu -t download -- -d ubuntu -r xenial -a amd64 $ lxc-start --name ubuntu -F ... Ubuntu 16.04.4 LTS ubuntu console ubuntu login: $ lxc-ls ubuntu

2: 使用cntr附加到容器:

$ cntr attach ubuntu [root@ubuntu2:/var/lib/cntr]# cat etc/os-release NAME="Ubuntu" VERSION="16.04.4 LTS (Xenial Xerus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 16.04.4 LTS" VERSION_ID="16.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" VERSION_CODENAME=xenial UBUNTU_CODENAME=xenial

rkt

1: 查找容器uuid:

$ rkt run --interactive=true docker://busybox $ rkt list UUID APP 镜像名称 状态 创建时间 启动时间 网络 c2d2e87e busybox registry-1.docker.io/library/busybox:latest 运行中 6分钟前 6分钟前 default:ip4=172.16.28.3

2: 使用cntr附加

# 确保你的容器仍在运行! $ cntr attach c2d2e87e # 终于不是旧的丑陋的top了! [gen0@rkt-c2d2e87e-e798-4341-ae93-26f6cbb7c017:/var/lib/cntr]# htop ...

使用cntr你还可以调试rkt的stage1 - 即使rkt本身不支持。

$ ps aux | grep stage1 joerg 13546 0.0 0.0 120808 1608 pts/12 S+ 11:10 0:00 grep --binary-files=without-match --directories=skip --color=auto stage1 root 22232 0.0 0.0 54208 2656 pts/7 S+ 10:54 0:00 stage1/rootfs/usr/lib/ld-linux-x86-64.so.2 stage1/rootfs/usr/bin/systemd-nspawn --boot --notify-ready=yes --register=true --link-journal=try-guest --quiet --uuid=c2d2e87e-e798-4341-ae93-26f6cbb7c017 --machine=rkt-c2d2e87e-e798-4341-ae93-26f6cbb7c017 --directory=stage1/rootfs --capability=CAP_AUDIT_WRITE,CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FSETID,CAP_FOWNER,CAP_KILL,CAP_MKNOD,CAP_NET_RAW,CAP_NET_BIND_SERVICE,CAP_SETUID,CAP_SETGID,CAP_SETPCAP,CAP_SETFCAP,CAP_SYS_CHROOT -- --default-standard-output=tty --log-target=null --show-status=0

因此我们使用进程ID而不是容器uuid:

$ cntr attach 22232
# 新的令人兴奋的领域!
[root@turingmachine:/var/lib/cntr]# mount | grep pods
sysfs on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys type sysfs (ro,nosuid,nodev,noexec,relatime)
tmpfs on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /var/lib/cntr/var/lib/rkt/pods/run/c2d2e87e-e798-4341-ae93-26f6cbb7c017/stage1/rootfs/sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)

systemd-nspawn

1: 启动容器

$ wget https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-root.tar.xz
$ mkdir /var/lib/machines/ubuntu
$ tar -xf ubuntu-16.04-server-cloudimg-amd64-root.tar.xz -C /var/lib/machines/ubuntu
$ systemd-nspawn -b -M ubuntu
$ machinectl list
MACHINE CLASS     SERVICE        OS     VERSION ADDRESSES
ubuntu  container systemd-nspawn ubuntu 16.04   -

2: 附加

$ cntr attach ubuntu

通用进程ID

cntr需要的最少信息是你想要附加的容器进程的进程ID。

# 你知道chromium也使用命名空间吗?
$ ps aux | grep 'chromium --type=renderer'
joerg    17498 11.7  1.0 1394504 174256 ?      Sl   15:16   0:08 /usr/bin/chromium

在这种情况下,17498就是我们要找的pid。

$ cntr attach 17498
# 看起来和我们的系统很相似,但用户更少
[joerg@turingmachine cntr]$ ls -la /
total 240
drwxr-xr-x   23 nobody nogroup    23 Mar 13 15:05 .
drwxr-xr-x   23 nobody nogroup    23 Mar 13 15:05 ..
drwxr-xr-x    2 nobody nogroup     3 Mar 13 15:14 bin
drwxr-xr-x    4 nobody nogroup 16384 Jan  1  1970 boot
drwxr-xr-x   24 nobody nogroup  4120 Mar 13 14:56 dev
drwxr-xr-x   52 nobody nogroup   125 Mar 13 15:14 etc
drwxr-xr-x    3 nobody nogroup     3 Jan  8 16:17 home
drwxr-xr-x    8 nobody nogroup     8 Feb  9 22:10 mnt
dr-xr-xr-x  306 nobody nogroup     0 Mar 13 09:38 proc
drwx------   22 nobody nogroup    43 Mar 13 15:09 root
...

Containerd

对于containerd集成,需要ctr二进制文件。你可以通过运行以下命令获取二进制文件:

$ GOPATH=$(mktemp -d)
$ go get github.com/containerd/containerd/cmd/ctr
$ $GOPATH/bin/ctr --help

将生成的ctr二进制文件放入你的$PATH

1: 启动容器

$ ctr images pull docker.io/library/busybox:latest
$ ctr run docker.io/library/busybox:latest boxbusy
$ ctr tasks lists
TASK        PID      STATUS
boxbusy    24310    RUNNING

2: 附加

$ cntr attach boxbusy

也可以从容器本身运行cntr。 这个仓库包含了一个示例Dockerfile:

$ docker build -f Dockerfile.example . -t cntr
$ docker save cntr > cntr.tar
$ ctr images import --base-name cntr ./cntr.tar

在这个例子中,我们通过进程ID附加到containerd。任务的进程ID在ctr tasks list中给出。

$ ctr run --privileged --with-ns pid:/proc/1/ns/pid --tty docker.io/library/cntr:latest cntr /usr/bin/cntr attach 31523 /bin/sh

要解析containerd名称,还需要将ctr二进制文件(~12MB)添加到Dockerfile中。

附加配置

ZFS

cntr需要在ZFS下启用POSIX ACL。默认情况下,Linux ZFS没有启用POSIX ACL。这会导致在尝试attach时出现以下错误:

unable to move container mounts to new mountpoint: EOPNOTSUPP: Operation not supported on transport endpoint

要在ZFS数据集上启用POSIX ACL:

$ zfs set acltype=posixacl zpool/media
$ zfs set xattr=sa zpool/media              # 可选,但建议使用以获得最佳性能

工作原理

Cntr与容器无关:它不与容器引擎交互,而是实现底层操作系统API。它将每个容器视为一组可以继承属性的进程。

Cntr继承以下容器属性:

  • 命名空间(mount、uts、pid、net、cgroup、ipc)
  • Cgroups
  • Apparamor/selinux
  • 能力
  • 用户/组ID
  • 环境变量
  • 以下文件:/etc/passwd、/etc/hostname、/etc/hosts、/etc/resolv.conf

在底层,它会生成一个继承容器完整上下文的shell或用户定义的程序,并将自身作为fuse文件系统挂载。

我们使用xfstests和广泛的文件系统性能基准测试(iozone、pgbench、dbench、fio、fs-mark、postmark等)对cntr文件系统的正确性和性能进行了广泛的评估。

相关项目

  • nsenter
    • 仅涵盖Linux命名空间,用户仅限于使用容器内安装的工具
  • toolbox
    • 实现了从容器连接到主机,这与Cntr的功能相反

Bibtex

我们在Usenix ATC 2018上发表了一篇包含Cntr所有技术细节的论文。

@inproceedings{cntr-atc18, author = {J{\"o}rg Thalheim and Pramod Bhatotia and Pedro Fonseca and Baris Kasikci}, title = {Cntr: 轻量级操作系统容器}, booktitle = {2018 {USENIX} 年度技术会议 ({USENIX} {ATC} 18)}, year = {2018}, }

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

热门AI工具生产力协作转型TraeAI IDE
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

聊天机器人AI助手热门AI工具AI对话
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

热门AI工具AI办公办公工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

模型训练热门AI工具内容创作智能问答AI开发讯飞星火大模型多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

AI助手热门AI工具AI创作AI辅助写作讯飞绘文内容运营个性化文章多平台分发
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多