[ssh-keys] 도커 컨테이너 내에서 SSH 키 사용

git clone & git push 실행과 같은 Git을 사용하여 다양한 재미있는 물건을 실행하는 앱이 있으며도 커화하려고합니다.

컨테이너 ‘user’가 사용할 컨테이너에 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



답변

빌드시 SSH를 사용해야하는 경우 더 어려운 문제입니다. 예를 들어, 당신은 사용하는 경우 git clone, 또는 내 경우 pipnpm개인 저장소에서 다운로드.

내가 찾은 해결책은 --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 .

도커 파일

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을 사용하고 실험 기능 --squash이있는 경우 레이어를 병합하는 빌드 명령에 추가 하여 SSH 키를 제거하고에서 숨길 수 있습니다 docker history.


답변

Ubuntu를 사용할 때 ssh_config가 올바르지 않습니다. 당신은 추가해야합니다

RUN  echo "    IdentityFile ~/.ssh/id_rsa" >> /etc/ssh/ssh_config

ssh 키를 인식하기 위해 Dockerfile에 연결하십시오.


답변

노트 :이 방법은 개인 이미지 이며 항상 사용되는 이미지에만 사용하십시오 !

ssh 키는 추가 한 후에 레이어 명령에서 키를 제거하더라도 이미지 내에 저장된 상태로 유지됩니다 ( 이 게시물의 주석 참조 ).

내 경우에는 이것이 정상이므로 이것이 내가 사용하는 것입니다.

# Setup for ssh onto github
RUN mkdir -p /root/.ssh
ADD id_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa
RUN echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config


답변

docker compose를 사용하는 경우 SSH 에이전트를 다음과 같이 전달하는 쉬운 선택이 있습니다.

something:
    container_name: something
    volumes:
        - $SSH_AUTH_SOCK:/ssh-agent # Forward local machine SSH key to docker
    environment:
        SSH_AUTH_SOCK: /ssh-agent


답변

Peter Grainger의 답변을 확장 하여 Docker 17.05부터 다단계 빌드 를 사용할 수있었습니다 . 공식 페이지 상태 :

다단계 빌드에서는 FROMDockerfile에서 여러 명령문 을 사용 합니다. 각 FROM명령어는 다른베이스를 사용할 수 있으며 각 명령어는 새로운 빌드 단계를 시작합니다. 최종 이미지에서 원하지 않는 모든 것을 남겨두고 한 단계에서 다른 단계로 아티팩트를 선택적으로 복사 할 수 있습니다.

이 점을 염두에 두는 것은 Dockerfile세 가지 빌드 단계 를 포함하는 나의 예입니다 . 클라이언트 웹 애플리케이션의 프로덕션 이미지를 작성하기위한 것입니다.

# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
    echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
    printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
    yarn --pure-lockfile --mutex file --network-concurrency 1 && \
    rm -rf /root/.ssh/

# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod

# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]

.dockerignore의 내용을 반복 .gitignore(그것을 방지 파일 node_modules및 결과 dist복사되는 프로젝트의 디렉토리) :

.idea
dist
node_modules
*.log

이미지를 빌드하는 명령 예 :

$ docker build -t ezze/geoport:0.6.0 \
  --build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
  --build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
  ./

개인 SSH 키에 암호가 없으면 빈 SSH_KEY_PASSPHRASE인수를 지정하십시오 .

이것이 작동하는 방식입니다.

1). 첫 번째 단계에서 package.json, yarn.lock파일과 개인 SSH 키라는 이름의 첫 번째 중간 이미지로 복사됩니다 sources. 더 이상의 SSH 키 암호 문구 프롬프트를 피하기 위해 자동으로 추가됩니다 ssh-agent. 드디어yarn 명령은 NPM에서 필요한 모든 종속성을 설치하고 SSH를 통해 Bitbucket에서 개인 git 리포지토리를 복제합니다.

2). 두 번째 단계는 웹 애플리케이션의 소스 코드를 빌드 및 축소 dist하여 다음 중간 이미지의 디렉토리에 배치합니다 production. 설치된 소스 코드 는 첫 번째 단계에서 생성 된 node_modules이미지에서 sources다음 줄로 복사됩니다 .

COPY --from=sources /app/ /app/

아마도 다음 줄이 될 수도 있습니다.

COPY --from=sources /app/node_modules/ /app/node_modules/

node_modules여기 첫 번째 중간 이미지의 디렉토리 만 SSH_KEY있으며 SSH_KEY_PASSPHRASE더 이상 인수가 없습니다. 빌드에 필요한 나머지는 모두 프로젝트 디렉토리에서 복사됩니다.

삼). 세 번째 단계 에서는 이름이 지정된 두 번째 중간 이미지의 디렉토리 ezze/geoport:0.6.0만 포함 하고 웹 서버를 시작하기 위해 Node Express를 설치 하여 태그 될 최종 이미지의 크기를 줄 입니다.distproduction

이미지 나열은 다음과 같은 출력을 제공합니다.

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ezze/geoport        0.6.0               8e8809c4e996        3 hours ago         717MB
<none>              <none>              1f6518644324        3 hours ago         1.1GB
<none>              <none>              fa00f1182917        4 hours ago         1.63GB
node                carbon              b87c2ad8344d        4 weeks ago         676MB

태그가 지정되지 않은 이미지는 첫 번째 및 두 번째 중간 빌드 단계에 해당합니다.

당신이 실행하는 경우

$ docker history ezze/geoport:0.6.0 --no-trunc

당신은 어떤이의 언급이 표시되지 않습니다 SSH_KEYSSH_KEY_PASSPHRASE최종 이미지에서.


답변

컨테이너 내에 ssh 키를 주입하기 위해 여러 솔루션이 있습니다.

  1. ADD지침 과 함께 Dockerfile을 사용하면 빌드 프로세스 중에 Dockerfile을 삽입 할 수 있습니다

  2. 단순히 다음과 같은 일을 cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa'

  3. docker cp컨테이너가 실행되는 동안 파일을 주입 할 수 있는 명령을 사용합니다.


답변

플랫폼 간 솔루션 중 하나는 바인드 마운트 를 사용 하여 호스트 .ssh폴더를 컨테이너 에 공유하는 것입니다 .

docker run -v /home/<host user>/.ssh:/home/<docker user>/.ssh <image>

에이전트 전달과 유사하게이 접근 방식은 컨테이너에 공개 키에 액세스 할 수있게합니다. 또 다른 단점은 루트가 아닌 사용자와도 작동하여 GitHub에 연결된다는 것입니다. 그러나 고려해야 할 한 가지주의 사항은 .ssh폴더의 모든 내용 (개인 키 포함) 이 공유되므로이 방법은 개발 및 신뢰할 수있는 컨테이너 이미지에만 바람직하다는 것입니다.