ansible에서 playbook 처리 루틴 이해

- ansible에서 playbook을 처리하면, 순서대로 각 play를 실행한다. 일반적으로 클라이언트가 플레이에서 다음 작업을 시작하기 전에, 모든 클라이언트가 작업을 성공적으로 완료해야 한다.

- 이론상으로는 ansible이 play실행 시 각 작업의 모든 클라이언트에 동시에 연결할 수 있다. 이것은 소규모의 경우 잘 작동한다. 하지만 play가 수백개의 호스트를 대상으로 하는 경우, 제어노드에 많은 부하가 걸릴 수 있다.

- ansible이 만드는 최대 동시 연결 수는 ansible 구성 파일에서 forks 매개 변수로 제어할 수 있다. 이 값의 default는 5이다.

- 예시 : 만약 play에 10개의 클라이언트가 있다면 ansible은 처음 5개의 클라이언트에 대해 첫번째 play 작업을 끝내고, 그 다음 다른 5개의 클라이언트의 첫번째 play작업을 두번째로 실행한다. 이런식으로 여러개의 클라이언트에 대해 play가 끝날때까지 이 작업을 수행한다.

 

forks 지시문 사용하기

- forks 지시문은 ansible.cfg의 [defaults] 섹션에 명시한다.

- forks = 20 이런식으로 사용.

- ansible.cfg에 설정하지 않았더라도, 명령행의 ansible, ansible-playbook 명령 각각에서 -f / --forks 옵션을 사용해 forks 수를 지정할수도 있다.

 

- play는 순서대로지만, 해당 play가 실행되는 클라이언트들은 하나가 아닌 여러개면 순서가 따로 정해진 게 아니라 fork 수만큼 한번에 명령을 전달하며, 응답한 순서대로 결과를 출력한다. 따라서 출력 결과는 항상 다를 수 있다.

- 예를들어 example1~4 호스트가 있다면, ping 모듈을 써서 명령을 쳤을 때 4가 먼저 나올수도 있고 2가 먼저 나올수도 있다.

 

 

 

ansible host (제어 노드)의 부하

- ansible host가 리눅스 클라이언트들을 관리하는 경우, 대부분 작업은 클라이언트에서 실행되므로 ansible host는 로드가 적다. 이 경우에는 일반적으로 forks는 높은 값으로(100 전후) 설정하면 성능이 향상되는 것을 볼 수 있다.

- ansible host가 네트워크 라우터,스위치 등을 관리하면 대부분의 모듈이 ansible host에서 실행되기 때문에 ansible host의 부하가 심하다. 리눅스 클라이언트와 비교했을 때 지원 가능한 forks의 수가 현저히 낮을 수 있다.

- 다시 정리하면, 어떤 환경이든 ansible host의 부하가 심할 수 있다면 forks 값을 적절히 조절해야 한다. 

 

 

play 실행 구조의 문제점과 롤링 업데이트

위에서 언급한 대로, ansible이 play를 실행하면, 모든 클라이언트가 해당 play를 완료해야만 다음 작업으로 넘어간다. 또한 모든 클라이언트가 모든 작업을 완료한 후에는 알림을 받은 핸들러가 실행된다.

 

그런데 이렇게 하면 문제의 여지가 있다. 예를 들어, 하나의 플레이가 부하 분산된 웹 서버 클러스터를 업데이트 한다면, 업데이트 하면서 웹 서버 클러스터 안의 모든 웹서버들이 다 다운타임을 갖게 된다. 따라서 클러스터임에도 서비스가 중지된다.  따라서 ansible에서 한번에 작업을 다 하지 않고 rolling으로 작업할 수 있는 구문이 필요하다.

 

 

serial 지시문

하나의 play에 모든 클라이언트이 한번에 작업이 완료되어야 하지 않도록, serial이라는 키워드를 사용할 수 있다. serial 지시문을 2로 설정하면, 예를들어 hosts에 명시된 클라이언트가 6개인 경우, 2개의 클라이언트에 대해 play를 실행하고, 핸들러까지 실행해서 모두 다 완료한다. 그 후에 그 다음 2개의 클라이언트에 대해 또 동일하게 진행하고 또 그 다음 남은 2개의 클라이언트에 대해 동일하게 진행한다.

 

* 예시

---
- name: rolling update
  hosts: webservers
  serial: 2
  tasks:
    - name: ....

- 이런 방식으로 사용된다. 또한 개수(숫자)가 아닌 백분율로도 지정할 수 있다. 이 백분율은 클라이언트의 갯수에 적용된다. 

 

* 예시 결과

- 클라이언트가 5개이고, serial: 2 로 설정하면, 아래와 같이 2개씩 나눠서 따로따로 수행하는것을 확인할 수 있다.

 

 

# 참고 : 에러가 발생하는 경우

- serial: 2로 했을 때 첫번째 2개가 실패하면, 플레이북이 중지되고 이후 남은 4개는 아예 실행되지 않는다.

 

 

 

결론

전체적으로 간단하게 정리하면, 다음과 같다.

- forks : ansible이 만드는 최대 동시 연결 수.

- serial : 한번에 play를 실행할 호스트 수

 

 

 

 

 

 

참조 링크

 

롤링 업데이트 배치 크기, 위임, 롤링 업데이트 및 로컬 작업 ansible 설명서

docs.ansible.com/ansible/2.7/user_guide/playbooks_delegation.html#rolling-update-batch-size

 

Delegation, Rolling Updates, and Local Actions — Ansible Documentation

You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. Being designed for multi-t

docs.ansible.com

 

ansible 성능 튜닝

https://www.ansible.com/blog/ansible-performance-tuning

 

+ Recent posts