Spec-Zone.ru › Ansible 2.7

Руководство по отладке и устранению неполадок сетевых модулей

Введение

Начиная с версии Ansible 2.1, вы можете использовать привычные модели Ansible для написания плейбуков и разработки модулей для управления разнородными сетевыми устройствами. Ansible поддерживает всё больше сетевых устройств с использованием как CLI через SSH, так и API (если доступен) транспорта.

В этом разделе обсуждается, как отлаживать и устранять неполадки сетевых модулей в Ansible 2.3.

Как устранять неполадки

Этот раздел охватывает устранение неполадок с сетевыми модулями.

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

Проблемы с аутентификацией:
  • Неверно указаны учетные данные
  • Удаленное устройство (сетевой коммутатор/маршрутизатор) не переходит на другие методы аутентификации
  • Проблемы с ключами SSH
Проблемы с таймаутами:
  • Возникают при попытке извлечь большое количество данных
  • Могут маскировать проблему с аутентификацией
Проблемы с плейбуком:
  • Использование delegate_to, вместо ProxyCommand. Дополнительную информацию см. в руководстве по прокси для сети.
  • Неиспользование connection: local

Предупреждение

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 (Process ID) процесса ansible-connection
  • u=fred — это пользователь running, а не удалённый пользователь, от имени которого вы пытаетесь подключиться
  • 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

Затем просмотрите лог-файл и найдите соответствующее сообщение об ошибке в остальной части документа.

Категория «проблема с путём сокета»

Платформы: Любые

Сообщения socket_path does not exist or cannot be found и unable to connect to socket появились в Ansible 2.5. Эти сообщения указывают на то, что сокет, используемый для связи с удалённым сетевым устройством, недоступен или не существует.

Например:

fatal: [spine02]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_TSqk5J/ansible_modlib.zip/ansible/module_utils/connection.py\", line 115, in _exec_jsonrpc\nansible.module_utils.connection.ConnectionError: socket_path does not exist or cannot be found\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 1
}

или

fatal: [spine02]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_TSqk5J/ansible_modlib.zip/ansible/module_utils/connection.py\", line 123, in _exec_jsonrpc\nansible.module_utils.connection.ConnectionError: unable to connect to socket\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 1
}

Рекомендации по решению:

Следуйте инструкциям, подробно описанным в включении ведения журнала сети.

Если идентифицированное сообщение об ошибке из лог-файла:

2017-04-04 12:19:05,670 p=18591 u=fred |  command timeout triggered, timeout value is 10 secs

или

2017-04-04 12:19:05,670 p=18591 u=fred |  persistent connection idle timeout triggered, timeout value is 30 secs

Следуйте инструкциям, подробно описанным в проблемах с таймаутами

Категория «Не удалось открыть сеанс»

Платформы: Любые

Сообщение unable to open shell появилось в Ansible 2.3. Это сообщение означает, что демон ansible-connection не смог успешно связаться с удалённым сетевым устройством. Обычно это означает проблему с аутентификацией. Это сообщение «catch all», значит нужно включить ведение журнала, чтобы найти первопричину.

Например:

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, возможно, paramiko (библиотека Python SSH, которую использует 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

Рекомендации по решению:

Увеличьте значение таймаута бездействия постоянного подключения:

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 (Глобальная настройка таймаута команды): Увеличьте значение таймаута команды в файле конфигурации или установив переменную среды.

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

Для network_cli, тип подключения netconf (применимо начиная с версии 2.7):

Рекомендации по решению:

- name: save running-config
  ios_command:
    commands: copy running-config startup-config
  vars:
    ansible_command_timeout: 30

Некоторые операции занимают больше времени, чем стандартные 10 секунд. Хороший пример — сохранение текущей конфигурации IOS-устройств в стартовую конфигурацию. В этом случае изменение значения таймаута со стандартных 10 секунд на 30 секунд предотвратит сбой задачи до успешного завершения команды.

Таймаут подключения постоянного сокета: например:

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 (значение таймаута в разделе defaults в файле конфигурации) и меньше, чем значение таймаута бездействия постоянного подключения (connect_timeout).

export ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT=30

Чтобы сделать это постоянным изменением, добавьте следующее в свой файл ansible.cfg:

[persistent_connection]
connect_retry_timeout = 30

Проблемы с playbook

В этом разделе подробно описаны проблемы, вызванные ошибками в самом Playbook.

Ошибка: «Неверное указание подключения, ожидалось connection=local, получено ssh»

Платформы: Любые

Модули сети требуют, чтобы подключение было установлено на local. Любое другое значение подключения приведет к ошибке в playbook. Ansible теперь обнаружит это условие и вернет сообщение об ошибке:

fatal: [nxos01]: FAILED! => {
    "changed": false,
    "failed": true,
    "msg": "invalid connection specified, expected connection=local, got ssh"
}

Для решения этой проблемы установите значение connection на local одним из следующих способов:

  • Установите для play значение connection: local
  • Установите для задачи значение connection: local
  • Запустите ansible-playbook с параметром -c local

Ошибка: «Не удается войти в режим конфигурации»

Платформы: 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"'

С этой конфигурацией просто создайте и запустите playbook в обычном режиме без дополнительных изменений. Модуль сети теперь подключится к сетевому устройству, сначала подключившись к хосту, указанному в ansible_ssh_common_args, что является bastion01 в приведенном выше примере.

Использование бастионного/переходного хоста с подключением netconf

Включение настройки переходного хоста

Бастионный/переходный хост с подключением netconf можно включить, задав переменную Ansible ``ansible_netconf_ssh_config`` либо на True , либо на путь к пользовательскому файлу ssh-конфигурации - задав переменную окружения ANSIBLE_NETCONF_SSH_CONFIG на True или путь к пользовательскому файлу ssh-конфигурации - задав секцию ssh_config = 1 или ssh_config = <ssh-file-path>``under ``netconf_connection

Если значение переменной конфигурации установлено в 1, proxycommand и другие переменные ssh считываются из файла конфигурации ssh по умолчанию (~/.ssh/config). Если значение переменной конфигурации установлено в путь к файлу, proxycommand и другие переменные ssh считываются из заданного пользовательского файла ssh.

Пример файла конфигурации ssh (~/.ssh/config)

Host junos01
HostName junos01
User myuser

ProxyCommand ssh user@bastion01 nc %h %p %r

Пример файла инвентаризации Ansible

[junos]
junos01

[junos:vars]
ansible_connection=netconf
ansible_network_os=junos
ansible_user=myuser
ansible_ssh_pass=!vault...

Примечание

Использование ProxyCommand с паролями через переменные

По умолчанию SSH не поддерживает предоставление паролей через переменные окружения. Это делается для предотвращения утечки секретов, например, в ps выводе.

Мы рекомендуем использовать SSH-ключи и, при необходимости, ssh-агент вместо паролей, где это возможно.

Разные проблемы

Периодический сбой при использовании типа подключения network_cli

Если полученный ответ командной строки не соответствует правильно в модуле подключения network_cli, задача может периодически завершаться с усечённым ответом или с сообщением об ошибке operation requires privilege escalation. Начиная с версии 2.7.1, добавлен новый таймер чтения буфера, чтобы обеспечить правильное соответствие запросов и отправку полного ответа в выходные данные. Значение таймера по умолчанию составляет 0,1 секунды и может быть скорректировано для каждой задачи или установлено глобально в секундах.

Пример настройки таймера для каждой задачи

- name: gather ios facts
  ios_facts:
    gather_subset: all
  register: result
  vars:
    ansible_buffer_read_timeout: 2

Чтобы установить это как глобальную настройку, добавьте следующее в свой файл ansible.cfg:

[persistent_connection]
buffer_read_timeout = 2

Задержку таймера для каждой команды, выполняемой на удалённом хосте, можно отключить, установив значение в ноль.

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.7/network/user_guide/network_debug_troubleshooting.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API