如何从Docker容器克隆Git存储库

Jim*_*Jim 6 git ssh-keys docker

我们有一个工具,需要克隆几个Git存储库以汇总文档数据。我们希望将该工具放在Docker容器中,以便在本地和Jenkins轻松运行它,并实现可重复性。

Git存储库托管在需要使用SSH密钥进行身份验证的专用服务器上。因此,Docker容器必须以某种方式获得对运行该容器的用户的SSH密钥的访问权限。

我们有一个约束列表:

  1. 我们希望将泊坞窗图像中嵌入的SSH密钥
  2. 我们希望用户构建Docker映像。我们认为Dockerfile不会启用可重现性,而已经生成的Docker映像可以
  3. 我们希望容器以root用户身份运行
  4. 我们使用运行容器的主机用户的SSH密钥
  5. 参数可被提供给该命令启动容器(-v-u,...)

问题:如果可能的话,我们如何实现?

有关:

Pie*_* B. 11

您可以使用类似:

echo "git-user:x:$(id -u):$(id -g):Git User:/tmp:/bin/bash" > /tmp/fake_passwd # See below why to use this
docker run \
   -u $(id -u):$(id -g) \
   -w /tmp \
   -v $HOME/.ssh:/path/to/.ssh \
   -v /tmp/fake_passwd:/etc/passwd  \
   --entrypoint sh \
   -it \
   alpine/git

  # commands in the container:
  $ export GIT_SSH_COMMAND='ssh -i /path/to/.ssh/id_rsa -o "StrictHostKeyChecking=no"'
  $ git clone [path to git repo]
Run Code Online (Sandbox Code Playgroud)

这将确保容器以与主机用户相同的UID / GID运行,从而能够读取密钥而无需更改其许可权或使用根权限。详细说明:

  • -u $(id -u):$(id -g) 设置容器用户以匹配主机用户
  • -w /tmp 确保我们在可以写入的目录中工作(我们还可以挂载一个我们具有读/写权限的卷,或使用该目录构建映像)
  • -v $HOME/.ssh:/path/to/.ssh 从主机挂载本地用户SSH密钥
  • --entrypoint sh并且-it特定于alpine/git进行交互式shell会话,因此您可能不需要在图像中使用它

为什么要挂载假/etc/passwd文件?

当您运行具有未知UID / GID(在中不存在的UID / GID)的基于Linux的容器(例如alpinedebian)时/etc/passwdgit clone命令可能会导致错误,并显示以下消息:

Cloning into 'myrepo'...
No user exists for uid 1000
fatal: Could not read from remote repository.
Run Code Online (Sandbox Code Playgroud)

通过挂载这个“伪” passwd文件,我们确保操作系统将识别正在运行容器的用户并允许我们的git clone命令起作用。我们的密码文件如下所示:

git-user:x:1000:1000:Git User:/tmp:/bin/bash
Run Code Online (Sandbox Code Playgroud)

大致意味着:

  • git-user UID 1000和GID 1000存在
  • 它的HOME目录是/tmp(它是可选的,但是该目录是可写的,并且避免发出警告git clone

通过设置/tmp(或在映像构建过程中可能创建的另一个目录),我们确保我们有一个可写的HOME目录,git-user该目录将防止出现警告,git clone指出无法创建.ssh目录

但是,如果您打算对容器运行其他任务,则可能会有其他副作用。

为什么要使用GIT_SSH_COMMAND

GIT_SSH_COMMAND='ssh -i /path/to/.ssh/id_rsa'将确保git clone使用我们的密钥,但这也可以使用ssh-agent完成-请参阅https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt

在我使用的示例中,-o "StrictHostKeyChecking=no" 但这可能是不安全的,另一种解决方案是使用git repo服务器主机密钥在容器中挂载一个已知的主机文件,并使用-o "UserKnownHostsFile=/path/to/KnownHostFile"


LeG*_*GEC 6

克隆主机上的存储库并将目录安装到 docker 映像中可以吗?

例如:

git clone github:repo1
git clone github:repo2
  ...

docker run -v repo1:/path/to/repo1 -v repo2:/path/to/repo2 ...
Run Code Online (Sandbox Code Playgroud)

  • 例如,它不适用于缺少 Git 的客户端。这就是为什么我们要“dockerizing”我们的工具,以实现可重复性。 (3认同)