Ansible

snooby·2022년 8월 12일
2

☁ Cloud

목록 보기
13/24
post-thumbnail

Infrastructure as a Code

앤서블은 여러 개의 서버를 효율적으로 관리하기 위해 만들어진 환경 구성 자동화 도구 입니다.

기본적으로 환경 자동화 세팅을 Bash 쉘 스크립트를 사용하여 많이 구성하는데, 이는 한계가 있습니다.
클러스터에 존재하는 많은 서버들에 동시에 동일한 환경으로 배포해야 하는 경우에 특히 그러합니다.

Ansible은 환경의 배포와 구성을 미리 선언적으로 작성한 코드에 맞춰 모든 서버에 배포함으로써 특정 환경을 동일하게 유지할 수 있도록 돕습니다. 이렇게 코드로 선언된 환경으로 세팅할 수 있게하는 것을 Infrastructure as a Code라고 합니다.

자동화가 왜 필요한가.

실제 환경에서 진행을 하다보면 어느순간 클러스터의 일부만 상태를 변경해야 하거나, VM이 일부는 Ubuntu, CentOS 섞여있는 클러스터인 경우도 있고 서버의 환경 세팅값이 다른 상황으로 구성해야하는 경우가 있습니다. 이러한 경우 각 서버 개수만큼 n번 이상의 작업을 요하게 됩니다.
너무 노가다 스럽고 단순 반복과 스트레스 유발의 작업이 더욱이 자동화가 필요하다는 것의 이유입니다.

더욱이 요즘처럼 클라우드로 많은 인프라 환경이 넘어가는 상황에서는 서버인프라 자동화는 필수라고 생각합니다.

Ansible

모든 애플리케이션처럼 앤서블도 서버와 클라이언트 구조로 이루어져있습니다.
그러나 앤서블은 에이전트가 없는 구조이기에 별도의 에이전트 설치가 필요하지 않아 상대적으로 간편합니다.
기존의 에이전트 역할은 SSH 데몬이 대체하기 때문에 SSH 접속만 가능한 서버라면 엔서블의 제어 대상이 될 수 있습니다.

한 VM에서 앤서블 커맨드를 실행하고, 다른 VM이 SSH 데몬을 통해 제어되는 구조입니다.

여러 서버를 효율적으로 관리할 수 있도록 돕는 환경 구성 도구 (provisioning 도구)

Python 기반으로 작성된 오픈소스로 Redhat 주체 하에 관리되고 있습니다.
ansible github
앤서블을 yaml형식으로 DSL를 작성하면, 앤서블이 해당 DSL을 이용해서 명령어를 실행해주는 방식. 앤서블은 대상 서버에 명령어를 실행하기 위해 SSH를 이용합니다.
따라서, 대상 서버에 ssh로 접속할 수 있게 세팅되어있어야 합니다.

앤서블을 쓰는 이유

1. shell의 한계

기존의 서버 세팅, 배포는 shell script를 사용하여 작성하였습니다.
shell은 unix 기반에서 별도의 라이브러리 설치없이 실행가능하다는 장점이 있지만,
shell만으로 여러 서버의 환경을 구성하는 것은 한계가 있습니다.
shell을 사용하여 json 파싱, xml 파싱 어려움 -> ansible은 미리 구현된 모듈로 쉽게 파싱할 수 있습니다.

2. yaml을 이용한 DSL

앤서블은 yaml을 이용해서 작업 내용들을 정의하기 때문에 shell script보다 쉽게 작성할 수 있습니다.
따라서, 앤서블 DSL에 대한 학습이 필요합니다. 또한 shell보다 덜 유연해서 복잡한 구문 작성은 어려움이 있습니다.

3. 멱등성 제공

엔서블은 멱등성을 제공하는 환경 자동화 도구입니다.

엔서블의 플레이북에서는 모듈 실행 시 결과를 상태로 정의함으로써 최종적으로 존재하는 환경을 명시합니다. 해당 상태가 만족된다면 앤서블은 다른 작업을 하지 않고 task를 종료하는데, 이는 플레이북을 몇번이라도 실행하더라도 동일하게 수행되게합니다. 따라서, 앤서블은 플레이북에서 정의된 바람직한 상태를 만족하도록 수행하기 때문에 동일한 플레이북을 몇번이고 실행해도 동일한 최종 결과값을 얻을 수 있는 멱등성을 제공하게 되는 것입니다.

앤서블이 제공하는 모듈의 대부분은 멱등성을 제공하는 것을 원칙으로 하기에 모듈의 옵션 또한 멱등성을 고려하여 명시하도록 되어있습니다. 따라서 한번 성공적으로 수행된 플레이북은 다시 재실행하더라도 서버에 전혀 영향을 끼치지 않게됩니다. 이미 플레이북이 원하던 상태에 도달하였기 때문에 더 이상 작업을 수행하지 않는 멱등성을 준수하게 되는 것입니다.

가령, yum 모듈을 통해 state:installed로 명시된 플레이북이 실행될 때, 해당 패키지가 이미 설치되어 있다면 해당 task는 아무런 동작도 하지 않고 success로 처리된 뒤 종료됩니다.

4. Infrastructure as Code

코드로 관리하는 인프라라는 개념으로 해당 어플리케이션의 환경정보를 코드로 관리해서 형상관리를 하자는 것입니다.

엔서블 기본개념

엔서블에는 크게 3가지 요소가 존재합니다.

1. 인벤터리
2. 플레이불
3. 모듈

이는 가각 어디서, 무엇을, 어떻게 수행할지에 대하여 정의합니다.

1. 인벤터리

엔서블에 의해 제어되어 Infrastructure as a Code의 대상이 될 서버들의 목록을 정의하는 파일입니다.
일반적으로 hosts.ini 파일에 정의하여 사용합니다.

인벤터리에는 여러 서버들의 접속 정보 (SSH 접근 IP, 포트, 리눅스 사용자) 등을 정의합니다.

서버이름 ansible_host=서버 Endpoint ansible_user=리눅스 사용자

-> 서버이름의 서버에 서버 endpoint를 사용하고, 리눅스 사용자를 통해 SSH로 접근한다.

또한, 여러개의 호스트를 그룹화하여 사용할 수 있습니다.

가령, 3개의 서버를 엔서블로 제어하려는개 1개는 ubuntu 2개는 centos라면 호스트 특정에 따라 서버를 분류하여 구분하기 쉽게 하고 그룹별로 원하는 명령어를 적용시킬 수도 있습니다.

  • i 인자를 사용하여 특정 서버 그룹에만 명령어를 내립니다.
ansible -m ping -i hosts_group.ini centos-servers

2. 플레이북

인벤터리 파일에서 정의된 서버들이 무엇을 해야할지 정의합니다.

yaml 포맷으로 작성하며 플레이북은 단독으로 사용되는 것이 아닌 플레이북 + 인벤터리의 조합으로 사용하게 됩니다.
인벤터리를 통해 어디에 작업을 수행할지 정의하고, 플레이북을 통해 무엇을 할지 정의하는 것입니다.
1개 이상의 play를 정의가능하며 각 play는 role과 task를 조합하여 작업 내용을 순서대로 기술합니다.


# play
- hosts: laputa # 대상 호스트
  vars: # playbook 내부 변수
    create_tag: "{{ tagging | default(False) }}"
  tasks: # 작업 내용 기술
    ...

ansible-playbook 명령어로 플레이북 실행하기

ansible-playbook -i hosts.ini 플레이북파일명.yaml

실제 플레이북은 Role이라는 앤서블 요소를 사용해 여러개의 플레이북을 정의해 사용한다.

3. 모듈

모듈은 플레이북에서 task가 어떻게 수행될지를 나타내는 요소입니다.

앤서블 코드를 실행하기 위한 코드 조각으로 앤서블이 정의한 DSL입니다.


- name: java | install {{ java_package }}.rpm
  yum:
    name: "{{ java_source_dir }}/{{ java_package }}.rpm"
    state: present
  become: yes

위의 플레이북 예제에서 task안에 yum 모듈을 사용하여 yum 명령어를 통해 java를 설치할 수 있도록 사용하였습니다.
yum으로 패키지를 설치하려면 어떤 패키지를 설치할건지 삭제할건지 업데이트 할 건지를 명시해야합니다.
그래서 yum 모듈은 어떤 패키지(name)를 어떻게 할건지(state)를 명시하는 것입니다.
모듈마다 요구하는 옵션이 다르므로 검색 후 사용해야합니다.

debug 모듈은 서버에서 디버깅을 위한 각종 값 또는 변수의 출력에 쓰이는 모듈입니다.
어떤 내용을 출력할지에 대한 명시가 있어야 하기 떄문에 msg: 라고 하는 옵션을 명시해줘야합니다.

앤서블 구조

앤서블은 크게 2가지 노드로 구분합니다.

  • controll node
    앤서블이 설치된 노드로써 ansible 명령이 실행가능한 노드입니다.
  • managed node
    앤서블로 관리할 노드로 python만 설치되어있으면 됩니다.
    controll node와 managed node의 python 버전대는 일치해야합니다!!

전반적인 실행 구조

controll node의 inventory에 정의된 호스트들에게 playbook에 정의된 행동을 취합니다.

앤서블 실행

앤서블을 실행하는 방법은 크게 2가지가 있습니다.

  • ad-hoc 명령어 : 단일 작업을 실행시 사용
# ansible 디렉토리에 ansible.cfg 라는 설정 파일 적용을 위해서 이동
$ cd ansible
 
# localhost 에 설치
$ ansible localhost -m include_role -a name=java \
  -e "java_source_dir=/usr/local/src java_package=adoptopenjdk-8-hotspot-8u222_b10-1.x86_64 java_force_install=True"
# -m : 사용할 모듈의 경로 지정
# -a : 모듈의 변수 (파라미터)
# -e : 해당 task 의 외부 변수를 지정
  • playbook 명령어 : 여러 작업을 정의한 playbook을 작성하여 실행
# ansible 디렉토리에 ansible.cfg 라는 설정 파일 적용을 위해서 이동
$ cd ansible
 
 
# laputa 배포 예제 (필수 변수는 외부 변수로 지정하여 전달)
$ ansible-playbook -i inventories/alpha.ini playbooks/deploy.yml -e "branch=alpha/04"
profile
데이터를 가치있게 다루고 싶은 개발자 🐥

0개의 댓글