Docker:如何在容器之间共享SSH密钥?

5

我有4个容器,配置如下 (docker-compose.yml):

version: '3'
networks:
  my-ntwk:
    ipam:
      config:
        - subnet: 172.20.0.0/24
services:
  f-app:
    image: f-app
    tty: true
    container_name: f-app
    hostname: f-app.info.my
    ports:
      - "22:22"
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.5
    extra_hosts:
      - "f-db.info.my:172.20.0.6"
      - "p-app.info.my:172.20.0.7"
      - "p-db.info.my:172.20.0.8"
    depends_on:
      - f-db
      - p-app
      - p-db
  f-db:
    image: f-db
    tty: true
    container_name: f-db
    hostname: f-db.info.my
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.6
  p-app:
    image: p-app
    tty: true
    container_name: p-app
    hostname: p-app.info.my
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.7
  p-db:
    image: p-db
    tty: true
    container_name: prod-db
    hostname: p-db.info.my
    networks:
      my-ntwk:
        ipv4_address: 172.20.0.8

每个镜像都是由相同的 Dockerfile 构建的:
FROM openjdk:8

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

EXPOSE 22

RUN useradd -s /bin/bash -p $(openssl passwd -1 myuser) -d /home/nf2/ -m myuser

ENTRYPOINT service ssh start && bash

现在,我希望能够在运行以下命令时,从f-app连接到任何其他机器而无需输入密码:ssh myuser@f-db.info.my。我知道需要在服务器之间交换ssh密钥(这不是问题),但我的问题是如何在使用Docker容器时进行交换,以及何时进行交换(构建时还是运行时)。
2个回答

1
如果您正在使用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

在macOS主机上进行ssh转发 - 与挂载$SSH_AUTH_SOCK路径不同,您必须挂载此路径 - /run/host-services/ssh-auth.sock
或者你可以这样做:


这是一个更难的问题,如果你需要在构建时使用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 .

Dockerfile
FROM openjdk:8

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

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

EXPOSE 22

RUN useradd -s /bin/bash -p $(openssl passwd -1 myuser) -d /home/nf2/ -m myuser

ENTRYPOINT service ssh start && bash

如果您使用的是Docker 1.13+和/或启用了实验性功能,可以在构建命令中添加--squash,它将合并层,删除SSH密钥并将其从docker history中隐藏。

1
要想无密码进行ssh,您需要创建一个无密码用户,并在容器中配置SSH密钥,还需要在源容器中添加ssh密钥,并将公钥添加到目标容器的授权文件中。以下是可行的Dockerfile。
FROM openjdk:7

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

EXPOSE 22


RUN useradd -rm -d /home/nf2/ -s /bin/bash -g root -G sudo -u 1001 ubuntu
USER ubuntu
WORKDIR /home/ubuntu

RUN mkdir -p /home/nf2/.ssh/ && \
    chmod 0700 /home/nf2/.ssh  && \
    touch /home/nf2/.ssh/authorized_keys && \
    chmod 600 /home/nf2/.ssh/authorized_keys

COPY ssh-keys/ /keys/
RUN cat /keys/ssh_test.pub >> /home/nf2/.ssh/authorized_keys

USER root
ENTRYPOINT service ssh start && bash

docker-compose将保持不变,这是您可以尝试的测试脚本。

#!/bin/bash
set -e
echo "start docker-compose"
docker-compose up -d
echo "list of containers"
docker-compose ps
echo "starting ssh test from f-db to f-app"
docker exec -it f-db sh -c "ssh -i /keys/ssh_test ubuntu@f-app"

如果需要更详细的信息,您可以尝试上面的工作示例docker-container-ssh

git clone git@github.com:Adiii717/docker-container-ssh.git
cd docker-container-ssh; 
./test.sh

您可以替换这些密钥,因为它们仅用于测试目的。


1
你的解决方案很棒,像往常一样 :) 非常感谢 - flywell
1
很高兴能帮到你 :) - Adiii
有没有办法避免每次使用ssh或scp时都要添加ssh -i /keys/ssh_test的命令? - flywell
是的,您可以将此密钥添加到默认密钥中。ssh-add /keys/ssh_test,将此命令添加到docker-entrypoint中。如果您能为此生成拉取请求,那就太好了。git@github.com:Adiii717/docker-container-ssh.git - Adiii
1
你可以查看合并请求 https://github.com/Adiii717/docker-container-ssh/pull/1,再次感谢。 - flywell

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