Mitogen์œผ๋กœ Ansible ์†๋„ ํ–ฅ์ƒ

์ฑ…์ž„๊ฐ์žˆ๋Š” ๊ฐ€์žฅ ์ธ๊ธฐ์žˆ๋Š” ๊ฒƒ ์ค‘ ํ•˜๋‚˜๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ๊ด€๋ฆฌ. ํ›„์— Red Hat์—์„œ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค. 2015๋…„์—๋Š” ์ˆซ์ž ํ”„๋กœ์ ํŠธ ์ฐธ๊ฐ€์ž ์ˆ˜์ฒœ ๊ฐœ๊ฐ€ ๋„˜์—ˆ๊ณ  Ansible์€ ์•„๋งˆ๋„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐฐํฌ ๋ฐ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์‹œ์Šคํ…œ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์‘์šฉ ๋ถ„์•ผ๊ฐ€ ๋งค์šฐ ์ธ์ƒ์ ์ž…๋‹ˆ๋‹ค.

Ansible์€ ์›๊ฒฉ ํ˜ธ์ŠคํŠธ์— ๋Œ€ํ•œ SSH ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. SSH ์„ธ์…˜์„ ์—ด๊ณ  ๋กœ๊ทธ์ธํ•œ ํ›„ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด Python ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ  ๋ณ„๋„์˜ ์ž„์‹œ ํŒŒ์ผ์— ์”๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์›๊ฒฉ ์‹œ์Šคํ…œ์—์„œ ์ด ํŒŒ์ผ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ „์ฒด ์ž‘์—… ์ˆœ์„œ๋Š” ์ƒ๋‹นํžˆ ๊ธธ๊ณ  ์ง€๋ฃจํ•˜๋ฏ€๋กœ ์ด๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋Š” SSH ํŒŒ์ดํ”„๋ผ์ธ ์ด๋ฅผ ํ†ตํ•ด ๋งค๋ฒˆ ์ƒˆ ์„ธ์…˜์„ ์—ฌ๋Š” ๋Œ€์‹  ํ•˜๋‚˜์˜ SSH ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋งŽ์€ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ทธ๋ƒฅ ๋„๋Š” ๊ฑธ ๊ธฐ์–ตํ•˜์„ธ์š” requiretty sudo ์„ค์ • /etc/sudoers ์›๊ฒฉ ์‹œ์Šคํ…œ์˜ ํŒŒ์ผ)

Ansible์„ ์˜ค๋ฒ„ํด๋Ÿฌํ‚นํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋ฏธํ† ๊ฒ. ์•„์ง ๋“ค์–ด๋ณด์ง€ ๋ชปํ•œ ์‚ฌ๋žŒ์ด ์žˆ๋‹ค๋ฉด ๊ทธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์›๊ฒฉ ์‹œ์Šคํ…œ์—์„œ Python ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Ansible์€ ์‚ฌ์šฉ ์‚ฌ๋ก€ ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. Mitogen์€ ์›๊ฒฉ ์‹œ์Šคํ…œ์—์„œ UNIX ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  zlib๋กœ ์••์ถ•๋˜๊ณ  pickle๋กœ ์ง๋ ฌํ™”๋œ Python ์ฝ”๋“œ๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž‘์—…์„ ๋” ๋นจ๋ฆฌ ์™„๋ฃŒํ•˜๊ณ  ํŠธ๋ž˜ํ”ฝ์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ ์„ค๋ช…์ด ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด๋ณด์‹œ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. "์ž‘๋™ ๋ฐฉ์‹". ํ•˜์ง€๋งŒ ์˜ค๋Š˜์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Ansible๊ณผ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์—๋งŒ ์ง‘์ค‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŠน์ • ์ƒํ™ฉ์—์„œ Mitogen์€ Ansible ์ฝ”๋“œ ์†๋„๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋†’์ด๊ณ  ํŠธ๋ž˜ํ”ฝ ์†Œ๋น„๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ํ™•์ธํ•˜๊ณ  ์ด๊ฒƒ์ด ์šฐ๋ฆฌ์—๊ฒŒ ์–ผ๋งˆ๋‚˜ ๋„์›€์ด ๋˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์›๊ฒฉ ์‹œ์Šคํ…œ์—์„œ ๊ตฌ์„ฑ ํŒŒ์ผ ์ƒ์„ฑ, ํŒจํ‚ค์ง€ ์„ค์น˜, ์›๊ฒฉ ์‹œ์Šคํ…œ ๊ฐ„ ํŒŒ์ผ ๋ณต์‚ฌ ๋“ฑ์˜ ์šฉ๋„๋กœ Ansible์„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋‹ค๋ฅธ ์˜ˆ๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•˜์„ธ์š”.

๊ฐ€์ž!

Ansible์˜ Mitogen ๊ตฌ์„ฑ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
Mitogen ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

pip install mitogen

์ด์ œ ๋‘ ๊ฐ€์ง€ ๋™๋“ฑํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ansible.cfg ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ ์˜ต์…˜์„ ๊ตฌ์„ฑํ•˜๊ฑฐ๋‚˜ ํ•„์š”ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„ค์น˜๋œ Mitogen์˜ ๊ฒฝ๋กœ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. /usr/lib/python2.7/site-packages/ansible_mitogen/plugins/strategy. ๊ทธ ๋‹ค์Œ์—:

export ANSIBLE_STRATEGY_PLUGINS=/usr/lib/python2.7/site-packages/ansible_mitogen/plugins/strategy
export ANSIBLE_STRATEGY=mitogen_linear

๋˜๋Š”

[defaults]
strategy = mitogen_linear
strategy_plugins = /usr/lib/python2.7/site-packages/ansible_mitogen/plugins/strategy

Mitogen์ด ์žˆ๊ฑฐ๋‚˜ ์—†๋Š” Ansible์„ virtualenv์— ์„ค์น˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

virtualenv mitogen_ansible
./mitogen_ansible/bin/pip install ansible==2.7.10 mitogen
virtualenv pure_ansible
./pure_ansible/bin/pip install ansible==2.7.10

Mitogen 0.2.7์€ Ansible 2.8์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(2019๋…„ XNUMX์›” ๊ธฐ์ค€).

๋ณ„์นญ ๋งŒ๋“ค๊ธฐ:

alias pure-ansible-playbook='$(pwd)/pure_ansible/bin/ansible-playbook'
alias mitogen-ansible-playbook='ANSIBLE_STRATEGY_PLUGINS=$(pwd)/mitogen_ansible/lib/python3.7/site-packages/ansible_mitogen/plugins/strategy ANSIBLE_STRATEGY=mitogen_linear $(pwd)/mitogen_ansible/bin/ansible-playbook'

์ด์ œ ์›๊ฒฉ ์‹œ์Šคํ…œ์—์„œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ํ”Œ๋ ˆ์ด๋ถ์„ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

---
- hosts: all
  gather_facts: false
  tasks:
    - name: Create files with copy content module
      copy:
        content: |
          test file {{ item }}
        dest: ~/file_{{ item }}
      with_sequence: start=1 end={{ n }}

๊ทธ๋ฆฌ๊ณ  Mitogen์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‹คํ–‰ํ•˜์—ฌ 10๊ฐœ์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

time mitogen-ansible-playbook file_creation.yml -i hosts -e n=10 &>/dev/null

real    0m2.603s
user    0m1.152s
sys     0m0.096s

time pure-ansible-playbook file_creation.yml -i hosts -e n=10 &>/dev/null

real    0m5.908s
user    0m1.745s
sys     0m0.643s

2๋ฐฐ์˜ ๊ฐœ์„ ์ด ๋ณด์ž…๋‹ˆ๋‹ค. 20, 30, ..., 100๊ฐœ์˜ ํŒŒ์ผ์„ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

time pure-ansible-playbook file_creation.yml -i hosts -e n=100 &>/dev/null

real    0m51.775s
user    0m8.039s
sys     0m6.305s

time mitogen-ansible-playbook file_creation.yml -i hosts -e n=100 &>/dev/null

real    0m4.331s
user    0m1.903s
sys     0m0.197s

๊ทธ ๊ฒฐ๊ณผ ์‹คํ–‰ ์†๋„๊ฐ€ 10๋ฐฐ ์ด์ƒ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค!
์ด์ œ ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹œ๋„ํ•ด๋ณด๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๋นจ๋ฆฌ ์ž‘๋™ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๋กœ์ปฌ ํ˜ธ์ŠคํŠธ์—์„œ ์›๊ฒฉ ํ˜ธ์ŠคํŠธ๋กœ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ(๋ชจ๋“ˆ ์‚ฌ์šฉ) copy):
    Mitogen์œผ๋กœ Ansible ์†๋„ ํ–ฅ์ƒ

  • ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์›๊ฒฉ ํ˜ธ์ŠคํŠธ์— ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ copy ๊ธฐ์ค€ ์น˜์ˆ˜:
    Mitogen์œผ๋กœ Ansible ์†๋„ ํ–ฅ์ƒ

  • ์›๊ฒฉ ํ˜ธ์ŠคํŠธ์—์„œ ๋กœ์ปฌ ํ˜ธ์ŠคํŠธ๋กœ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค:
    Mitogen์œผ๋กœ Ansible ์†๋„ ํ–ฅ์ƒ

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์›๊ฒฉ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์›๊ฒฉ ํ˜ธ์ŠคํŠธ์— ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค).
Mitogen์œผ๋กœ Ansible ์†๋„ ํ–ฅ์ƒ

๋ณด์‹œ๋‹ค์‹œํ”ผ Mitogen์€ ์ด๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์‹œ๊ฐ„๊ณผ ํŠธ๋ž˜ํ”ฝ์„ ๋ชจ๋‘ ์ ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด Ansible์— ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜ˆ๋ฅผ ๋“ค์–ด ๋””์Šคํฌ๋‚˜ ๋„คํŠธ์›Œํฌ์˜ I/O ๋˜๋Š” ๋‹ค๋ฅธ ๊ณณ์— ์žˆ๋Š” ๊ฒฝ์šฐ Mitogen์ด ๋„์›€์„ ์ค„ ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

pip๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ yum/dnf ๋ฐ Python ๋ชจ๋“ˆ์ด ํฌํ•จ๋œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๊ฒฐํ•จ์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ํŒจํ‚ค์ง€๊ฐ€ ์บ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

---
- hosts: all
  gather_facts: false
  tasks:
    - name: Install packages
      become: true
      package:
        name:
          - samba
          - httpd
          - nano
          - ruby
        state: present

    - name: Install pip modules
      become: true
      pip:
        name:
          - pytest-split-tests
          - bottle
          - pep8
          - flask
        state: present

Mitogen์„ ์‚ฌ์šฉํ•˜๋ฉด 12์ดˆ๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” Mitogen์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
ํŽ˜์ด์ง€ Ansible ํŽ˜์ด์ง€์šฉ Mitogen ๋‹ค๋ฅธ ๋ฒค์น˜๋งˆํฌ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

Mitogen์€ ๋ชจ๋“ˆ์ด ์‹คํ–‰ ์ค‘์ผ ๋•Œ ๋ชจ๋“ˆ ์†๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์„ ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ฆฌ ์‹คํ–‰ํ•  ์ˆ˜๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฐฐํฌ ์‹œ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์ฐพ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋ฉฐ, ์ด๊ฒƒ์ด Ansible ๋•Œ๋ฌธ์ธ ๊ฒฝ์šฐ Mitogen์€ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ํ”Œ๋ ˆ์ด๋ถ ์‹คํ–‰ ์†๋„๋ฅผ ํฌ๊ฒŒ ๋†’์ด๋Š” ๋ฐ ๋„์›€์„ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€