docker 构建期间的 SSH 代理转发
SSH agent forwarding during docker build
在通过 dockerfile
构建 docker 图像时,我必须克隆一个 github 存储库。我将我的 public ssh 密钥添加到我的 git 中心帐户,我可以从我的 docker 主机克隆存储库。虽然我看到我可以在 docker 运行 like
时通过映射 $SSH_AUTH_SOCK
env 变量来使用 docker 主机的 ssh 密钥
docker run --rm -it --name container_name \
-v $(dirname $SSH_AUTH_SOCK):$(dirname $SSH_AUTH_SOCK) \
-e SSH_AUTH_SOCK=$SSH_AUTH_SOCK my_image
如何在 docker 构建期间执行相同的操作?
不幸的是,您无法将 ssh 套接字转发到构建容器,因为 Docker 目前不支持构建时间卷装载。
这个话题已经讨论很久了,参考GitHub下面的问题:
如您所见,已针对不同的用例多次请求此功能。到目前为止,维护人员一直在犹豫是否要解决这个问题,因为他们认为在构建期间安装卷会破坏可移植性:
the result of a build should be independent of the underlying host
如 this 讨论中所述。
这可以使用替代构建脚本来解决。例如,您可以创建一个 bash 脚本并将其放在 ~/usr/local/bin/docker-compose
或您最喜欢的位置:
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &
/usr/bin/docker-compose $@
然后在您的 Dockerfile 中,您将使用现有的 ssh 套接字:
...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
&& apk add --no-cache socat openssh \
&& /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
&& bundle install \
...
or any other ssh commands will works
现在您可以调用我们的自定义docker-compose build
。它会调用带有共享 ssh 套接字的实际 docker 脚本。
对于 Docker 18.09 及更高版本
您可以使用 Docker 的新功能将您现有的 SSH 代理连接或密钥转发给构建器。例如,这可以在构建期间克隆您的私有存储库。
步骤:
首先设置环境变量以使用新的BuildKit
export DOCKER_BUILDKIT=1
然后使用新的(实验性)语法创建 Docker 文件:
# syntax=docker/dockerfile:experimental
FROM alpine
# install ssh client and git
RUN apk add --no-cache openssh-client git
# download public key for github.com
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
# clone our private repository
RUN --mount=type=ssh git clone git@github.com:myorg/myproject.git myproject
并使用
构建图像
docker build --ssh default .
在此处阅读更多相关信息:https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066
这个也很有趣:
看起来像:
- 在主机上
mkfifo myfifo
nc -lk 12345 <myfifo | nc -U $SSH_AUTH_SOCK >myfifo
- 在 dockerfile 中
RUN mkfifo myfifo
RUN while true; do \
nc 172.17.0.1 12345 <myfifo | nc -Ul /tmp/ssh-agent.sock >myfifo \
done &
RUN export SSH_AUTH_SOCK=/tmp/ssh-agent.sock
RUN ssh ...
在通过 dockerfile
构建 docker 图像时,我必须克隆一个 github 存储库。我将我的 public ssh 密钥添加到我的 git 中心帐户,我可以从我的 docker 主机克隆存储库。虽然我看到我可以在 docker 运行 like
$SSH_AUTH_SOCK
env 变量来使用 docker 主机的 ssh 密钥
docker run --rm -it --name container_name \
-v $(dirname $SSH_AUTH_SOCK):$(dirname $SSH_AUTH_SOCK) \
-e SSH_AUTH_SOCK=$SSH_AUTH_SOCK my_image
如何在 docker 构建期间执行相同的操作?
不幸的是,您无法将 ssh 套接字转发到构建容器,因为 Docker 目前不支持构建时间卷装载。
这个话题已经讨论很久了,参考GitHub下面的问题:
如您所见,已针对不同的用例多次请求此功能。到目前为止,维护人员一直在犹豫是否要解决这个问题,因为他们认为在构建期间安装卷会破坏可移植性:
the result of a build should be independent of the underlying host
如 this 讨论中所述。
这可以使用替代构建脚本来解决。例如,您可以创建一个 bash 脚本并将其放在 ~/usr/local/bin/docker-compose
或您最喜欢的位置:
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &
/usr/bin/docker-compose $@
然后在您的 Dockerfile 中,您将使用现有的 ssh 套接字:
...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
&& apk add --no-cache socat openssh \
&& /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
&& bundle install \
...
or any other ssh commands will works
现在您可以调用我们的自定义docker-compose build
。它会调用带有共享 ssh 套接字的实际 docker 脚本。
对于 Docker 18.09 及更高版本
您可以使用 Docker 的新功能将您现有的 SSH 代理连接或密钥转发给构建器。例如,这可以在构建期间克隆您的私有存储库。
步骤:
首先设置环境变量以使用新的BuildKit
export DOCKER_BUILDKIT=1
然后使用新的(实验性)语法创建 Docker 文件:
# syntax=docker/dockerfile:experimental
FROM alpine
# install ssh client and git
RUN apk add --no-cache openssh-client git
# download public key for github.com
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
# clone our private repository
RUN --mount=type=ssh git clone git@github.com:myorg/myproject.git myproject
并使用
构建图像docker build --ssh default .
在此处阅读更多相关信息:https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066
这个也很有趣:
看起来像:
- 在主机上
mkfifo myfifo
nc -lk 12345 <myfifo | nc -U $SSH_AUTH_SOCK >myfifo
- 在 dockerfile 中
RUN mkfifo myfifo
RUN while true; do \
nc 172.17.0.1 12345 <myfifo | nc -Ul /tmp/ssh-agent.sock >myfifo \
done &
RUN export SSH_AUTH_SOCK=/tmp/ssh-agent.sock
RUN ssh ...