Руководство по отладке и устранению неполадок сети
- Введение
- Как устранять неполадки
- Категория «Невозможно открыть оболочку»
- Проблемы с таймаутами
- Проблемы с плейбуками
- Проблемы с прокси
Введение
Начиная с версии Ansible 2.1, вы можете использовать привычные для Ansible модели для создания плейбуков и разработки модулей для управления разнородными сетевыми устройствами. Ansible поддерживает всё большее количество сетевых устройств, используя как CLI по SSH, так и API (если доступен) для транспорта.
Этот раздел описывает, как отлаживать и устранять неполадки в сетевых модулях Ansible 2.3.
Как устранять неполадки
Этот раздел посвящён устранению неполадок с сетевыми модулями.
Ошибки, как правило, попадают в одну из следующих категорий:
| Проблемы с аутентификацией: | |
|---|---|
| |
| Проблемы с таймаутами: |
|
| Проблемы с плейбуком: | |
| |
Предупреждение
unable to open shell
Сообщение unable to open shell появилось в Ansible 2.3. Оно означает, что демону ansible-connection не удалось успешно связаться с удалённым сетевым устройством. Обычно это указывает на проблему с аутентификацией. Подробнее см. раздел «Проблемы с аутентификацией и подключением» в этом документе.
Включение журналирования сетевых операций и как прочитать файл журнала
Платформы: Любые
Ansible 2.3 имеет улучшенную систему журналирования, помогающую диагностировать и устранять проблемы с сетевыми модулями Ansible.
Поскольку журналы очень подробные, они отключены по умолчанию. Их можно включить с помощью опций ANSIBLE_LOG_PATH и ANSIBLE_DEBUG на контроллере ansible, т.е. машине, на которой выполняется ansible-playbook.
Перед запуском ansible-playbook выполните следующие команды для включения журналирования:
# Specify the location for the log file export ANSIBLE_LOG_PATH=~/ansible.log # Enable Debug export ANSIBLE_DEBUG=True # Run with 4*v for connection level verbosity ansible-playbook -vvvv ...
После завершения работы Ansible вы можете проверить файл журнала, созданный на контроллере ansible:
less $ANSIBLE_LOG_PATH 2017-03-30 13:19:52,740 p=28990 u=fred | creating new control socket for host veos01:22 as user admin 2017-03-30 13:19:52,741 p=28990 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a 2017-03-30 13:19:52,741 p=28990 u=fred | current working directory is /home/fred/ansible/test/integration 2017-03-30 13:19:52,741 p=28990 u=fred | using connection plugin network_cli ... 2017-03-30 13:20:14,771 paramiko.transport userauth is OK 2017-03-30 13:20:15,283 paramiko.transport Authentication (keyboard-interactive) successful! 2017-03-30 13:20:15,302 p=28990 u=fred | ssh connection done, setting terminal 2017-03-30 13:20:15,321 p=28990 u=fred | ssh connection has completed successfully 2017-03-30 13:20:15,322 p=28990 u=fred | connection established to veos01 in 0:00:22.580626
Обратите внимание на следующие элементы в журнале:
-
p=28990Идентификатор процесса (PID) процессаansible-connection -
u=fredПользовательrunningansible, а не удалённый пользователь, от имени которого вы пытаетесь подключиться -
creating new control socket for host veos01:22 as user adminхост:порт как пользователь -
control socket path isрасположение сокета постоянного соединения на диске -
using connection plugin network_cliУказывает на использование постоянного подключения -
connection established to veos01 in 0:00:22.580626Время, затраченное на получение оболочки на удалённом устройстве
Поскольку файлы журналов подробные, вы можете использовать grep для поиска определённой информации. Например, после определения `pid из строки creating new control socket for host, вы можете искать другие записи о подключении в журнале:
grep "p=28990" $ANSIBLE_LOG_PATH
Изоляция ошибки
Платформы: Любые
Как и при любой попытке отладки, важно максимально упростить тестовый случай.
В Ansible это можно сделать, убедившись, что вы работаете только с одним удалённым устройством:
- Используя
ansible-playbook --limit switch1.example.net... - Используя ад-хок команду
ansible
ad-hoc относится к запуску Ansible для выполнения некоторых быстрых команд с помощью /usr/bin/ansible, а не языка оркестрации, который является /usr/bin/ansible-playbook. В этом случае мы можем убедиться в подключении, попытавшись выполнить одну команду на удалённом устройстве:
ansible -m eos_command -a 'commands=?' -i inventory switch1.example.net -e 'ansible_connection=local' -u admin -k
В приведённом примере мы:
- подключаемся к
switch1.example.netуказанном в файле инвентаризацииinventory - используем модуль
eos_command - выполняем команду
? - подключаемся с именем пользователя
admin - информируем ansible о необходимости запросить пароль SSH, указав
-k
Если у вас правильно настроены ключи SSH, вам не нужно указывать параметр -k
Если подключение всё ещё не удается, вы можете комбинировать его с параметром enable_network_logging. Например:
# Specify the location for the log file export ANSIBLE_LOG_PATH=~/ansible.log # Enable Debug export ANSIBLE_DEBUG=True # Run with 4*v for connection level verbosity ansible -m eos_command -a 'commands=?' -i inventory switch1.example.net -e 'ansible_connection=local' -u admin -k
Затем просмотрите файл журнала и найдите соответствующее сообщение об ошибке в остальной части этого документа.
Категория «Невозможно открыть оболочку»
Платформы: Любые
Сообщение unable to open shell появилось в Ansible 2.3. Это означает, что демону ansible-connection не удалось успешно связаться с удалённым сетевым устройством. Это, как правило, указывает на проблему с аутентификацией. Это сообщение «общее», означающее, что нужно включить log_path для нахождения базовых проблем.
Например:
TASK [prepare_eos_tests : enable cli on remote device] **************************************************
fatal: [veos01]: FAILED! => {"changed": false, "failed": true, "msg": "unable to open shell"}
или:
TASK [ios_system : configure name_servers] *************************************************************
task path:
fatal: [ios-csr1000v]: FAILED! => {
"changed": false,
"failed": true,
"msg": "unable to open shell",
}
Предложения по решению:
Следуйте инструкциям, описанным в enable_network_logging.
После того, как вы определили сообщение об ошибке из файла журнала, конкретное решение можно найти в остальной части документа.
Ошибка: «[Errno -2] Имя или служба неизвестны»
Платформы: Любые
Указывает, что удалённый хост, к которому вы пытаетесь подключиться, недоступен.
Например:
2017-04-04 11:39:48,147 p=15299 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a 2017-04-04 11:39:48,147 p=15299 u=fred | current working directory is /home/fred/git/ansible-inc/stable-2.3/test/integration 2017-04-04 11:39:48,147 p=15299 u=fred | using connection plugin network_cli 2017-04-04 11:39:48,340 p=15299 u=fred | connecting to host veos01 returned an error 2017-04-04 11:39:48,340 p=15299 u=fred | [Errno -2] Name or service not known
Предложения по решению:
- Если вы используете параметр
provider:, убедитесь, что его подпараметрhost:установлен правильно. - Если вы не используете
provider:или параметры верхнего уровня, убедитесь, что ваш файл инвентаризации корректен.
Ошибка: «Ошибка аутентификации»
Платформы: Любые
Возникает, если учетные данные (имя пользователя, пароли или ключи SSH), переданные в ansible-connection (через ansible или ansible-playbook), не могут быть использованы для подключения к удалённому устройству.
Например:
<ios01> ESTABLISH CONNECTION FOR USER: cisco on PORT 22 TO ios01 <ios01> Authentication failed.
Предложения по решению:
Если вы указываете учетные данные через password: (прямо или через provider:) или переменную окружения ANSIBLE_NET_PASSWORD, возможно, библиотека SSH Python (которую использует Ansible) использует ключи SSH, и поэтому указанные вами учетные данные игнорируются. Чтобы выяснить, так ли это, отключите поиск ключей. Это можно сделать так:
export ANSIBLE_PARAMIKO_LOOK_FOR_KEYS=False
Чтобы сделать это постоянным изменением, добавьте следующее в ваш файл ansible.cfg:
[paramiko_connection] look_for_keys = False
Ошибка: «подключение к хосту <имя_хоста> вернуло ошибку» или «Неверный адрес»
Это может произойти, если отпечаток SSH не был добавлен в файл известных хостов Paramiko (библиотеки Python SSH).
При использовании постоянных подключений с Paramiko подключение выполняется в фоновом процессе. Если у хоста ещё нет валидного ключа SSH, по умолчанию Ansible попросит добавить ключ хоста. Это приведёт к ошибкам при подключениях, выполняемых в фоновых процессах.
Например:
2017-04-04 12:06:03,486 p=17981 u=fred | using connection plugin network_cli 2017-04-04 12:06:04,680 p=17981 u=fred | connecting to host veos01 returned an error 2017-04-04 12:06:04,682 p=17981 u=fred | (14, 'Bad address') 2017-04-04 12:06:33,519 p=17981 u=fred | number of connection attempts exceeded, unable to connect to control socket 2017-04-04 12:06:33,520 p=17981 u=fred | persistent_connect_interval=1, persistent_connect_retries=30
Предложения по решению:
Используйте ssh-keyscan для предварительной заполнения known_hosts. Вам нужно убедиться, что ключи верны.
ssh-keyscan veos01
или
Вы можете указать Ansible автоматически принять ключи
Метод переменной окружения:
export ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD=True ansible-playbook ...
Метод ansible.cfg:
ansible.cfg
[paramiko_connection] host_key_auto_add = True
Ошибка: «Доступные методы аутентификации отсутствуют»
Например:
2017-04-04 12:19:05,670 p=18591 u=fred | creating new control socket for host veos01:None as user admin 2017-04-04 12:19:05,670 p=18591 u=fred | control socket path is /home/fred/.ansible/pc/ca5960d27a 2017-04-04 12:19:05,670 p=18591 u=fred | current working directory is /home/fred/git/ansible-inc/ansible-workspace-2/test/integration 2017-04-04 12:19:05,670 p=18591 u=fred | using connection plugin network_cli 2017-04-04 12:19:06,606 p=18591 u=fred | connecting to host veos01 returned an error 2017-04-04 12:19:06,606 p=18591 u=fred | No authentication methods available 2017-04-04 12:19:35,708 p=18591 u=fred | connect retry timeout expired, unable to connect to control socket 2017-04-04 12:19:35,709 p=18591 u=fred | persistent_connect_retry_timeout is 15 secs
Предложения по решению:
Не указан пароль или ключ SSH
Очистка постоянных подключений
Платформы: Любые
В Ansible 2.3 сокеты постоянных подключений хранятся в ~/.ansible/pc для всех сетевых устройств. Когда выполняется плейбук Ansible, постоянное подключение отображается при указании подробного вывода.
<switch> socket_path: /home/fred/.ansible/pc/f64ddfa760
Чтобы очистить постоянное подключение перед его таймаутом (по умолчанию таймаут составляет 30 секунд бездействия), просто удалите файл сокета.
Проблемы с таймаутами
Таймауты
Таймаут бездействия постоянного подключения:
Например:
2017-04-04 12:19:05,670 p=18591 u=fred | persistent connection idle timeout triggered, timeout value is 30 secs
Предложения по решению:
Увеличьте значение тайм-аута для простоя соединения. .. code-block:: yaml
export ANSIBLE_PERSISTENT_CONNECT_TIMEOUT=60Чтобы сделать это постоянным изменением, добавьте следующее в ваш ansible.cfg файл:
[persistent_connection] connect_timeout = 60
Таймаут команды: Например:
2017-04-04 12:19:05,670 p=18591 u=fred | command timeout triggered, timeout value is 10 secs
Предложения по решению:
Вариант 1: Увеличьте значение таймаута команды в конфигурационном файле или установив переменную окружения. Примечание: Это значение должно быть меньше тайм-аута для простоя постоянного соединения, т.е. connect_timeout
export ANSIBLE_PERSISTENT_COMMAND_TIMEOUT=30
Чтобы сделать это постоянным изменением, добавьте следующее в ваш ansible.cfg файл:
[persistent_connection] command_timeout = 30
Вариант 2: Увеличьте таймаут команды для каждого задания. Все модули сети поддерживают значение таймаута, которое можно установить для каждого задания. Значение таймаута определяет количество секунд, по истечении которых задание завершится с ошибкой, если команда не вернула результат.
Например:
Предложения по решению:
- name: save running-config
ios_command:
commands: copy running-config startup-config
provider: "{{ cli }}"
timeout: 30
Некоторые операции занимают больше времени, чем стандартные 10 секунд. Хороший пример — сохранение текущей конфигурации IOS-устройств в конфигурацию по умолчанию. В этом случае изменение значения таймаута с 10 до 30 секунд предотвратит ошибку задания до успешного завершения команды. Примечание: Это значение должно быть меньше таймаута для простоя постоянного соединения, т.е. connect_timeout
Таймаут подключения постоянного сокета: Например:
2017-04-04 12:19:35,708 p=18591 u=fred | connect retry timeout expired, unable to connect to control socket 2017-04-04 12:19:35,709 p=18591 u=fred | persistent_connect_retry_timeout is 15 secs
Предложения по решению:
Увеличьте значение тайм-аута для простоя постоянного соединения. Примечание: Это значение должно быть больше значения таймаута SSH (значение таймаута в разделе по умолчанию в конфигурационном файле) и меньше значения тайм-аута для простоя постоянного соединения (connect_timeout).
export ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT=30
Чтобы сделать это постоянным изменением, добавьте следующее в ваш ansible.cfg файл:
[persistent_connection] connect_retry_timeout = 30
Проблемы с плейбуком
В этом разделе подробно описаны проблемы, вызванные ошибками самого плейбука.
Ошибка: “invalid connection specified, expected connection=local, got ssh”
Платформы: Любые
Модули сети требуют, чтобы значение подключения было установлено на local. Любое другое значение подключения приведет к ошибке плейбука. Ansible теперь обнаруживает эту ситуацию и возвращает сообщение об ошибке:
fatal: [nxos01]: FAILED! => {
"changed": false,
"failed": true,
"msg": "invalid connection specified, expected connection=local, got ssh"
}
Чтобы исправить эту проблему, установите значение подключения на local одним из следующих способов:
- Установите для плейбука использование
connection: local - Установите для задания использование
connection: local - Запустите ansible-playbook с параметром
-c local
Ошибка: “Unable to enter configuration mode”
Платформы: eos и ios
Это происходит, когда вы пытаетесь выполнить задачу, требующую привилегированного режима в оболочке пользователя.
Например:
TASK [ios_system : configure name_servers] *****************************************************************************
task path:
fatal: [ios-csr1000v]: FAILED! => {
"changed": false,
"failed": true,
"msg": "unable to enter configuration mode",
}
Предложения по решению:
Добавьте authorize: yes к заданию. Например:
- name: configure hostname
ios_system:
provider:
hostname: foo
authorize: yes
register: result
Если для входа в привилегированный режим требуется пароль, его можно указать с помощью auth_pass; если auth_pass не задано, вместо него будет использована переменная окружения ANSIBLE_NET_AUTHORIZE.
Добавьте authorize: yes к заданию. Например:
- name: configure hostname
ios_system:
provider:
hostname: foo
authorize: yes
auth_pass: "{{ mypasswordvar }}"
register: result
Проблемы с прокси
delegate_to vs ProxyCommand
Новый механизм подключения для модулей сети в Ansible 2.3, использующий cli транспорт, больше не поддерживает использование директивы delegate_to. Для использования бастиона или промежуточного хоста перехода для подключения к сетевым устройствам через cli транспорт, модули сети теперь поддерживают использование ProxyCommand.
Для использования ProxyCommand, настройте параметры прокси в файле инвентаризации Ansible, чтобы указать хост прокси.
[nxos] nxos01 nxos02 [nxos:vars] ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q bastion01"'
С указанной выше конфигурацией просто создайте и запустите плейбук в обычном режиме без дополнительных изменений. Модуль сети теперь подключится к сетевому устройству, сначала подключившись к хосту, указанному в ansible_ssh_common_args, что равно bastion01 в приведенном выше примере.
Примечание
Использование ProxyCommand с паролями через переменные
По умолчанию SSH не поддерживает предоставление паролей через переменные окружения. Это делается для предотвращения утечки секретов, например, в выводе ps.
Мы рекомендуем использовать ключи SSH и, при необходимости, ssh-agent, а не пароли, где это возможно.
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.4/network_debug_troubleshooting.html