Мечтают ли YML программисты о тестировании ansible?

    kitchen-ci schema


    Это текстовая версия выступления 2018-04-25 на Saint-Petersburg Linux User Group. Пример кода тут: https://github.com/ultral/ansible-role-testing


    Полагаю что вы используете configuration mangement, а не bash. Т.е. ваша конфигурация это код. Если мы говорим, что инфраструктура это код, то к её созданию должна применяться та же философия, что и для разработки ПО. Вы задумывались об этом? Как у вас это сделано? А у других?


    Пререквизиты


    В описываемом случае было множество вводных:


    • Множество ansible ролей.
    • Hyper-V как основной гипервизор.
    • Приватное облако с ограниченными возможностями по созданию виртуальных машин на лету.
    • Proxy для доступа к интернету.
    • Невозможность запускать тестирование ansible ролей в docker, потому что роль это конфиг целой вм, в том числе сетевые настройки например.
    • Желание использовать политику зеленого мастера для репозитория с ansible ролями.

    Преждем чем делать своё, сравним существующие решения.


    Проект Test Kitchen Molecule Свой
    Language ruby python bash/ruby
    Watchers 132 126 0
    Stars 1413 1154 1
    Forks 502 174 2
    License Apache 2.0 MIT Any
    Commits 1929 1264 0
    Releases 101 121 0
    Contributors 109 82 5

    Name testinfra serverspec inspec Goss
    Github philpep/testinfra mizzy/serverspec chef/inspec aelsabbahy/goss
    Language python ruby ruby go
    Watchers 93 145 165 67
    Stars 997 2105 1167 2170
    Forks 138 361 330 156
    License Apache 2.0 MIT Apache 2.0 Apache 2.0
    Commits 380 1854 4609 309
    Releases 35 282 346 47
    Contributors 43 110 159 31

    Мы решили не изобретать велосипед и взять готовое решение. Наша инфраструктурная команда умеет в ruby поэтому был выбран Test Kitchen & inspec


    Kitchen-CI


    kitchen-ci schema


    Идея до безобразия простая. Создаем новую виртуальную машину, применяем роль, прогоняем smoke-test.


    Green Build Policy


    Green build policy schema


    Но решили идти дальше. Использовать аля github flow, т.е. роли в отдельных бранчах и после ревью мерджим в мастер. Если тесты ок, то накатываем роли на инфраструктуру.


    Вложенная виртуализация


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


    we need to go deeper


    Изначально попробовали Virtualbox x32 что бы не включать поддержку nested. Это оказалось не очень идей из-за стабильныз kernel panic. Второй важный фактор, что мы сидим на x86_64, так что изыскания продолжились(привет libvirt), но остановились на virtualbox как более распространным по поддерживаемым ОС.


    Сложности


    Во время запуска это всего добра был ряд сложностей


    Прокинуть настройки proxy с хоста в гостя гостя


    В некоторых тестовых сценарияъ использовалась настройки proxy, при этому на хосте с testkitchen использовался прозрачный прокси и бонусом ansible не принимал extra variables с пустыми значениями.


    Решение: банально — создаем ERB шаблон.


    <%= ENV['http_proxy'].to_s.empty? ? 'http://proxy.example.com:3128' : ENV['http_proxy'] %>

    Управление сетевыми настройками через ansible


    В некоторых ролях настраивалась сеть, в тестах это выглядело так:


    • Настраиваем сеть копированием файлика.
    • Применяем настройки сети.
    • Все плохо.

    Решение: Добавить интерфейс к виртуальной машине


    Если тестовый набор содержи "_" все падает


    Virtualbox не может пользовать "_" в имени виртуальной машины. А виртуальная машина использовала название сценария.


    Решение: переименовать тестовые наборы "vm_" => "vm-"


    Тестовые сценарии с установкой Oracle без "." в конце имени виртуальной машины падают


    Роль пользовалась в условном продашине, когда решили покрыть ее тестами. Когда раскатываешь на подготовленную вм — роль отрабатывает, через testkitchen падает.


    Небольшая подсказка


    [root@vm-oracle vagrant]# getent ahosts vm-oracle
    127.0.0.1 STREAM vm-oracle
    127.0.0.1 DGRAM
    127.0.0.1 RAW
    [root@vm-oracle vagrant]# getent ahosts vm-oracle.
    fe80::a00:27ff:febd:bd6a STREAM vm-oracle
    fe80::a00:27ff:febd:bd6a DGRAM
    fe80::a00:27ff:febd:bd6a RAW
    10.0.2.15 STREAM
    10.0.2.15 DGRAM
    10.0.2.15 RAW
    [root@oracle vagrant]# getent ahosts oracle.example.com.
    192.168.128.182 STREAM oracle.example.local
    192.168.128.182 DGRAM
    192.168.128.182 RAW

    Есть идеи что происходит?


    Это был забавный сценарий:


    1. У нас включался биндинг IPv4 только в настройках oracle listener.
    2. oracle использует FQDN.
    3. linux содержит специальную базу "myhostname" для разрешения доменных имен, она использовалась после /etc/hosts & dns серверов.
    4. Vagrant создает VM & обновляет /etc/hosts.

    Чуть поясню:
    Что происходит в случае vm-oracle


    1. vagrant создает виртуальную машину.
    2. vagrant обновляет /etc/hosts(vm-oracle x2)
    3. oracle listener слушает IPv4.
    4. oracle listeners разрешает доменное имя vm-oracle. & получает IPv6.
    5. FAILED

    Что происходит в случае vm-oracle.


    1. vagrant создает виртуальную машину.
    2. vagrant обновляет /etc/hosts ( vm-oracle &  vm-oracle.).
    3. oracle listener слушает IPv4.
    4. oracle listeners разрешает доменное имя vm-oracle. & получает IPv4
    5. OK

    OOM в гости к нам приходит


    OOM случайным образом убивал виртуальные машину. Testkitchen при этому в логах своих давал всякие странные собщение.


    Решение: Увеличить колличество памяти.


    Медленные билды


    Вся эта схма работала медленно, десятки минут, иногда и больше часа.


    Решения:


    • Packer. Предсобирать образы виртуальных машин.
    • Пускать несолько тестовых сценариев в параллель

    Заключение


    Если мы говорим, что инфраструктура это код, то к её созданию должна применяться та же философия, что и для разработки ПО. С одной стороны получилось рабочее решение, но есть некоторые неприятные момент:


    • Не дружелюбно оно все выглядит.
    • Смесь ruby & python.
    • Отсутсвует проверки иимутабельности ролей.
    • Медленно работает.
    • Сложно....

    На выходе molecule с docker смотрится интересно и более нативно. Мы подумываем об этом.


    Ссылки


    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 15

      +2

      Молекула вполне хороша для юнит-тестинга ролей.
      Я даже пробовал TTD с ней. Ну так, нормально получается.
      Но как с ней без боли делать интеграционные тесты — тайна великая есть.
      Так что похоже придется брать у коллег вариант с vagrant или придумывать свой вариант.
      А теперь добавьте к этому то что инфраструктура может быть не только в ansible но и в оркестрации — terraform или ещё чего. И тут вообще лес тёмный.

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

        Поэтому и пишу что кухня «сложная». Щас вектор мысли примерно такой:
        1. по максимуму выносить «юнит тестирование», это как раз молекула.
        2. на создание виртуалок забить из-за того что долго, делать ревью при мерджах.
        3. модули ansible тестировать средствами языка
          0
          Странно, как раз молекулой интеграционное тестирование нескольких ролей очень даже неплохо получается, за счет возможности нормально поднять одновременно несколько разных виртуалок, в отличие от test kitchen, которая в автоматическом режиме поднимает виртуалки по одной. Или я чего-то не знаю?
            0

            Нескольких ролей на одном хосте — да. А если мне надо тестировать поэйбук который конфигурирует 3 сервера? Как молекула с таким справится?


            Имхо никак. Это не ее цель

              0
              Похожая проблема.
              Я хочу тестировать плейбуки, а это несколько комбинаций хостов ролей и переменных.
              И вот как это делать и не сойти с ума, не представляю.
                0
                в testkitchen такой подход как раз удобно реализовать, но дружить с ansible не очень удобно
                  0

                  Вот только вроде при запуске kitchen test кухня поднимает и тушит виртуалки по очереди, в отличие от молекулы. Или есть какой то обходной путь помимо руками вызвать kitchen converge && kitchen verify && kitchen destroy?

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

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


                        Может для конкретики обсудим более прикладную задачу?

                0

                Очень даже справляется. Пример можно посмотреть например тут: https://github.com/ansible/molecule/tree/master/test/scenarios/driver/docker/molecule/multi-node Для AWS или вагранта — аналогичные тесты в соседних директориях

                  0
                  спасибо, интересная ссылка. на кухне подобное делал подсовывая свой vagrantfile
            0
            дубль, удалён
              0
              Небольшой вопрос — а вы не сталкивались с необходмостью перезагружать виртуалки в ролях? Просто в этом случае test kitchen теряет соединение, и говорит что test failed, в отличие от молекулы, которые отрабатывает такие ситуации нормально. Возможно вы как-то смогли это обойти?
                0

                Именно в такой формулировке не сталкивался. В packer это решали отдельным шагом. При тестирование своего линукс дистрибутива в эта логика была в обертке на баше которая выжидала поднятие сети по таймауту

              Only users with full accounts can post comments. Log in, please.