我正在尝试克隆一个包含子模块的存储库。主repo克隆正常,但当我在dockerfile中执行git submodule update --init --recursive
时,子模块抛出错误。
fatal: clone of 'git@github.com:jkeys089/lua-resty-hmac.git' into submodule path '/tmp/third-party/lua-resty-hmac' failed
Failed to clone 'third-party/lua-resty-hmac'. Retry scheduled
Cloning into '/tmp/third-party/lua-resty-jwt'...
load pubkey "/root/.ssh/id_rsa": invalid format
Warning: Permanently added the RSA host key for IP address '140.82.118.3' to the list of known hosts.
Load key "/root/.ssh/id_rsa": invalid format
git@github.com: Permission denied (publickey).
在图像中我有这个
# authorise ssh host
RUN mkdir /root/.ssh/ \
&& chmod 700 /root/.ssh \
&& ssh-keyscan github.com > /root/.ssh/known_hosts
# add key and set permission
RUN echo "${SSH_PRIVATE_KEY}" >> /root/.ssh/id_rsa \
&& echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub \
&& chmod 600 /root/.ssh/id_rsa.pub \
&& chmod 600 /root/.ssh/id_rsa
我无法控制子模块。我不确定我是否可以从git@github.com
更改为https以获取子模块。
我甚至尝试使用GITHUB_TOKEN
路由
# start up git and clone
RUN git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/" \
&& git clone https://github.com/GluuFederation/gluu-gateway.git /tmp \
&& cd /tmp/ \
&& git submodule update --init --recursive
下面是构建命令的一部分。build --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)"
请在这方面帮帮忙。真让人沮丧:(
8条答案
按热度按时间cdmah0mi1#
另一个可能的问题是,如果你使用Makefile来运行docker build命令。在这种情况下,Makefile中的命令看起来像这样:
Make
将换行符替换为空格(make shell)这意味着写入容器的ssh密钥具有不同的格式,从而产生上面的错误。
我无法找到一种方法来保留Makefile命令中的换行符,所以我采取了一种变通方法,将.ssh目录复制到docker构建环境中,通过Dockerfile复制文件,然后删除它们。
guicsvcw2#
如果密钥为“invalid format”,请尝试使用old PEM format重新生成它。
确保将公钥添加到您的GitHub帐户以进行正确的身份验证。
OP Shammir添加了注解:
我认为问题是在构建过程中没有任何东西从主机复制到Docker镜像。
在“
docker build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"
returning empty”中,Shammir使用dockito/vault
来管理私钥,但也将其配置为“AddKeysToAgent”:如果私钥不受密码保护(如上面的命令),则不需要3xiyfsfu3#
仅供参考。
我手动创建了一个私钥文件
key.id_rsa
并将内容粘贴到其中。但是当我用它来克隆git仓库时:钥匙的内容绝对正确。然后我试着用
ssh-keygen
把我的密钥和另一个生成的密钥进行比较,结果确实是无效格式。只是我的钥匙里有一行没完没了的新单词。
添加新的一行后,结束的关键,所有的工作愉快~什么惊喜!
[更新]:即使在Windows上也要使用
\n
而不是\r\n
。vwhgwdsa4#
此答案适用于Windows用户(尚未在Linux上尝试过)。
我搜索了很多答案和文章,但在构建我的docker镜像时仍然出现无效格式错误。
实际原因是,当我们将私钥文件的内容作为参数传递时,它们是在一行中传递的。转义字符被转换为空格,这对于密钥来说基本上是无效的格式。为了避免这个错误,有两种方法可以将私钥传递给docker镜像:
1.在docker文件中使用
COPY
命令复制私钥文件并在docker镜像中使用。这不是一个好的选择,因为它可能会暴露您的私钥。示例:COPY id_rsa /root/.ssh/id_rsa
1.这是一种黑客,我用它的工作。在文本编辑器中打开私钥文件,在私钥中的每一行末尾添加
\n
,并连接每一行以在一行中创建整个密钥。例如,生成的密钥看起来像这样:-----开始OPENSSH PRIVATE KEY-----b3BlbnNzaC1redjEAAAAABG5vvmUAAAAEbm9uZQAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACdmF7/Vo4m2FWPf+8uZRRF88dnsyj+z+lCWNWBrT8gAAAJh1tssodbbL -------END OPENSSH PRIVATE KEY-------
让它看起来像这样:
-----开始OPENSSH PRIVATE KEY-----
\n
b3BlbnNzaC1redjEAAAAABG5vvmUAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n
QyNTUxOQAAACdmF7/Vo4m2FWPf+8uZRRF88dnsyj+z+lCWNWBrT8gAAAJh1tssodbbL\n
--------END OPENSSH PRIVATE KEY------\n
将其保存在密钥文件中,并在构建docker image时将修改后的文件传递到参数中。
8ljdwjyq5#
确保最后一行后面有一个\n。我花了很长时间才想明白。
42fyovps6#
**不要使用
echo "${SSH_PRIVATE_KEY}" >> /root/.ssh/id_rsa
来传递私钥(公钥也是一样)。**我在尝试Load key "/root/.ssh/id_rsa": invalid format
时也遇到了类似的错误这导致了像
identity file /root/.ssh/id_rsa type -1 invalid format
和read_passphrase: can't open /dev/tty
这样的错误。正确的方法是使用
该解决方案解释说:我的私钥被错误地格式化了-而不是很多行,它被作为一行程序传递,你可能有任何其他格式问题,比如在开始或结束时忘记了“-”,或者在行的结尾有错误,比如缺少换行符格式或在行的结尾有一个额外的字母。
更多细节请参见Dockerfile: clone repo with passwordless private key. Errors: “authentication agent” or “read_passphrase: can't open /dev/tty”,主要思想来自Add private key to ssh-agent in docker file,它同样来自Gitlab CI/Docker:ssh-add一直在请求密码。
yvgpqqbh7#
在大多数情况下,由于安全风险,您不应该在容器中添加任何ssh密钥,因为任何人都可以获得ssh密钥,如果他们有权访问您的镜像。
类似地,Docker也不推荐使用ARG,因为您可以使用
docker history <image>
检索秘密。秘密被嵌入在构建的层中。您可以在这里找到更多详细信息https://docs.docker.com/engine/reference/builder/#arg推荐的方法是使用CI/CD将GitHub repo克隆到本地文件夹,然后使用COPY操作将代码复制到您的映像中。但是如果你真的想克隆你的GitHub仓库,有两种方法:
1.在构建https://render.com/docs/docker-secrets期间将secret装入卷。请注意,secret挂载具有root权限,因此如果您以非root用户身份读取secret,则会收到权限错误。
1.使用多阶段构建。你可以在第一个阶段使用gitsync镜像,克隆仓库,然后在第二个阶段将仓库的内容复制到你的镜像中。https://docs.docker.com/build/building/multi-stage/。通过这种方式,您可以将secret加载到第一阶段,克隆存储库,然后将工件复制到后面的阶段。最后阶段的形象将不会有任何痕迹,你的秘密,如果你这样做的正确。
克隆私有库并将其安装在最终映像中的示例:
shyt4zoc8#
在我的情况下,这是因为缺少尾随空行。