
์ด์ ์ฑํฐ๊น์ง playbook์ ์คํ ํ๋ฆ์ ์ ์ดํ๋ ๋ฐฉ๋ฒ(๋ฉํฐ play, serial, delegate_to)์ ๋ฐฐ์ ์ต๋๋ค. ์ด๋ฒ์๋ task์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ถ๊ธฐ ์ฒ๋ฆฌํ๊ฑฐ๋ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๊น์ง ์ฌ์๋ํ๋ ํจํด์ ๋ค๋ฃน๋๋ค.
command๋ shell ๋ชจ๋๋ก ๋ช
๋ น์ ์คํํ๋ฉด stdout, stderr, return code ๋ฑ์ด ๋ฐํ๋ฉ๋๋ค. register๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๊ฒฐ๊ณผ๋ฅผ ๋ณ์์ ์ ์ฅํ๊ณ ์ดํ task์์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
playbook/register_test.yml:
---
- name: register test
hosts: managed
gather_facts: false
become: true
tasks:
- name: uptime
command: uptime
register: result
- name: print
debug:
msg: "{{ result.stdout }}"
TASK [uptime] ********************************************************************
changed: [node2]
changed: [node3]
changed: [node1]
TASK [print] *********************************************************************
ok: [node1] => {
"msg": " 08:50:26 up 2:11, 0 user, load average: 1.01, 0.49, 0.25"
}
ok: [node2] => {
"msg": " 08:50:26 up 2:11, 0 user, load average: 1.01, 0.49, 0.25"
}
ok: [node3] => {
"msg": " 08:50:26 up 2:11, 0 user, load average: 1.01, 0.49, 0.25"
}
register๋ ๋ณ์์๋ stdout ์ธ์๋ ๋ค์ํ ํ๋๊ฐ ๋ค์ด ์์ต๋๋ค:
| ํ๋ | ์ค๋ช |
|---|---|
stdout |
ํ์ค ์ถ๋ ฅ (๋ฌธ์์ด) |
stdout_lines |
ํ์ค ์ถ๋ ฅ (์ค ๋จ์ ๋ฆฌ์คํธ) |
stderr |
ํ์ค ์๋ฌ |
rc |
return code (0์ด๋ฉด ์ฑ๊ณต) |
changed |
๋ณ๊ฒฝ ์ฌ๋ถ (bool) |
register๋ก ์ ์ฅํ ๊ฒฐ๊ณผ๋ฅผ when ์กฐ๊ฑด์์ ํ์ฉํ๋ฉด, ์ด์ task์ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค์ task์ ์คํ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
playbook/register_when.yml:
---
- name: register when test
hosts: managed
gather_facts: false
become: true
tasks:
- name: print hostname
command: cat /etc/hostname
register: result
- name: print
debug:
msg: "์ด ๋
ธ๋๋ primary์
๋๋ค."
when: result.stdout == "node1"
TASK [print hostname] ************************************************************
changed: [node3]
changed: [node1]
changed: [node2]
TASK [print] *********************************************************************
skipping: [node2]
ok: [node1] => {
"msg": "์ด ๋
ธ๋๋ primary์
๋๋ค."
}
skipping: [node3]
node1์์๋ง debug ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๊ณ , node2์ node3์ skipping๋ฉ๋๋ค. ๊ฐ ๋
ธ๋์์ cat /etc/hostname์ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ when ์กฐ๊ฑด์ด ๋
ธ๋๋ณ๋ก ๋ค๋ฅด๊ฒ ํ๊ฐ๋ฉ๋๋ค.
์ฒ์ ์์ฑํ ๋ when: result.stdout == node1๋ก ์ฐ๋ฉด ๋ค์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค:
Error while evaluating conditional: 'node1' is undefined
์์ธ: when์์ ๋ฐ์ดํ ์์ด node1์ ์ฐ๋ฉด ๋ณ์๋ก ํด์๋ฉ๋๋ค. node1์ด๋ผ๋ ๋ณ์๋ ์ ์๋ ์ ์ด ์์ผ๋ฏ๋ก undefined ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
ํด๊ฒฐ: ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ๋ฐ๋์ ๋ฐ์ดํ๋ก ๊ฐ์ธ์ผ ํฉ๋๋ค:
when: result.stdout == "node1"
์๋น์ค ๋ฐฐํฌ ํ "์ ์ ์ํ๊ฐ ๋ ๋๊น์ง ๋๊ธฐ"ํ๋ ํจํด์ ๋งค์ฐ ํํฉ๋๋ค. Kubernetes์ readiness probe์ฒ๋ผ, Ansible์์๋ until๋ก ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋ ๋๊น์ง ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
playbook/until_test.yml:
---
- name: until test
hosts: managed
gather_facts: false
become: true
tasks:
- name: print non exist file
shell: cat /tmp/ready.txt
register: result
ignore_errors: true
until: "'ok' in result.stdout"
retries: 5
delay: 3
| ์ต์ | ์ค๋ช |
|---|---|
until |
์ด ์กฐ๊ฑด์ด true๊ฐ ๋ ๋๊น์ง ๋ฐ๋ณต |
retries |
์ต๋ ์ฌ์๋ ํ์ (๊ธฐ๋ณธ๊ฐ: 3) |
delay |
์ฌ์๋ ๊ฐ๊ฒฉ โ ์ด ๋จ์ (๊ธฐ๋ณธ๊ฐ: 5) |
ignore_errors |
์ต์ข ์คํจ ์์๋ playbook์ ์ค๋จํ์ง ์์ |
/tmp/ready.txt๊ฐ ์กด์ฌํ์ง ์๋ ์ํ์์ ์คํํ๋ฉด 3์ด ๊ฐ๊ฒฉ์ผ๋ก 5๋ฒ ์ฌ์๋ํ ๋ค ์ต์ข
์คํจํฉ๋๋ค:
TASK [print non exist file] ******************************************************
FAILED - RETRYING: [node1]: print non exist file (5 retries left).
FAILED - RETRYING: [node1]: print non exist file (4 retries left).
FAILED - RETRYING: [node1]: print non exist file (3 retries left).
FAILED - RETRYING: [node1]: print non exist file (2 retries left).
FAILED - RETRYING: [node1]: print non exist file (1 retries left).
fatal: [node1]: FAILED! => {"attempts": 5, "changed": true, ...
"stderr": "cat: /tmp/ready.txt: No such file or directory", ...}
...ignoring
ignore_errors: true๊ฐ ์์ผ๋ฏ๋ก ์๋ฌ๋ฅผ ๋ฌด์ํ๊ณ playbook์ ์ ์ ์ข
๋ฃ๋ฉ๋๋ค. PLAY RECAP์์ ignored=1๋ก ์ง๊ณ๋ฉ๋๋ค.
๐ก ignore_errors๋ task ๋ ๋ฒจ์ ๋ถ์ด์ธ์
play ๋ ๋ฒจ์
ignore_errors: true๋ฅผ ์ฐ๋ฉด ํด๋น play์ ๋ชจ๋ task์์ ์๋ฌ๊ฐ ๋ฌด์๋ฉ๋๋ค. ์๋์น ์์ ์๋ฌ๋ฅผ ๋์น ์ ์์ผ๋ฏ๋ก, ํ์ํ task์๋ง ๊ฐ๋ณ์ ์ผ๋ก ์ง์ ํ๋ ๊ฒ์ด ์์ ํฉ๋๋ค.
ad-hoc ๋ช ๋ น์ผ๋ก ํ์ผ์ ๋ง๋ ๋ค ๋ค์ ์คํํฉ๋๋ค:
ansible managed -m shell -a "echo ok > /tmp/ready.txt" -b
ansible-playbook playbook/until_test.yml
TASK [print non exist file] ******************************************************
changed: [node1]
changed: [node2]
changed: [node3]
์ฒซ ์๋์์ stdout์ "ok"๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก ์ฌ์๋ ์์ด ๋ฐ๋ก ์ฑ๊ณตํฉ๋๋ค.
command์ shell ๋ชจ๋์ ๋ ๋ค ์๊ฒฉ ๋
ธ๋์์ ๋ช
๋ น์ ์คํํ์ง๋ง, ์ค์ํ ์ฐจ์ด๊ฐ ์์ต๋๋ค:
| command | shell | |
|---|---|---|
| ์ ๊ฒฝ์ | X (์ง์ ์คํ) | O (/bin/sh๋ฅผ ํตํด ์คํ) |
ํ๊ฒฝ๋ณ์ ์นํ ($HOME) |
X | O |
ํ์ดํ (|), ๋ฆฌ๋ค์ด๋ ์
(>) |
X | O |
| ๋ณด์ | injection ์ํ ์์ | ์ ๊ธฐ๋ฅ ์ฌ์ฉ ๊ฐ๋ฅ = injection ๊ฐ๋ฅ์ฑ |
์์น: ์ ๊ธฐ๋ฅ(ํ์ดํ, ๋ฆฌ๋ค์ด๋ ์
, ํ๊ฒฝ๋ณ์ ๋ฑ)์ด ํ์ ์๋ค๋ฉด command๋ฅผ ์ฌ์ฉํ์ธ์. ๋ ์์ ํ๊ณ , ์๋ํ์ง ์์ ์ ํด์์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
| ๊ฐ๋ | ์ญํ | ํ์ฉ ์์ |
|---|---|---|
| register | task ๊ฒฐ๊ณผ๋ฅผ ๋ณ์์ ์ ์ฅ | ์ด์ task ๊ฒฐ๊ณผ๋ก ๋ถ๊ธฐ, ์ถ๋ ฅ ํ์ธ |
| register + when | ์ ์ฅ๋ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ์กฐ๊ฑด๋ถ ์คํ | ํน์ ๋ ธ๋์์๋ง ์ถ๊ฐ ์์ ์ํ |
| until + retries + delay | ์กฐ๊ฑด ์ถฉ์กฑ๊น์ง ์ฃผ๊ธฐ์ ์ฌ์๋ | ์๋น์ค ๊ธฐ๋ ๋๊ธฐ, ์ํ ํ์ธ |
| command vs shell | ์ ๊ฒฝ์ ์ฌ๋ถ ์ฐจ์ด | ์ ๊ธฐ๋ฅ ๋ถํ์ ์ command ์ฐ์ ์ฌ์ฉ |
๋ค์ ์ฑํฐ์์๋ apt์ hold/unhold๋ก ํจํค์ง ๋ฒ์ ์ ๊ณ ์ ํ๊ณ , block/rescue๋ก ์๋ฌ๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค.