Как отладить Ansible проблемы?
иногда ansible
не делать то, что вы хотите. И увеличение многословия не помогает. Например, я сейчас пытаюсь начать coturn
сервер, который поставляется с init script on systemd
OS (Debian Jessie). Анзибль считает, что он работает, но это не так. Как мне разобраться в том, что происходит под капотом? Какие команды выполняются и какой код вывода/выхода?
6 ответов
модули отладки
самый простой способ-запустить
ansible
/ansible-playbook
с повышенным уровнем детализации, добавив-vvv
к строке выполнения.-
самый тщательный способ для модулей, написанных на Python (Linux/Unix), - запустить
ansible
/ansible-playbook
с переменной окруженияANSIBLE_KEEP_REMOTE_FILES
значение1
(машина управления).это заставляет Ansible оставлять точную копию скриптов Python, которые он выполнил (успешно или нет) на целевой машине.
путь к скриптам печатается в журнале Ansible и для обычных задач они хранятся в домашнем каталоге пользователя SSH:
~/.ansible/tmp/
.точная логика встроена в скрипты и зависит от каждого модуля. Некоторые используют Python со стандартными или внешними библиотеками, некоторые вызывают внешние команды.
отладка playbooks
аналогично отладке модулей, повышающих уровень детализации с
-vvv
параметр вызывает больше данных для печати в журнал Ansibleтак как Ansible 2.1 a Отладчик Playbook позволяет отлаживать интерактивно неудачные задачи: проверять, изменять данные; повторно запускать задачу.
подключение отладка
- добавлять до
ansible
/ansible-playbook
вызов журнал содержит отладочную информацию для связи.
вот что я придумал.
Ansible отправляет модули в целевую систему и выполняет их там. Поэтому, если вы измените модуль локально, ваши изменения вступят в силу при запуске playbook. На моей машине модули находятся в /usr/lib/python2.7/site-packages/ansible/modules
(ansible-2.1.2.0
). И service
модуль на core/system/service.py
. Anisble модули (экземпляров AnsibleModule
класса, объявленные в module_utils/basic.py
) и log
метод, который отправляет сообщения на systemd журнал, если он доступен, или возвращается к syslog
. Итак, беги!--9--> в целевой системе добавьте операторы отладки (module.log(msg='test')
) для локального модуля и запуска вашего playbook. Вы увидите инструкции debug в разделе ansible-basic.py
имя блока.
кроме того, при запуске ansible-playbook
С -vvv
, вы можете увидеть некоторые выходные данные отладки в systemd
журнал, по крайней мере, сообщения вызова и сообщения об ошибках, если таковые имеются.
еще одна вещь, если вы пытаетесь отлаживать код, который работает локально с pdb
(import pdb; pdb.set_trace()
), вы, скорее всего, столкнетесь BdbQuit
исключения. Это потому что python
закрывается stdin
при создании потока (ansible
работник). Решение здесь состоит в том, чтобы открыть stdin
перед pdb.set_trace()
как предложил здесь:
sys.stdin = open('/dev/tty')
import pdb; pdb.set_trace()
отладка ролей / playbooks
В основном отладка ansible automation через большой инвентарь в больших сетях-это не что иное, как отладка распределенного сетевого приложения. Это может быть очень утомительно и деликатно, и не хватает удобных инструментов.
таким образом, я считаю, что также ответ на ваш вопрос-это объединение всех ответов перед моим + небольшое дополнение. Так вот:
абсолютно обязательным: вы нужно хотеть знать, что происходит, то есть что вы автоматизируете, что вы ожидаете, что произойдет. например, неспособность ansible обнаружить службу с блоком systemd как запущенную или как остановленную обычно означает ошибку в файле или модуле service unit, поэтому вам нужно 1. выявление ошибок, 2. Сообщите об ошибке поставщику / сообществу, 3. Предоставьте обходной путь с TODO и ссылку на ошибку. 4. Когда ошибка исправлена-удалите обходной путь
чтобы упростить отладку кода модули, столько, сколько вы можете
дайте всем задачам и переменным значимые имена.
используйте инструменты статического анализа кода, такие как
ansible-lint
. Это спасает вас от действительно глупых маленьких ошибок.использовать флаги многословия и путь к журналу
использовать
debug
модуль мудро-
"Знай свои факты" - иногда полезно сбросить факты целевой машины в файл и вытащить его к ансиблю-мастеру!--6-->
использовать
strategy: debug
в некоторых случаях вы можете попасть в Задача отладчик по ошибке. Затем вы можете оценить все параметры, которые использует задача, и решить, что делать дальшепоследним средством будет использование отладчика Python, прикрепляющего его к локальному ansible run и / или к удаленному Python, выполняющему модули. Это обычно сложно: вам нужно разрешить открыть дополнительный порт на машине, и если код, открывающий порт, вызывает проблема?
кроме того, иногда полезно "смотреть в сторону" - подключитесь к целевым хостам и увеличьте их отладочность (более подробное ведение журнала)
конечно, коллекция журналов облегчает отслеживание изменений, происходящих в результате операций ansible.
как вы можете видеть, как и любые другие распределенные приложения и фреймворки-debug-ability по-прежнему не так, как мы хотели бы для.
фильтры/Плагины
это в основном разработка Python, отладка как любое приложение Python
модули
В зависимости от технологии и осложняется тем, что вам нужно видеть, что происходит локально и удаленно, вам лучше выбрать язык, достаточно простой для отладки удаленно.
для печати возвращаемых значений можно использовать модуль register и модуль debug. Например, я хочу знать, как называется код возврата моего выполнения скрипта "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
существует несколько уровней отладки, которые вам могут понадобиться, но самый простой-добавить ANSIBLE_STRATEGY=debug
переменная окружения, которая включит отладчик при первой ошибке.
отладка Ansible задач может быть почти невозможно, если задачи не являются вашими собственными. Вопреки тому, что говорится на сайте 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. Не очень хорошая идея. Этот конкретный фрагмент может завершиться ошибкой с сообщением
fatal: [master0]: не удалось! = > {"msg": "элемент условной проверки != openshift_ca_host' не удалось. Ошибка была: ошибка при оценке условный (пункт != openshift_ca_host): 'item' не определен\n\nThe ошибка, похоже, была в '/главная/пользователь / openshift-ansible / роли / openshift_master_certificates/задачи / главная.в формате YML': строка 39, столбец 3, но может\nbe в другом месте файла в зависимости от точная проблема синтаксиса.\n\n оскорбительная строка выглядит так:\n\n\n- имя: создайте сертификат главного сервера\N ^ здесь\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 Openshift Ansible занимает +50 минут. Фаза развертывания занимает более + 70 минут. Каждый раз! Первый запуск или последующие прогоны. И нет никакого способа ограничить предоставление одним узлом. Это limit
проблема была частью Ansible в 2012 году, и она по-прежнему является частью Ansible сегодня. Этот факт говорит нам кое о чем.
дело здесь в том, что Ansible следует использовать так, как было задумано. Для простых задач без программирования YAML. Хорошо для многих серверов, но он не должен использоваться для сложных задач управления конфигурацией.
Ansible-это не Инфраструктура как инструмент кода ( IaC).
Если вы спросите, как отлаживать Ansible проблемы, вы используете его таким образом, что он не предназначен для использования. Не используйте его как инструмент IaC.