Распределение по другим хостам при использовании Serial в Ansible

Распределение по другим хостам при использовании Serial в Ansible

У меня есть более 80 хостов, на которых работает мое приложение, и я обновляю давно существующий ansible playbook, чтобы изменить наш балансировщик нагрузки. В нашей текущей настройке балансировщика нагрузки хосты можно добавлять/удалять из балансировщика нагрузки за одну ansible play, обращаясь к AWS CLI. Однако мы переключаемся на балансировщик нагрузки, настроенный на нескольких наших собственных хостах, и будем вводить и выводить хосты, манипулируя текстовыми файлами на этих хостах с помощью ansible. По сути, мне нужен внутренний цикл по разным хостам в playbook, при этом используя Serial.

У меня возникли проблемы со структурированием сценария таким образом, чтобы можно было разослать blockinfileкоманды хостам в группе, tag_Type_edgeодновременно выполняя развертывание на 80 tag_Type_appхостах с последовательным портом: 25%.

Вот что я хочу уметь делать:

---
- hosts: tag_Type_app
  serial: "25%"
  pre_tasks:

    - name: Gathering ec2 facts
      action: ec2_metadata_facts

    - name: Remove from load balancers
      debug:
        msg: "This is where I'd fan out to multiple different hosts from group tag_Type_edge to manipulate
              text files to remove the 25% of hosts from tag_Type_app from the load balancer"

  tasks:
    - name: Do a bunch of work to upgrade the app on the tag_Type_app machines while out of the load balancer
      debug:
        msg: "deploy new code, restart service"


  post_tasks:
    - name: Put back in load balancer
        debug:
          msg: "This is where I'd fan out to multiple different hosts from group tag_Type_edge to manipulate
                 text files to *add* the 25% of hosts from tag_Type_app back into the load balancer"

Как мне структурировать это так, чтобы обеспечить внутренний цикл tag_Type_edgeпри использовании serial: 25% на всех tag_Type_appящиках?

решение1

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

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

---
- name: Example loop over load balancers for each app server
  hosts: tag_Type_app
  serial: "25%"

  pre_tasks:
    - name: Gathering ec2 facts
      action: ec2_metadata_facts

    - name: Remove from load balancers
      debug:
        msg: "Remove app instance {{ inventory_hostname }} from edge node {{ item }}"
      delegate_to: "{{ item }}"
      loop: "{{ query('inventory_hostnames', 'tag_Type_edge') }}"

  tasks:
    - name: Do a bunch of work to upgrade the app on the tag_Type_app machines while out of the load balancer
      debug:
        msg: "deploy new code, restart service"

  post_tasks:
    - name: Put back in load balancer
      debug:
        msg: "Add app instance {{ inventory_hostname }} to edge node {{ item }}"
      delegate_to: "{{ item }}"
      loop: "{{ query('inventory_hostnames', 'tag_Type_edge') }}"

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

Пара сложных моментов. Любой сбой в цикле "edge" приведет к сбою хоста "app". Что оставит частичное состояние некоторых хостов edge включенным, а некоторых нет. Если только у вас нет какого-то механизма отката, например, блока со спасательным средством, которое его отменяет.

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

Также он будет запускать относительно большое количество задач, по крайней мере app ✕ edge ✕ 2. Это может быть немного медленно. Можно было бы немного смягчить, увеличив количество форков.

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

Связанный контент