#container #container-image #docker #cp #kubernetes #copy #podman

bin+lib dcp

一个简单的工具,用于轻松复制容器文件系统

5 个版本

0.4.1 2022 年 10 月 31 日
0.4.0 2022 年 9 月 11 日
0.3.2 2022 年 9 月 5 日
0.3.1 2022 年 8 月 27 日
0.3.0 2022 年 8 月 15 日

#1811开发工具

每月 21 次下载

MIT 许可证

4MB
605

dcp: 将 docker cp 简化

GitHub Actions Latest version MIT licensed

摘要

容器是封装应用程序及其依赖项的优秀工具,允许应用程序以简化的方式在任何地方运行。一些容器镜像包含启动长时间运行的二进制文件的命令,而另一些则可能只包含需要环境可用的数据(例如,Kubernetes 集群)。例如,operator-framework bundlescrossplane packages 都使用容器镜像来存储 Kubernetes 清单。这些清单在集群上解包并可供最终用户使用。

使用容器镜像存储数据的一个缺点是它们是不透明的。无法快速了解镜像内部的内容,尽管哈希摘要有助于查看镜像是否已从先前的版本更改。选项是使用 docker cp 或类似工具,例如 podman 或 containerd。

单独使用 docker cp 可能会很麻烦。假设你在一个注册表中有一个远程镜像。你必须拉取该镜像,从该镜像创建一个容器,然后才能运行 docker cp <container-id>,使用一个不直观的语法来选择要复制到本地文件系统的内容。

dcp 是一个简单的二进制文件,试图简化此工作流程。用户只需说 dcp <image-name>,它就可以将镜像内容提取到本地文件系统。它还可以直接将镜像内容打印到 stdout,而不创建任何本地文件。

安装

从 crates.io 安装

如果你是 Rust 程序员并且已经在本地上安装了 Rust,你可以通过简单地输入 cargo install dcp 安装 dcp,这将从 crates.io 获取最新版本。

下载编译后的二进制文件

发布部分提供了不同平台的预编译版本的dcp。Linux、macOS和Windows(实验性)的二进制文件已预先构建。对于macOS,提供了arm和x86目标,而对于Linux,仅提供x86。如果您的系统不受支持,可以从源代码构建dcp。

从源代码构建

要从源代码构建,请确保您已本地安装了rust工具链。此项目不依赖于nightly版本,并使用1.62-stable工具链。克隆仓库并运行cargo build --release以构建二进制的发布版本。从那里,您可以将二进制文件移动到您的$PATH中的一个文件夹中,以便轻松访问。

实现

由于在编写时没有合适的Rust语言实现的containerd客户端,因此dcp依赖于外部docker和podman包提供的API。这限制了dcp只能在docker或podman作为容器运行时的工作系统中运行。

默认情况下,dcp将在标准路径中查找要连接的活动docker套接字。如果docker套接字不可用,则dcp将回退到当前用户的podman套接字,基于$XDG_RUNTIME_DIR环境变量。

如果docker套接字位于远程主机或自定义位置,请使用带有自定义套接字路径的-s标志。

标志和示例

默认情况下,dcp将内容复制到当前目录.。例如,让我们尝试以下命令

$ dcp tyslaton/sample-catalog:v0.0.4 -c configs

此命令将从图像复制configs目录(通过-c标志指定)到当前目录。

为了进一步配置,让我们尝试

$ dcp tyslaton/sample-catalog:v0.0.4 -d output -c configs

此命令将下载请求的图像,仅提取configs目录并将其复制到本地output目录(通过-d标志指定)。

另一个示例,仅复制manifests目录

$ dcp quay.io/tflannag/bundles:resolveset-v0.0.2 -c manifests

最后,我们可以通过提供用户名和密码(通过-u--p标志指定)来引用私有注册表。

$ dcp quay.io/tyslaton/sample-catalog-private:latest -u <username> -p <password>

注意:这可以作为连接到私有注册表的方便方式,但在本地不安全,因为您的凭据保存在您的shell历史记录中。如果您想保持完全安全,请通过<container_runtime> login登录并本地提取图像。然后,dcp将能够注意到本地提取的图像并进行处理。

常见问题解答

Q:在解压缩图像的根文件系统时遇到意外的错误:trying to unpack outside of destination path。我如何避免这种情况?

A:dcp依赖于底层以tar文件表示的图像文件系统的Rust库tar来解压缩图像。unpack方法非常敏感,它不会将文件写入指定目标路径之外。因此,符号链接在解压缩时会引发错误。在可能的情况下,使用-c标志指定要解压缩的目录,而不是文件系统根目录,以避免此错误。


Q:我想使用dcp从图像中提取内容,但我不知道内容在图像中的存储位置。在dcp中是否有类似于ls的命令或类似功能?

A:检查优秀的dive 工具,通过层轻松地探索容器文件系统。找到要复制的文件路径后,然后可以使用 dcp 提取这些特定的文件。


:dcp 在 Windows 上支持吗?

A:是的,dcp 在 Windows 上支持。Windows 支持是实验性的,因为没有 CI 覆盖,但它可能在您的 Windows 环境中工作。您需要做的唯一非默认更改是暴露 docker 守护进程,以便 dcp 可以连接到它。这可以通过以下两种方式之一完成:

  1. 将以下内容添加到您的 %userprofile%\.docker\daemon.json 文件。

    {
        "hosts": ["tcp://0.0.0.0:2375"]
    }
    
  2. 通过 Docker Desktop UI,在 General 下的 Expose daemon on tcp://localhost:2375 without TLS 中启用设置。


:我想检查镜像标签,以确定我应该从文件系统中的哪个位置复制。dcp 有 inspect 命令来列出镜像标签吗?

A:可以使用底层容器运行时轻松列出镜像的标签。例如,运行 docker image inspect <image-id> | grep Labels 来查看附加到镜像的标签。从那里,可以使用 dcp 从容器文件系统中复制文件。

测试

如果您想运行测试套件,只需运行标准的 cargo 命令。这将运行所有相关的单元、集成和文档测试。

$ cargo test

依赖关系

~14–28MB
~430K SLoC