메뉴 닫기

자동화 프로그램 앤서블(ansible) 소개

자동화 프로그램 앤서블(ansible) 소개

ansible 소개

IT 기업에 종사하는 직업군은 서비스 운영 또는 제공 목적으로 서버를 셋팅 할 때가 있으며 아래와 같은 케이스로 작업을 진행하기도 합니다.

※ 서버 셋팅 케이스

  • 원격 접속 후 매뉴얼을 참고하여 셋팅
  • 서버에 원격으로 접속하여 쉘 스크립트를 통한 셋팅
  • 별도의 프로그램(ssh, scp, ftp) 등을 응용한 셋팅

서버가 소량이라면 충분히 활용이 가능하지만 수십대 이상일 경우는 어떨까요? 쉘 스크립트를 잘 만들어둔 상태라면 큰 어려움은 없겠지만 실수나 다른 문제로 서버의 운영 체제의 재설치를 진행하는 것은 누구를 막론하고 발생할 수도 있습니다.

앤서블의 구조도

 

앤서블(Ansible)은 이런 고민을 덜어줄 수 있는 오픈소스 프로그램으로 컨트롤러에 설치 또는 도커 이미지를 통해 사용 할 수 있으며 클라이언트 서버에는 별도의 프로그램을 설치하지 않아도 되는 구조로 리눅스/윈도우 계열의 셋팅을 지원합니다. 이렇게 편리한 이유는 ssh를 사용하기 때문이며 두가지 방법을 통해 사용이 가능 합니다. 특히 멱등성을 지원하여 중복 작업을 방지하는 장점도 존재합니다.

※ 앤서블의 사용 방법

  • cmd : 명령어를 통한 직접 컨트롤 
  • Playbook : yaml 파일을 통해 스크립트 처럼 설정하여 서버를 셋팅 멱등성의 경우 개별적인 설정이 필요

테스트에 사용 된 서버와 ansible 설치 방법

본 글에서는 테스트를 위해 3대의 서버를 사용 했습니다.

운영체제 : Ubuntu 22.04 
컨트롤러 서버 : 10.7.2.100
클라이언트 서버 1 : 10.7.2.101
클라이언트 서버 2 : 10.7.2.102

컨트롤러에서 ansible의 레포지토리 등록과 운영체제의 업데이트 및 업그레이드를 진행 후 리부팅을 진행 합니다.

sudo apt-add-repository ppa:ansible/ansible
apt update && apt upgrade -y
reboot

ansible를 설치 합니다. 설치 완료 후 /etc/ansible가 생성되며 해당 디렉토리에서 작업을 진행해도 되지만 여러 서비스를 셋팅하는 엔지니어라면 개별적으로 디렉토리를 관리하는 것이 좋습니다.

apt install ansible
mkdir /ansible/

ansible 테스트

셋팅이 필요한 서버의 내역 리스트를 host에 정리합니다.

vi /ansible/host
[ubuntu_server] #※1
ubuntu1 ansible_host=10.7.2.101 #※2 
ubuntu2 ansible_host=10.7.2.102

#※1 : 서버의 그룹 명입니다.
#※2 : ubuntu1은 10.7.2.101의 호스트 명입니다.

특정 서버에 ssh를 통해 첫 접속을 시도하면 key 관련 내용이 나타나며 앤서블은 ssh를 통해 작동하기에 이 부분이 yes로 처리되지 않은 상태에서 사용하면 에러가 발생합니다.

This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?

ubuntu2 | FAILED! => {
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}

미리 처리해두면 이 문제는 해결되겠지만 서버가 수십대 이상이라면 작업이 지연되겠죠. 보안 상 권장되지는 않지만 아래와 같이 설정을 진행하는 방법이 있습니다.

1) sheel 변수를 통한 임시 처리
ssh key를 체크 하지 않는 옵션을 임시 변수로 등록합니다.
export ANSIBLE_HOST_KEY_CHECKING=False

사용이 완료되었다면 변수를 제거합니다.
unset ANSIBLE_HOST_KEY_CHECKING

2) 영구적인 설정 (보안 상 권장하진 않습니다.)
아래와 같이 설정 후 저장하면 설정이 적용됩니다.
vi /etc/ansible/ansible.cfg
[defaults]
host_key_checking = False

호스트 설정이 진행 됐는지 확인 해봅니다. -i 옵션은 /ansible/host 파일이 이외에 host 파일을 지정 할 수 있어 서버 리스트의 관리가 편합니다.

ansible-inventory -i /ansible/host --list -y
all:
  children:
    ubuntu_server:
      hosts:
        ubuntu1:
          ansible_host: 10.7.2.101
        ubuntu2:
          ansible_host: 10.7.2.102

앤서블을 통해 uptime의 명령어 사용이 가능한지 확인 합니다.

ansible -i /ansible/host all -a "uptime" -u root -k
SSH password: 
ubuntu2 | CHANGED | rc=0 >>
 15:16:34 up  3:37,  1 user,  load average: 0.08, 0.02, 0.01
ubuntu1 | CHANGED | rc=0 >>
 15:16:34 up  3:37,  1 user,  load average: 0.00, 0.00, 0.00

여기까지만 보면 앤서블의 작동 구조는 이렇게 볼 수 있습니다.

컨트롤러 서버 → 엔서블(ssh) → 클라이언트 서버 작업 

-i /ansible/host all : 명령어 사용시 host에 지정된 all(전체), ubuntu_server(그룹), ubuntu1, ubuntu2 명령어 사용을 지정
-a "uptime" : 리눅스의 업타임, 부하 확인 명령어 uptime
-u root : 유저 또는 root를 지정 가능
-k : 패스워드를 입력

ansible 플레이북 테스트

ansible만 봤을 때 스크립트로도 충분히 원하는 작업을 할 수 있지 않나? 라는 의문이 들 수 있지만 host(인벤토리)의 리스트에서 서버를 지정 후 명령을 실행하여 편리하게 자동화를 진행해주는 기능을 가진 플레이북이라는 기능이 존재 합니다. 아래의 내용은 ubuntu 서버에 apt를 통한 apm 설치 및 워드프레스 다운 및 압축 해제에 관해 내용이 정리 되어 있습니다.

※ 아래의 기능은 테스트를 위해 apm에 관련 된 중요한 작업이 모두 생략 되어 있는 형태입니다. 실제 서버에 운영 목적으로 사용하지 않는 것을 권장 드립니다.

vi /ansible/apm.yml
- name: 서버 APM 설치 yaml
  gather_facts: yes
  hosts: ubuntu_server

  tasks:
    - name: APT 업데이트 및 APM 설치 진행
      apt:
        update_cache: yes
        force_apt_get: yes
        name: apache2, php, php-mysql, mariadb-client, mariadb-server
        state: present

    - name: 워드프레스 다운로드
      get_url:
        url: https://ko.wordpress.org/wordpress-6.3.2-ko_KR.tar.gz
        dest: /var/www/html/wordpress-6.3.2-ko_KR.tar.gz
      when: not (ansible_facts['filestat']['/var/www/html/wordpress-6.3.2-ko_KR.tar.gz'].exists | default(false))

    - name: 워드프레스 디렉토리 생성
      file:
        path: /var/www/html/wordpress
        state: directory

    - name: 워드프레스 압축 해제
      unarchive:
        src: /var/www/html/wordpress-6.3.2-ko_KR.tar.gz
        dest: /var/www/html/wordpress
        remote_src: yes
        extra_opts: "--strip-components=1"

플래이북의 사용 방법은 ansible 명령어와 차이는 없습니다. 호스트를 지정하고 명령어를 지정할 플레이북을 설정한 뒤 비밀번호를 기입하여 처리합니다.

ansible-playbook -i /ansible/ubuntu_host /ansible/apm.yml -k
SSH password: 

PLAY [서버 APM 설치 yaml] *************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************
ok: [ubuntu1]
ok: [ubuntu2]

TASK [APT 업데이트 및 APM 설치 진행] **************************************************************************************************
ok: [ubuntu2]
ok: [ubuntu1]

TASK [워드프레스 다운로드] ************************************************************************************************************
ok: [ubuntu2]
ok: [ubuntu1]

TASK [워드프레스 디렉토리 생성] *******************************************************************************************************
ok: [ubuntu1]
ok: [ubuntu2]

TASK [워드프레스 압축 해제] ***********************************************************************************************************
ok: [ubuntu1]
ok: [ubuntu2]

PLAY RECAP ****************************************************************************************************************************
ubuntu1                    : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ubuntu2                    : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

이 단계에서 정상적으로 진행 된다면 http://ip/wordpress 로 접속 시 설치 화면을 볼 수 있습니다. 여기까지만 보면 앤서블 플레이북의 작동 구조는 이렇게 볼수 있습니다.

# 플레이북의 시작 점
- name: 서버 APM 설치 yaml 
  gather_facts: yes
# /ansible/host에 등록 된 그룹 ubuntu_server에 속한 서버들은 아래와 같은 내용으로 설치가 진행되며 ubuntu1 등으로 개별 지정 가능
  hosts: ubuntu_server 

# 클라이언트 서버에 명령어를 사용
  tasks:
    - name: APT 업데이트 및 APM 설치 진행
# apt 모듈이 사용
      apt:
# apt update
        update_cache: yes
        force_apt_get: yes
# apt install
        name: apache2, php, php-mysql, mariadb-client, mariadb-server
# 멱등성 설정으로 서버에 프로그램이 설치되어 있는 경우 설치를 진행하지 않도록 하는 설정
        state: present

    - name: 워드프레스 다운로드
# url을 통해 파일을 다운로드하며 파일이 존재할 경우 다운로드는 시도되지 않는다.
      get_url:
        url: https://ko.wordpress.org/wordpress-6.3.2-ko_KR.tar.gz
        dest: /var/www/html/wordpress-6.3.2-ko_KR.tar.gz
      when: not (ansible_facts['filestat']['/var/www/html/wordpress-6.3.2-ko_KR.tar.gz'].exists | default(false))

    - name: 워드프레스 디렉토리 생성
      file:
        path: /var/www/html/wordpress
        state: directory

    - name: 워드프레스 압축 해제
# wordpress 디렉토리에 압축이 해제된다.
      unarchive:
        src: /var/www/html/wordpress-6.3.2-ko_KR.tar.gz
        dest: /var/www/html/wordpress
        remote_src: yes
        extra_opts: "--strip-components=1"

# 정리하면 hosts로 설치 할 서버가 지정되고 tasks를 통해 apm의 설치, 워드프레스의 다운로드 및 압축 해제가 진행된다.

위에서는 간단한 설치를 위주로 진행 했지만 쉘 스크립트를 통해 그 안에 있는 내용으로 작업을 진행할 수 있습니다. 아래의 스크립트는 shell에 접근 시 내용을 보여주는 /etc/motd를 수정합니다.

vi /ansible/test_motd.sh  
#!/bin/bash
echo "######################################################################" > /etc/motd
echo -e "\nHello User\n" >> /etc/motd      
echo "######################################################################" >> /etc/motd

이 yml 파일은 test_motd.sh 스크립트를 ubuntu_server 그룹의 서버 /usr/local/src/ 디렉토리에 보낸 뒤 스크립트를 실행 시킵니다. 작동시키면 해당 서버로 로그인 할때 motd에 적힌 내용을 볼 수 있습니다.

vi /ansible/script.yml
- name: 쉘 스크립트 원격 실행
  hosts: motd_server
  
  tasks:
    - name: 쉘 스크립트를 원격 서버로 전송합니다.
      copy:
        src: /ansible/test_motd.sh
        dest: /usr/local/src/test_motd.sh
        mode: +x

    - name: 쉘 스크립트를 실행 합니다.
      shell: /usr/local/src/test_motd.sh

기존의 host와는 다른 파일을 생성 했습니다. 이렇게 한 이유는 앤서블은 특정 디렉토리에 구애받지 않고 동작하는 것을 보여드리기 위함입니다.

vi /ansible/motd_host 
[motd_server] 
motd1 ansible_host=10.7.2.111  
motd2 ansible_host=10.7.2.112

명령어를 사용하면 초기에 만든 /ansible/host에 영향을 받지않고 작업이 진행 됩니다.

ansible-playbook -i /ansible/motd_host /ansible/script.yml  -k

ansible 응용 방법

지금까지 앤서블, 플레이북 사용시 패스워드를 입력하는 -k 옵션을 사용하여 예시를 보여 드렸습니다.  앤서블이 멱등성이라는 뛰어난 기능을 제공 하지만 여러 기능을 다뤄야하는 엔지니어 특성상 보안적인 부분과 만일에 대비 해야 하는 점이 있기 때문입니다.  하지만 좀 더 편하게 사용을 해보려는 분이 있을 수도 있어 내용을 정리해보려 합니다.

ssh-keygen을 통해 key를 생성합니다. Enter을 몇번 누르면 생성이 진행 됩니다.

ssh-keygen

키를 복사하는 부분에 있어 시간이 지연되는 건 패스워드를 기입해야 한다는 점입니다. 서버가 2 ~ 3 대라면 모르지만 수십대라면 시간도 걸리고 번거롭겠죠. 

ssh-copy-id root@IP
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.7.2.101's password:

앤서블의 플레이북은 이런 고민을 쉽게 처리해줄 수 있습니다. 아래의 내용은 id_rsa.pub 파일의 key 값을 클라이언트 서버의 authorized_keys에 복사해 주는 플레이북입니다. 

vi /ansible/ssh_copy.yml
- name: ssh key 복사 진행
  hosts: ubuntu_server

  tasks:
    - name: 원본 키 값 삭제
      command: rm /root/.ssh/authorized_keys

    - name: ssh key 파일 복사 및 수정 진행
      copy:
        src: /root/.ssh/id_rsa.pub
        dest: /root/.ssh/authorized_keys
        mode: '0600'

    #- name: 작업 완료 가정 원본 키 삭제
      #command: rm /root/.ssh/authorized_keys

    #- name: authorized_keys 빈 파일 생성
      #command: touch rm /root/.ssh/authorized_keys

    #- name: authorized_keys 권한 설정 
      #command: chmod 0600 rm /root/.ssh/authorized_keys

플레이북을 실행하면 이후부터는 -k 옵션을 사용하지 않고 사용이 가능합니다. 

ansible-playbook -i /ansible/host /ansible/ssh_copy.yml  -k

플레이북에 주석 처리한 부분은 다른 곳에서 설정 후 실행 시키면 모든 작업이 완료된 후 key값이 초기화 될 것 입니다.

ansible을 어떻게 사용할 것인가

지금 소개해드린 내용은 앤서블의 일부분 만을 기재한 내용으로써 어느 정도의 시간을 들여 기술을 쌓아야만 효율적으로 이용이 가능 할 것으로 생각 됩니다. 현재로는 아래와 같은 방법으로 응용할 수 있을 것으로 생각됩니다.

  • 서비스 상품화 환경 테스트
    1개의 서비스를 상품화 하기 위해서는 셋팅을 반복하고 변경하면서 에러 등의 변수를 하나씩 없애야하기에 수많은 테스트와 시간이 필요합니다. 앤서블의 플레이북 기능과 쉘 스크립트를 잘 활용하면 구간 별로 어느 설정이 문제였는지 필요한 점이 무엇 인지를 조금 더 빠르게 판단을 지을 수 있을 것으로 보입니다.
  • 서버 셋팅
    다양한 환경의 서버를 다루고 있어 플레이북을 잘 작성해두면 셋팅에 소요되는 시간을 줄일 수 있을 것으로 예상 됩니다. yaml 파일의 경우 다른 곳에서도 사용 되기에 사용 방법을 알아두면 도움이 될 것 같습니다.

idchowto.com

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x