【问题标题】:docker : how to share ssh-keys between containers?docker:如何在容器之间共享 ssh-keys?
【发布时间】:2020-10-19 15:18:12
【问题描述】:

我有 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 容器以及何时(构建或运行时)做到这一点!

【问题讨论】:

    标签: docker ssh docker-compose dockerfile openssh


    【解决方案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-forwarding - 不是挂载 $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 中。

    【讨论】:

      【解决方案2】:

      要在没有密码的情况下进行ssh,您需要创建无密码用户并在容器中配置SSH keys,此外,您还需要在源容器中添加ssh keys,并且应该在授权中添加公钥目标容器。

      这是工作的 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
      

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

      【讨论】:

      • 您的解决方案很棒,一如既往:) 非常感谢
      • 很高兴它有帮助:)
      • 有没有办法避免每次使用 ssh 或 scp 时添加 ssh -i /keys/ssh_test ?
      • 是的,您可以将此密钥添加到默认密钥。 ssh-add /keys/ssh_test,将此命令添加到 docker-entrypoint。如果您可以为此 git@github.com:Adiii717/docker-container-ssh.git 生成拉取请求,那就太好了
      • 可以查看合并github.com/Adiii717/docker-container-ssh/pull/1,再次感谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2020-10-06
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多