Как отлаживать проблемы с Ansible?

Иногда ansible не делает то, что вы хотите. И увеличение подробностей не помогает. Например, теперь я пытаюсь запустить сервер coturn, который поставляется с init script на systemd OS (Debian Jessie). Ansible считает, что он работает, но это не так. Как посмотреть, что происходит под капотом? Какие команды выполняются и какой код выхода/выхода?

Ответ 1

Отладка модулей

  • Самый простой способ - запустить ansible/ansible-playbook с увеличенным уровнем детализации, добавив -vvv к строке выполнения.

  • Самый простой способ для модулей, написанных на Python (Linux/Unix), - запустить ansible/ansible-playbook с переменной окружения ANSIBLE_KEEP_REMOTE_FILES, установленной на 1 (на управляющей машине).

    Это приводит к тому, что Ansible оставляет точную копию написанных на Python скриптов (успешно или нет) на целевой машине.

    Путь к сценариям печатается в журнале Ansible, а для обычных задач они хранятся в домашнем каталоге пользователя SSH: ~/.ansible/tmp/.

    Точная логика встроена в скрипты и зависит от каждого модуля. Некоторые из них используют Python со стандартными или внешними библиотеками, некоторые из них вызывают внешние команды.

Отладка игровых автоматов

  • Аналогично отладке модулей, увеличивающих уровень детализации с параметром -vvv, больше данных нужно печатать в журнале Ansible

  • Так как Ansible 2.1 a Отладчик для воспроизведения книг позволяет отлаживать интерактивно неудачные задачи: проверять, изменять данные; перезапустите задачу.

Отладка соединений

  • Добавление параметра -vvvv в вызов ansible/ansible-playbook заставляет журнал включать в себя информацию для отладки для соединений.

Ответ 2

Вот что я придумал.

Ansible отправляет модули в целевую систему и выполняет их там. Поэтому, если вы меняете модуль локально, ваши изменения вступят в силу при запуске playbook. На моих машинных модулях находятся /usr/lib/python2.7/site-packages/ansible/modules (ansible-2.1.2.0). И service модуль находится в core/system/service.py. Неиспользуемые модули (экземпляры класса AnsibleModule объявленные в module_utils/basic.py) имеют метод log, который отправляет сообщения в журнал systemd, если он доступен, или возвращается в syslog. Итак, запустите journalctl -f в целевой системе, добавьте операторы отладки (module.log(msg='test')) в локальный модуль и запустите свою playbook. Вы увидите отладочные заявления под именем ansible-basic.py.

Кроме того, при запуске ansible-playbook с -vvv, вы можете увидеть некоторые выходные данные отладки в systemd журнала, по крайней мере, призывание сообщения и сообщения об ошибках, если таковые имеются.

Еще одна вещь, если вы попытаетесь отладить код, выполняющийся локально с помощью pdb (import pdb; pdb.set_trace()), скорее всего, вы BdbQuit исключением BdbQuit. Это потому, что python закрывает stdin при создании потока (ansible рабочий). Решением здесь является повторное открытие stdin перед запуском pdb.set_trace() как предлагается здесь:

sys.stdin = open('/dev/tty')
import pdb; pdb.set_trace()

Ответ 3

Отладка ролей /playbooks

В основном отладка управляемой автоматизации над большой инвентаризацией в крупных сетях - это не что иное, как отладка распределенного сетевого приложения. Это может быть очень утомительно и деликатно, и не хватает удобных для пользователя инструментов.

Таким образом, я считаю, что и ответ на ваш вопрос - это объединение всех ответов перед моим + небольшим добавлением. Итак, здесь:

  • абсолютно обязательный: вам нужно знать, что происходит, то есть то, что вы автоматизируете, что вы ожидаете. например невозможность обнаружить службу с помощью блока systemd как работающего или остановленного обычно означает ошибку в файле служебных модулей или сервисном модуле, поэтому вам нужно 1. определить ошибку, 2. Сообщить об ошибке поставщику/сообществу, 3. Предоставить обходной путь с TODO и ссылкой на ошибку. 4. Когда ошибка исправлена ​​- удалите обходное решение

  • чтобы сделать ваш код проще для отладки используемых модулей, насколько вы можете

  • дать всем значимым именам задач и переменных.

  • используйте инструменты для анализа статического кода, такие как ansible-lint. Это избавит вас от действительно глупых мелких ошибок.

  • использовать флаги verbosity и путь к журналу

  • используйте debug модуль с умом

  • "Знай свои факты" - иногда полезно сбрасывать информацию о целевой машине в файл и вытаскивать ее в незаменимый мастер

    • используйте strategy: debug, в некоторых случаях вы можете попасть в отладчик задачи при ошибке. Затем вы можете оценить все параметры, которые использует задача, и решить, что делать дальше

    • последнее применение будет использовать отладчик Python, привязав его к локальному проходу и/или удаленному Python, выполняющему модули. Это обычно сложно: вам нужно разрешить открывать дополнительный порт на машине, и если код, открывающий порт, вызывает проблему?

Кроме того, иногда полезно "смотреть в сторону" - подключаться к целевым узлам и увеличивать их отлаживаемость (более подробное ведение журнала)

Конечно, коллекция журналов облегчает отслеживание изменений, происходящих в результате незаметных операций.

Как вы можете видеть, как и любые другие распределенные приложения и фреймворки - способность отладки все еще не так, как мы хотели бы.

Фильтры/плагинов

Это в основном разработка Python, отладка как любое приложение Python

Модули

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

Ответ 4

Вы можете использовать модуль регистров и модуль отладки для печати возвращаемых значений. Например, я хочу знать, что такое код возврата моего выполнения script, вызванный "somescript.sh", поэтому у меня будут задачи в игре, например:

- name: my task
  shell: "bash somescript.sh"
  register: output

- debug:
  msg: "{{ output.rc }}"

Для полных значений возврата вы можете получить доступ в Ansible, вы можете проверить эту страницу: http://docs.ansible.com/ansible/latest/common_return_values.html

Ответ 5

Существует несколько уровней отладки, которые вам могут понадобиться, но проще всего добавить переменную среды ANSIBLE_STRATEGY=debug, которая позволит отладчику выполнить первую ошибку.

Ответ 6

Отладка Возможные задачи могут быть практически невозможны, если задачи не являются вашими собственными. Вопреки тому, что говорится в веб-сайте Ansible.

Никаких специальных навыков кодирования не требуется

Ansible требует высоко специализированных навыков программирования, потому что это не YAML или Python, это грязная смесь обоих.

Ранее обсуждалась идея использования языков разметки для программирования. XML был очень популярен в сообществе Java за один раз. XSLT также является прекрасным примером.

По мере того, как проекты Ansible растут, сложность растет по экспоненте как результат. Возьмем, к примеру, проект OpenShift Ansible, который выполняет следующую задачу:

- name: Create the master server certificate
  command: >
    {{ hostvars[openshift_ca_host]['first_master_client_binary'] }} adm ca create-server-cert
    {% for named_ca_certificate in openshift.master.named_certificates | default([]) | lib_utils_oo_collect('cafile') %}
    --certificate-authority {{ named_ca_certificate }}
    {% endfor %}
    {% for legacy_ca_certificate in g_master_legacy_ca_result.files | default([]) | lib_utils_oo_collect('path') %}
    --certificate-authority {{ legacy_ca_certificate }}
    {% endfor %}
    --hostnames={{ hostvars[item].openshift.common.all_hostnames | join(',') }}
    --cert={{ openshift_generated_configs_dir }}/master-{{ hostvars[item].openshift.common.hostname }}/master.server.crt
    --key={{ openshift_generated_configs_dir }}/master-{{ hostvars[item].openshift.common.hostname }}/master.server.key
    --expire-days={{ openshift_master_cert_expire_days }}
    --signer-cert={{ openshift_ca_cert }}
    --signer-key={{ openshift_ca_key }}
    --signer-serial={{ openshift_ca_serial }}
    --overwrite=false
  when: item != openshift_ca_host
  with_items: "{{ hostvars
                  | lib_utils_oo_select_keys(groups['oo_masters_to_config'])
                  | lib_utils_oo_collect(attribute='inventory_hostname', filters={'master_certs_missing':True}) }}"
  delegate_to: "{{ openshift_ca_host }}"
  run_once: true

Я думаю, мы все можем согласиться с тем, что это программирование в YAML. Не очень хорошая идея. Этот конкретный фрагмент может завершиться неудачей с сообщением типа

фатальный: [master0]: FAILED! => {"msg": "Условная проверка 'item! = openshift_ca_host' не удалась. Ошибка была: ошибка при оценке условного (item! = openshift_ca_host): 'item' не определен\n\nПроизошла ошибка в '/home/user/openshift-ansible/roles/openshift_master_certificates/tasks/main.yml ': строка 39, столбец 3, но может \n быть в другом месте в файле в зависимости от точной проблемы синтаксиса.\n\nСоглашение о нарушении :\n\n\n- имя: создать сертификат главного сервера \n ^ here\n "}

Если вы нажмете такое сообщение, вы обречены. Но у нас есть отладчик? Хорошо, посмотрим, что происходит.

master0] TASK: openshift_master_certificates : Create the master server certificate (debug)> p task.args
{u'_raw_params': u"{{ hostvars[openshift_ca_host]['first_master_client_binary'] }} adm ca create-server-cert {% for named_ca_certificate in openshift.master.named_certificates | default([]) | lib_utils_oo_collect('cafile') %} --certificate-authority {{ named_ca_certificate }} {% endfor %} {% for legacy_ca_certificate in g_master_legacy_ca_result.files | default([]) | lib_utils_oo_collect('path') %} --certificate-authority {{ legacy_ca_certificate }} {% endfor %} --hostnames={{ hostvars[item].openshift.common.all_hostnames | join(',') }} --cert={{ openshift_generated_configs_dir }}/master-{{ hostvars[item].openshift.common.hostname }}/master.server.crt --key={{ openshift_generated_configs_dir }}/master-{{ hostvars[item].openshift.common.hostname }}/master.server.key --expire-days={{ openshift_master_cert_expire_days }} --signer-cert={{ openshift_ca_cert }} --signer-key={{ openshift_ca_key }} --signer-serial={{ openshift_ca_serial }} --overwrite=false"}
[master0] TASK: openshift_master_certificates : Create the master server certificate (debug)> exit

Как это помогает? Это не так.

Дело здесь в том, что невероятно плохая идея использовать YAML в качестве языка программирования. Это бардак. И симптомы беспорядка, который мы создаем, повсюду.

Некоторые дополнительные факты. Предоставление фазы предварительных условий на Azure of Openshift Ansible занимает +50 минут. Фаза развертывания занимает больше, чем +70 минут. Каждый раз! Первый запуск или последующие прогоны. И нет возможности ограничить предоставление одного узла. Эта проблема limit была частью Ansible в 2012 году, и она по-прежнему остается частью Ansible. Этот факт говорит нам кое-что.

Дело здесь в том, что Ansible следует использовать, как предполагалось. Для простых задач без программирования YAML. Отлично подходит для большого количества серверов, но он не должен использоваться для сложных задач управления конфигурацией.

Ansible не является инструментом инфраструктуры (Code IaC).

Если вы спросите, как отлаживать проблемы Ansible, вы используете его таким образом, чтобы он не предназначался для использования. Не используйте его как инструмент IaC.