#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 абсолютно верно, но, как я уже писал… Я искал решение без перестройки образа. Спасибо!