Ввести SSH-ключ в контейнер Docker

#docker #ssh #docker-compose

#docker #ssh #docker-составить

Вопрос:

Я пытаюсь найти «глобальное» решение для внедрения SSH-ключа в контейнер. Я знаю, что есть несколько решений, включая docker build kit и так далее … но я не хочу создавать образ и вводить SSH-ключ. Я хочу ввести SSH-ключ, используя существующий образ с помощью docker compose.

Я использую следующий файл docker compose:

 version: '3.1'

services:
  server1:
    image: XXXXXXX
    container_name: server1
    command: bash -c "/root/init.sh amp;amp; python3 /root/my_python.py"
    environment:
      - MANAGED_HOST=mserver
    volumes:
      - ./init.sh:/root/init.sh
    secrets:
      - id_rsa

secrets:
   id_rsa:
     file: /home/user/.ssh/id_rsa
  

The init.sh заключается в следующем:

 #!/bin/bash

eval "$(ssh-agent -s)" > /dev/null
if [ ! -d "/root/.ssh/" ]; then
    mkdir /root/.ssh
    ssh-keyscan $MANAGED_HOST > /root/.ssh/known_hosts
fi
ssh-add -k /run/secrets/id_rsa
  

Если я запущу docker compose с помощью команды parameter
bash -c "/root/init.sh amp;amp; python3 /root/my_python.py" , тогда проверка подлинности SSH на соответствующем удаленном хосте ($ MANAGED_HOST) не работает.

Запущен процесс агента:

 root         8     1  0 12:50 ?        00:00:00 ssh-agent -s
  

known_hosts в порядке:

 root@c67655d87ced:~# cat /root/.ssh/known_hosts
BLABLABLA ssh-rsa AAAAB3BLABLABLA....
  

и агент запущен, но закрытый ключ не добавлен:

 root@c67655d87ced:~# ssh-add -l
Could not open a connection to your authentication agent.
  

Теперь, если я войду в контейнер (docker exec -it server1 / bin / bash) и выполню команды из init.sh один за другим из командной строки, затем работает SSH-аутентификация на соответствующем удаленном хосте ($ MANAGED_HOST)?!?

Есть идеи, как я могу заставить его работать, используя docker compose?

Ответ №1:

Этого должно быть достаточно, чтобы файл $HOME/.ssh/id_rsa существовал с соответствующими разрешениями; вам не нужен работающий ssh-агент.

 #!/bin/sh
if ! [ -d "$HOME/.ssh" ]; then
  mkdir "$HOME/.ssh"
fi
chmod 0700 "$HOME/.ssh"
if [ -n "$MANAGED_HOST" ]; then
  ssh-keyscan "$MANAGED_HOST" >> "$HOME/.ssh/known_hosts"
fi
if [ -f /run/secrets/id_rsa ]; then
  cp /run/secrets/id_rsa "$HOME/.ssh/id_rsa"
  chmod 0400 "$HOME/.ssh/id_rsa"
fi
# exec "$@"
  

Типичным шаблоном является использование Dockerfile ENTRYPOINT для выполнения подобных задач настройки в первый раз. Он будет передан CMD в качестве аргументов, и прокомментированная exec "$@" строка в конце файла запускает это как команду. Вы бы настроили это в Dockerfile вашего изображения следующим образом:

 FROM XXXXXX
...
# Script must be executable on the host, and must start with a
# #!/bin/sh "shebang" line
COPY init.sh /root
# MUST use JSON-array form
ENTRYPOINT ["/root/init.sh"]
# Can use any Dockerfile syntax
CMD ["python3", "/root/my_python.py"]
  

В вашем конкретном примере вы запускаете init.sh как подпроцесс. ssh-agent Настройка устанавливает некоторые переменные среды, например $SSH_AUTH_SOCK , но когда они выполняются как подпроцесс, они не передаются обратно в хост-процесс. Вы можете использовать стандартную . встроенную оболочку POSIX (встроенная функция bash source эквивалентна, но нестандартна), чтобы установить эти переменные среды в контексте родительской оболочки:

 command: sh -c ". /root/init.sh amp;amp; exec python3 /root/my_python.py"
  

exec Заменяет оболочку оболочки скриптом Python, который вам обычно нужен. Это также приведет к тому, что родительский процесс ssh-agent станет родительским процессом, который потенциально может удивить ваш процесс, если он завершится.

Комментарии:

1. Ваш init.sh и command: sh -c ". /root/init.sh amp;amp; exec python3 /root/my_python.py" сделал свое дело! Ваше предложение относительно Dockerfile абсолютно верно, но, как я уже писал… Я искал решение без перестройки образа. Спасибо!