Вопрос или проблема
Я довольно новичок в Ansible. Использую Ansible 2.10 на своем ноутбуке (ansible master) и пытаюсь скопировать некоторые файлы и директории с удаленного сервераA на удаленный серверB.
На сервереA я создал SSH-ключ (id_rsa) используя пользователя sudo и скопировал публичный ключ на серверB (в файл authorized_keys того же пользователя sudo).
Файл Hosts
[servers]
prod_server ansible_host=IP_prod
new_server ansible_host=IP_new
[servers:vars]
ansible_user=sudo_user
ansible_sudo_pass=password
ansible_ssh_private_key_file=~/.ssh/id_rsa
Playbook
- name: Перенос файлов с prod на новый сервер
hosts: new_server
gather_facts: false
become: true
roles:
- rsync
Роль
- name: Копирование файлов на новый сервер
synchronize:
src: /etc/letsencrypt/live/domain/fullchain.pem
dest: /opt
delegate_to: prod_server
При запуске playbook возникает ошибка:
fatal: [new_server -> IP_new]: FAILED! => {"changed": false, "cmd": "/usr/bin/rsync --delay-updates
-F --compress --archive --rsh=/usr/bin/ssh -S none -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no
-o UserKnownHostsFile=/dev/null --rsync-path=sudo rsync --out-format=<<CHANGED>>%i %n%L
/etc/letsencrypt/live/domain/fullchain.pem sudo_user@IP_new:/opt", "msg": "Warning: Identity
file /root/.ssh/id_rsa not accessible: No such file or directory.\nWarning: Permanently added
'IP_new' (ECDSA) to the list of known hosts.\r\nsudo_user@IP_new: Permission denied (publickey).....
Любая помощь будет очень ценна.
С уважением
delegate_to: prod_server
в задаче synchronize:
означает, что файл должен быть скопирован с prod_server
на new_server
. Из-за become: true
задача выполняется от имени root
, и rsync пытается использовать публичный ключ -i /root/.ssh/id_rsa
, которого нет
Warning: Identity file /root/.ssh/id_rsa not accessible: No such file or directory.
Чтобы решить проблему, либо создайте SSH-ключи для root
на prod_server
и убедитесь, что он может подключиться к new_server
(если вы хотите, чтобы root скопировал файл), либо удалите глобальный become: true
из play и убедитесь, что sudo_user
может подключиться с prod_server
к new_server
и скопировать файл.
Когда вы удалите глобальный become: true
из play, вам придется избирательно включать его в каждой задаче по мере необходимости. В этом случае, чтобы упростить эскалацию в playbook, возможно, вы захотите перенести синхронизацию файла в отдельный play.
Ответ или решение
При возникновении ошибки при копировании файлов между удаленными серверами с использованием модуля Ansible synchronize важно детально разобраться в ситуации, чтобы найти эффективное решение. Мы рассмотрим теоретические аспекты проблемы, проанализируем предоставленный пример и предложим практические решения для устранения ошибки.
Теория
Ansible — это мощный инструмент автоматизации, часто используемый для управления конфигурацией и развертывания приложений. Модуль synchronize
в Ansible основывается на утилите rsync
, которая предназначена для копирования и синхронизации файлов между компьютерами по сети, что делает его полезным для задач переноса данных.
В данном случае задача состоит в копировании файла fullchain.pem
с сервера A (prod_server) на сервер B (new_server). Команду копирования выполняет Ansible, находящийся на вашем локальном компьютере. Ключевую роль в этом процессе играет правильная настройка SSH, так как rsync
использует SSH для установления соединения между серверами.
Пример
В вашей настройке Ansible перечислено два сервера: prod_server
и new_server
, на которые вы пытаетесь передать файлы. Конфигурация требует наличия SSH-ключей, которые позволят производить аутентификацию без запроса пароля. Ошибка в вашей конфигурации заключается в том, что вы используете глобальный параметр become: true
, который указывает Ansible выполнять задачи от имени пользователя root
.
Когда вы используете delegate_to: prod_server
, задача synchronize
пытается действовать от имени root
на prod_server
и подключаться к new_server
. Однако файл SSH-ключа указан неверно: /root/.ssh/id_rsa
отсутствует, что вызывает ошибку Permission denied (publickey)
.
Применение
Для решения проблемы следуйте этим шагам:
-
Настройка SSH-ключей для root:
- На сервере
prod_server
создайте пару SSH-ключей для пользователяroot
:ssh-keygen -t rsa -b 2048
- Скопируйте публичный ключ в файл
authorized_keys
на сервереnew_server
, чтобыroot
мог подключаться без пароля.
- На сервере
-
Использование SSH-ключа sudo пользователя:
- Если вы не хотите использовать
root
, удалите глобальныйbecome: true
из playbook. - Убедитесь, что пользователь
sudo_user
настроен с правильно скопированным SSH-ключом, чтобы он мог подключаться от имени себя изprod_server
вnew_server
.
- Если вы не хотите использовать
-
Селективное использование esc связей:
- Удалите
become: true
из общего playbook и активируйте его только в тех задачах, где это необходимо.
- Удалите
-
Организация playbook:
- Разделите playbook на несколько шагов: сначала переносите файл без
become
, а затем добавляйте его для задач, которые требуют повышения привилегий.
- Разделите playbook на несколько шагов: сначала переносите файл без
-
Проверка директории SSH:
- Убедитесь, что права доступа к файлам и директориям для SSH настроены корректно. Например, директория
.ssh
и файлauthorized_keys
должны иметь разрешения 700 и 600 соответственно.
- Убедитесь, что права доступа к файлам и директориям для SSH настроены корректно. Например, директория
Эти действия должны помочь вам правильно настроить Ansible playbook для передачи файлов с одного удаленного сервера на другой. Имейте в виду, что отладка ошибок SSH часто требует точного понимания, какие идентификационные данные и из какой директории используются, поэтому подробный лог анализа всегда полезен при решении подобных проблем.