Распространение на другие хосты, если Serial уже используется в ansible.
У меня более 80 хостов, на которых работает мое приложение, и я обновляю давно существующую книгу сценариев Ansible, чтобы изменить наш балансировщик нагрузки. В нашей текущей настройке балансировщика нагрузки хосты можно добавлять/удалять из балансировщика нагрузки за один проход, используя интерфейс командной строки AWS. Однако мы переходим на балансировщик нагрузки, настроенный на нескольких наших собственных хостах, и будем подключать и отключать хосты, манипулируя текстовыми файлами на этих хостах с помощью ansible. По сути, мне нужен внутренний цикл по различным хостам в книге воспроизведения при использовании Serial.
У меня возникли проблемы со структурированием сборника сценариев, чтобы я мог развернуть его веером.
Вот что я хочу сделать:
---
- 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"
Как я могу структурировать это, чтобы разрешить внутренний цикл?
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 — это плагин поиска, который создает шаблоны инвентаризации, туда можно использовать любой шаблон.
Пара хитрых вещей по этому поводу. Любой сбой в «пограничном» цикле приведет к сбою узла «приложения». Это оставит частичное состояние некоторых пограничных хостов включенными, а некоторых нет. Если только у вас нет какого-то механизма возврата, например, блока со спасательной функцией, который его отменяет.
В цикле задач некоторые функции, связанные с инвентарем и игрой, не будут применяться. Вы не можете дополнительно ограничить пограничные хосты с помощью--limit
в командной строке. Вы также не можете использоватьserial
чтобы сгруппировать их, это уже в пьесе.
Кроме того, он будет выполнять относительно большое количество задач, по крайней мере, приложение ✕ Edge ✕ 2. Это может быть немного медленно. Можно несколько смягчить ситуацию, увеличив количество вилок.
Если бы у вашего балансировщика нагрузки с несколькими хостами была одна плоскость управления, вам не нужно было бы задействовать так много хостов. Выполнение одной задачи на каждый сервер приложений. Возможно, в данный момент вы не готовы к этому, но стоит об этом подумать.