我有一个应用程序,执行各种有趣的东西与Git(像运行Git克隆& Git推送),我试图docker-ize它。

我遇到了一个问题,虽然我需要能够添加一个SSH密钥到容器的容器“用户”使用。

我试着把它复制到/root/。ssh/,更改$HOME,创建一个git ssh包装器,仍然没有运气。

以下是Dockerfile供参考:

#DOCKER-VERSION 0.3.4                                                           

from  ubuntu:12.04                                                              

RUN  apt-get update                                                             
RUN  apt-get install python-software-properties python g++ make git-core openssh-server -y
RUN  add-apt-repository ppa:chris-lea/node.js                                   
RUN  echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
RUN  apt-get update                                                             
RUN  apt-get install nodejs -y                                                  

ADD . /src                                                                       
ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa                             
RUN   cd /src; npm install                                                      

EXPOSE  808:808                                                                 

CMD   [ "node", "/src/app.js"]

App.js运行git命令,比如git pull


当前回答

这是现在可用的18.09版!

根据文档:

docker构建有一个——ssh选项来允许docker引擎 转发SSH代理连接。

下面是Dockerfile在容器中使用SSH的例子:

# 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 private repository
RUN --mount=type=ssh git clone git@github.com:myorg/myproject.git myproject

创建Dockerfile后,使用——ssh选项连接ssh代理:

$ docker build --ssh default .

另外,请查看https://medium.com/@tonistiigi/build- secrets.and -ssh-forwarding-in dock-18-09-ae8161d066

其他回答

如果您需要在构建时使用SSH,那么这个问题就更难解决了。例如,如果你使用git克隆,或者在我的情况下,pip和npm从私有存储库下载。

我发现的解决方案是使用——build-arg标志添加键。然后你可以使用新的实验——squash命令(添加1.13)来合并图层,这样键在删除后就不再可用了。以下是我的解决方案:

建造的命令

$ docker build -t example --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" --squash .

Dockerfile

FROM python:3.6-slim

ARG ssh_prv_key
ARG ssh_pub_key

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

# 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

# Avoid cache purge by adding requirements first
ADD ./requirements.txt /app/requirements.txt

WORKDIR /app/

RUN pip install -r requirements.txt

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

# Add the rest of the files
ADD . .

CMD python manage.py runserver

更新:如果你正在使用Docker 1.13并且有实验功能,你可以在build命令中添加——squash,它将合并层,删除SSH密钥并从Docker历史记录中隐藏它们。

以下是Docker容器中SSH所面临的挑战的简要概述。要从容器内连接到可信的远程而不泄漏机密,有以下几种方法:

SSH代理转发(只支持linux,不是直接的) 内置SSH,使用BuildKit(实验性,Compose还不支持) 使用绑定挂载来公开~/。SSH到容器。(仅限开发,潜在不安全) Docker Secrets(跨平台,增加复杂性)

除此之外,在使用Compose时,还可以使用在运行时可访问的独立docker容器中运行的密钥存储。这里的缺点是由于创建和管理密钥存储库(如HashiCorp的Vault)所需的机制而增加了复杂性。

对于在独立的Docker容器中使用SSH密钥,请参阅上面链接的方法,并根据您的具体需求考虑每种方法的缺点。然而,如果你在Compose中运行,并且想要在运行时共享一个应用程序的密钥(反映OP的实用性)试试这个:

创建一个docker-compose。Env文件并将其添加到.gitignore文件中。 更新docker-compose。Yml并为需要密钥的服务添加env_file。 在应用程序运行时从环境中访问公钥,例如process.node。Node.js应用中的DEPLOYER_RSA_PUBKEY。

上述方法非常适合开发和测试,虽然它可以满足生产需求,但在生产中,您最好使用上述其他方法之一。

额外的资源:

Docker文档:使用绑定挂载 Docker Docs:使用Docker机密管理敏感数据 堆栈溢出:在docker容器内使用SSH密钥 Stack Overflow:在macOS上使用ssh-agent和docker

为了在容器中注入ssh密钥,你有多种解决方案:

使用带有ADD指令的Dockerfile,你可以在构建过程中注入它 简单地执行cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa' 使用docker cp命令,允许您在容器运行时注入文件。

在docker(17.05)的后续版本中,您可以使用多阶段构建。哪个是最安全的选择,因为之前的构建只能被后续的构建使用,然后被销毁

有关更多信息,请参阅我的stackoverflow问题的答案

Docker容器应该被视为它们自己的“服务”。为了分离关注点,你应该分离功能:

1)数据应该在数据容器中:使用链接卷将repo克隆到。然后可以将该数据容器链接到需要它的服务。

2)使用一个容器来运行git克隆任务(即它唯一的任务是克隆),当你运行它时将数据容器链接到它。

3) ssh-key也一样:把它作为一个卷(如上所述),当你需要它时链接到git克隆服务

这样,克隆任务和密钥都是临时的,只在需要时才活动。

现在,如果你的应用程序本身是一个git接口,你可能会考虑直接使用github或bitbucket REST api来完成你的工作:这就是它们的设计目的。