在Docker中使用ssh-add - 无法打开与身份验证代理的连接

13

我正在尝试为我的Python Flask API创建一个Docker镜像。

我需要使用git安装依赖项,而且我已经在Docker中多次安装了git。但是在这里,我不明白我做错了什么。

使用Docker:

FROM python:3.6-slim

ARG ssh_prv_key
ARG ssh_pub_key

RUN apt-get update && \
    apt-get install -y openssh-server &&\
    apt-get install -y git

# Authorize SSH Host
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts

# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub && \
    echo "StrictHostKeyChecking no " > /root/.ssh/config


RUN eval "$(ssh-agent -s)"
RUN ssh-add /root/.ssh/id_rsa

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app/
RUN pip3 install --no-cache-dir -r requirements.txt

# Remove SSH keys
RUN rm -rf /root/.ssh/

COPY ./my_api /usr/src/app

# Expose the Flask port
EXPOSE 5000

CMD [ "python", "./app.py" ]

我执行了以下命令:
docker build --build-arg ssh_prv_key=.keys/id_rsa --build-arg ssh_pub_key=.keys/id_rsa.pub -t my-api -f Dockerfile . 

这导致我出现以下错误:

Step 7/16 : RUN eval "$(ssh-agent -s)"
 ---> Running in be450cc39533
Agent pid 9
Removing intermediate container be450cc39533
 ---> fb101226dc5f
Step 8/16 : RUN ssh-add /root/.ssh/id_rsa
 ---> Running in 4288e93db584
Could not open a connection to your authentication agent.
The command '/bin/sh -c ssh-add /root/.ssh/id_rsa' returned a non-zero code: 2

一个PID是通过eval函数从ssh-agent中检索出来的,但我无法连接到它。
已解决
最后我找到了问题所在。首先,我的构建参数不正确。正确的docker构建命令如下:
docker build --build-arg ssh_prv_key="$(cat .keys/id_rsa)" --build-arg ssh_pub_key="$(cat .keys/id_rsa.pub)" -t my-api -f Dockerfile . 

此外,我不知道为什么,git在没有使用ssh keys的情况下正确处理它。
RUN eval "$(ssh-agent -s)"
RUN ssh-add /root/.ssh/id_rsa  

执行上述命令会出现"无法连接到您的代理"错误。

正确的文件是

FROM python:3.6-slim

ARG ssh_prv_key
ARG ssh_pub_key

RUN apt-get update && \
    apt-get install -y git

# Authorize SSH Host
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts

# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub


RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app/
RUN pip3 install --no-cache-dir -r requirements.txt

# Remove SSH keys
RUN rm -rf /root/.ssh/

COPY ./my_api /usr/src/app

# Expose the Flask port
EXPOSE 5000

CMD [ "python", "./app.py" ]
3个回答

4
我认为这个问题与您的容器中的ssh配置有关,Ubuntu默认的ssh策略是拒绝root远程登录。
要启用它,请将以下行添加到您的Dockerfile中。
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
此行编辑/etc/ssh/sshd_config文件以允许root登录,但您需要重启sshd服务。为此,您还需要在Dockerfile中添加以下行。
RUN systemctl restart sshd
如果您信任证书,请在ssh-add后添加-K标志。
RUN ssh-add -k /root/.ssh/id_rsa
-k选项用于在向代理加载密钥或从代理中删除密钥时,仅处理纯私有密钥并跳过证书。
希望这可以帮助到您。 最好的问候,

在执行 RUN systemctl restart sshd 命令时,我遇到了以下错误:无法连接到总线:没有这样的文件或目录。 - Laurent GRENIER
现在的问题是你的init进程PID 1是/bin/bash而不是systemd。你可以尝试使用"RUN service sshd restart"。如果不行,可以尝试"RUN /etc/init.d/sshd restart"。 如果你只是用它作为客户端连接到另一个主机,那么你可以跳过这一步。 此外,检查一下这个问题,它可能会有所帮助:"https://askubuntu.com/questions/813588/systemctl-failed-to-connect-to-bus-docker-ubuntu16-04-container"。 - Ahmed Eldakhli
这是正确的方向,但如果无法帮助您解决问题,请参考此链接:https://dev59.com/fGMm5IYBdhLWcg3wIsQ2#52751261 - Braden Holt

3

不要编写这些命令:

RUN eval "$(ssh-agent -s)"
RUN ssh-add /root/.ssh/id_rsa  
RUN pip3 install --no-cache-dir -r requirements.txt

使用不同的RUN语句,在单一层中执行它们,例如:
RUN eval "$(ssh-agent -s)" && \
    ssh-add /root/.ssh/id_rsa && \
    pip3 install --no-cache-dir -r requirements.txt

我尝试了这个方法,没有遇到任何问题。


如果 RUN eval "$(ssh-agent -s)" && echo "$SSH_AUTH_SOCK" 返回类似路径的内容,那么这应该可以工作。 - Nae

0

最近,您可以使用build命令来指定ssh选项:https://docs.docker.com/compose/compose-file/build/#ssh

在docker-compose文件中的配置如下:

build:
  context: .
  ssh: 
    - default   # mount the default ssh agent

后期编辑(2022年7月30日):

这个SSH功能不久前被添加,关于实现它有一个很大的 GitHub 帖子。最近在CI/CD流水线项目中尝试使用它,并且发现docker-compose和SSH的命令行支持是缺失的。我们通过使用 docker build 命令来解决这个问题:

DOCKER_BUILDKIT=1 docker build --ssh default=${SSH_KEY_PATH} -t imagename .

然后,在 docker-compose 文件中使用新构建的镜像名称:

services:
  servicename:
    image: imagename
    container_name: containername
    ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接