在 Singularity/Apptainer 构建期间使用主机的 SSH 密钥

lua*_*tor 9 git ssh-keys singularity-container apptainer

当从定义文件构建 Singularity/Apptainer 映像时,是否有一种可移植的方法可以在构建过程中使主机系统的 SSH 密钥可用?

给出一些背景:

我有一个定义文件,在%post我使用 SSH 克隆私有 git 存储库的部分中,即:

git clone git@github.com:luator/private_repo.git
Run Code Online (Sandbox Code Playgroud)

此操作会失败,因为在构建期间主机系统的 SSH 密钥在容器中不可用。

我可能可以复制容器中的密钥,并在构建过程结束时将其从那里删除。但是,为此,我需要对定义文件中密钥的路径进行硬编码,这在路径不同的另一台计算机上使用相同的定义文件时很糟糕。git clone在构建过程中是否有更便携的方式来完成工作?

avi*_*610 5

此答案基于与 drdaved 在 Apptainer Slack 上的讨论。

我们发现执行此操作的方法是通过设置环境变量让 Apptainer 构建过程使用主机ssh-agentSSH_AUTH_SOCK。这样,如果主机上的代理知道您的密钥,则可以在构建期间在容器中使用它。

主机SSH_AUTH_SOCK上的必须绑定到容器中。检查您SSH_AUTH_SOCK在主机上的位置;如果它位于构建期间已绑定到容器中的目录中(例如/tmp),那么您就可以开始了。否则,您需要手动绑定它。套接字的常见位置类似于/run/user/1000/keyring/ssh,因此您可以添加--bind /run到容器构建命令中。

此方法的优点是密钥不会被复制到容器映像中。存储的唯一信息是主机ssh-agent运行的套接字。AFAIK 这不是一个安全问题。

请注意,我们必须做一些温和的技巧,因为主机上的环境变量不会传递到构建过程,并且无法在构建命令中直接设置环境变量。因此,我们设置 via --build-arg,并使用 build arg in%post来设置环境变量。

示例test.def文件:

Bootstrap: docker
From: ubuntu:latest

%post
    apt update
    apt install git -y

    export SSH_AUTH_SOCK={{ SSH_AUTH_SOCK }}
    git clone git@github.com:luator/private-repo.git
Run Code Online (Sandbox Code Playgroud)

构建命令(如果您的SSH_AUTH_SOCK 意愿已经绑定到容器):

apptainer build --build-arg SSH_AUTH_SOCK=$SSH_AUTH_SOCK test.sif test.def
Run Code Online (Sandbox Code Playgroud)

构建命令(如果您的SSH_AUTH_SOCK 意愿尚未绑定到容器,并且可以在 获取/run/...):

apptainer build --build-arg SSH_AUTH_SOCK=$SSH_AUTH_SOCK --bind /run test.sif test.def
Run Code Online (Sandbox Code Playgroud)