예전에는 sendmail server를 설정할 수 있으면 고수로 대우받을 수 있었습니다.

sendmail 외엔 무료로 쓸수 있는 mail server 가  없었지만 sendmail 의 설정 파일은 바이너리 코드 수준으로 사람이 읽기 매우 어렵고 난이도가 높아서 설정과 사용이 어려웠습니다.


이렇게 오랫동안 시스템 관리와 인프라 관리는 command line 에서 명령어를 치고 설정 파일을 직접 편집하면서 운영 업무를 수행해 왔습니다.


수작업을 하면 여러 문제가 있지만 그 중에 하나는 확장이 어렵다는 점입니다.


예전에야 초고가의 workstation 을 구매하고 여기에서 모든 workload 를 실행했고 용량이 부족하면 CPU 나 메모리를 증설하는 scale up 의 시대였지만 지금은 클라우드 환경에서 Scale out 이 중요한 시대이며 작게 시작하고 기민하게 대응해야 할 때입니다.

만약 수작업으로 운영 업무를 했다면 서비스 성공해도 인프라를 이에 맞게 확장하기 어려운 문제가 있습니다.


또 하나의 큰 문제는 시스템 변경이나 설정을 수작업으로 운영자가 일일이 한다면 실수로 단계를 건너뛰거나 잘못된 명령어를 실행할 소지가 큽니다.

특히 규모가 커지면 작업의 복잡도와 실수 여지도 비례해서 커지므로 비즈니스의 성장을 뒷받침하기가 어려워집니다.


이런 문제를 해결하기 위해 "코드로 인프라 관리하기(Infrastructure as Code)" 개념이 대두되었고 자동화를 통해 수작업시 발생하는 인적 오류(human error)를 최소화하고 양질의 운영 서비스를 제공할 필요가 대두되었습니다.


ansible 은 code 로 IT infrastructure 를 자동화하는 도구로 Puppet이나  Chef 와 동일한 역할을 수행하며 다음과 같은 특징이 있습니다.


특징

agent-less

puppet 나 chef 같은 도구들은 관리 대상 서버에 별도의 프로그램을 설치하고 이를 통해서 관리 업무를 수행합니다

이런 프로그램들은 보통 daemon 방식의 agent 로 동작하며 이런 별도의 프로그램들을 통해 강력한 기능을 제공하지만 반대로 agent 설치 및 관리라는 별도의 복잡한 추가 작업이 발생합니다.

특히 이런 프로그램들은 별도의 DSL(Domain Specific Language) 를 갖고 있으며 DSL 이 ruby 로 되어 있으므로 ruby 설치 및 모듈 관리같은 작업이 필요합니다.


ansible은 이런 복잡함을 제거하기 위해 agent 가 없으므로 관리 대상인 노드에 별도의 프로그램 설치가 필요없이 (SSH 접속은 가능해야 합니다.) 기존 IT 인프라를 활용해서 자동화를 구성할 수 있습니다.


쉬운 사용법과 state machine

ansible 은 복잡하지 않고 사용하기가 쉽고 자동화의 절차 및 과정을 이해하기 쉽습니다. 또 자동화 단계를  yaml 문법을 사용해서 작성하므로 에디터만 있으면 쉽게 읽을 수 있습니다.

개인적으로 yaml 은 악명 높은 줄맞춤 문제때문에 선호하는 포맷은 아닙니다.


ansible 은  상태 기계(state machine)의 일종으로 시스템을 원하는 상태로 표현하여 IT 배포를 자동화하므로 필요한 변경만 수행하여 시스템의 상태를 유지합니다.

이로 위해서 아래에서 설명할 멱등성을 제공하므로 ansible 로 관리하는 시스템은 원하는 상태를 충족할 수 있습니다.


멱등성(Idempotent)

위키 백과에서 멱등성의 정의는 다음과 같습니다.

멱등법칙(冪等法則) 또는 멱등성(冪等性, 영어: idempotent)은 수학이나 전산학에서 연산의 한 성질을 나타내는 것으로, 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다. 멱등법칙의 개념은 추상대수학(특히, 사영작용소·폐포연산자 이론)과 함수형 프로그래밍(참조 투명성의 성질과 관련된)의 여러 부분에서 사용하고 있다.


동일 연산을 여러 번 실행해도 같은 결과가 나온다는 의미인데 ansible 에서 제공하는 모든 기능들은 멱등성을 갖도록 설계되어 있으므로 ansible 에서는 동일한 운영 작업을 여러 번 실행해도 같은 결과가 나옵니다.


예로 directory 를 생성하는 mkdir 명령어 는 다음과 같은 경우 에러를 냅니다.

  1. 생성하려는 디렉터리가 이미 있을 경우
  2. 여러 계층의 디렉터리를 만들려고 했는데 상위 디렉터리가 없을 경우

다음 명령어를 실행할 경우 docs 가 이미 있다면 mkdir 은 오류를 냅니다.

mkdir docs
BASH

또 다음과 같이 계층적으로 디렉터리를 생성할 경우 c 의 상위 디렉터리가 없어도 오류가 발생합니다.

mkdir a/b/c
BASH

위 명령어들은 현재 상태에 따라 결과값이 달라지므로 멱등성을 갖지 않으며 멱등성을 갖게 하려면 "디렉터리가 있어도 에러를 내지 않고 상위 디렉터리가 없을 경우 만들어 주는" --parents 옵션을 추가하면 됩니다.


또 하나의 예로 SELinux 의 설정을 enforcing 으로 하고 사용한다고 가정해 보겠습니다. 그러면  /etc/selinux/config 에 다음과 같은 내용이 들어가야 합니다.

SELINUX=enforcing
SELINUXTYPE=targeted 
CODE


먼저 다음과 같이 echo 구문을 사용할 수 있습니다.

echo "SELINUX=enforcing" >> /etc/selinux/config 
BASH


위 명령어를 여러 번 실행하면 기존 설정 파일에 덧붙이므로 실행 횟수만큼 동일한 내용이 계속 추가되고 설정 파일이 변경되므로 멱등성이 없는 작업이며 관리하기도 어렵게 됩니다.

SELINUX=enforcing
SELINUXTYPE=targeted
SELINUX=enforcing
SELINUX=enforcing
CODE

그렇다고 이런 간단한 작업을 위해서 sed 등으로 스크립트를 사용하는 것은 작성 및 검증 시간을 고려하면 효율적이지 않습니다.


ansible 의 모듈중 하나인 lineinfile 을 사용하면 파일에 특정 항목이 없으면 추가하고 다른 값이 있으면 변경해 주므로 여러 번 실행해도 동일한 결과를 가져옵니다.

- name: Ensure SELinux is set to enforcing mode
  lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: SELINUX=enforcing
CODE


ansible 은 위와 같이 제공하는 기능들이 멱등성을 갖도록 설계되어 있으므로 같은 스크립트를 여러 번 실행해도 동일한 결과를 낼 수 있으므로 작업을 단순화하고 인적오류를 최소화하며 서버의 상태를 정의하고 관리할 수 있습니다.

구성 요소

ansible 구성 요소

module

ansible 은 멱등성이 보장되는 다양한 기능의 모듈을 제공하며 운영자는 모듈을 직접 실행하거나 또는 playbook 을 통해서 체계적으로 실행할 수 있습니다.


예로 command 모듈을 사용하면 리모트 호스트에서 정해진 명령을 실행할 수 있습니다.

ansible webserver  -m command -a "/bin/systemctl reboot"
BASH


원하는 module 이 없을 경우 직접 개발하거나 사용자 모듈 repository 인 ansible galaxy 에서 다운 받아서 실행할 수 있습니다.

커뮤니티 모듈은 멱등성을 제공하지 않을수도 있습니다.


inventory

인벤토리는 ansible 로 관리할 host 의 묶음으로 호스트는  그룹에 포함시켜서 관리할 수 있습니다. 그룹은 하위 그룹을 포함할 수 있으며 한 호스트는 여러 그룹에 포함될 수 있습니다.

인벤토리는 windows 의 INI 형식으로 관리할 수 있으며 다음은 web-servers 라는 그룹과 db-servers 라는 호스트 그룹을 만들고 다시 이 두 그룹을 포함하는 mybiz-servers 라는 그룹을 생성합니다.

[web-servers]
web1.example.com
web2.example.com

[db-servers]
db1.example.com
db2.example.com

[mybiz-servers:children]
web-servers
db-servers
CODE

playbook

ansible 은 "자동화 절차를 기술한 파일"을 playbook 이라 부르며 이 파일은 yaml 문법을 사용해서 작성합니다.


Ansible Control Node

ansible playbook 을 실행해서 변경을 수행할 서버로 Linux 나 Unix 계열 OS 여야 합니다. 또 ansible 은 python 으로 개발되었으므로 python 3.5 이상 설치가 필요합니다.


Managed Hosts

ansible 이 상태 관리를 수행할 변경 대상 시스템으로 inventory 에 정의되어 있습니다.