본문 바로가기

* Twodragon

Ansible 101: 손쉬운 인프라 관리를 위한 앤서블 시작하기

안녕하세요. Twodragon 입니다.

가시다 님의 온라인 A101(Ansible 101 study) 강의에 대한 첫번째 주차 과제이며 손쉬운 인프라 관리를 위한 도전기 입니다!

 

Ansible이란 무엇이며 사용하는 목적은?

Ansible은 오픈 소스의 구성 관리, 배포, 오케스트레이션 도구입니다. 데브옵스(DevOps)와 자동화의 한 형태로, 서버 환경을 효과적으로 관리하고 구성하는 데 사용됩니다. Ansible은 에이전트를 필요로하지 않는 특징을 가지고 있어 설치 및 관리가 간편하며, YAML 언어를 사용하여 사용자 친화적인 구성이 가능합니다.

  1. 구성 관리(Configuration Management): Ansible은 서버 및 네트워크 장치의 구성을 코드로 정의하고, 변경 사항을 관리하여 일관된 상태를 유지합니다. 이를 통해 시스템 구성의 변경이 추적 가능하고, 문제 발생 시 이전 상태로 롤백이 가능합니다.
  2. 배포(Deployment): 소프트웨어나 애플리케이션의 배포를 자동화하여 빠르고 안정적인 배포를 가능케 합니다. 코드를 사용하여 서버에 소프트웨어를 설치하고 구성함으로써 일관된 환경을 유지할 수 있습니다.
  3. 오케스트레이션(Orchestration): 여러 서버나 서비스 간의 작업 흐름을 자동화하고 관리합니다. 복잡한 태스크의 순서를 조절하여 전체 시스템이 조화롭게 동작하도록 합니다.
  4. 자동화(Automation): 반복적이고 일상적인 작업들을 자동화하여 운영 효율성을 향상시킵니다. 이를 통해 개발자 및 운영팀은 보다 생산적으로 일할 수 있습니다.
  5. 클라우드 자원 관리(Cloud Resource Management): Ansible은 다양한 클라우드 서비스와 통합하여 가상 머신, 스토리지, 네트워크 등의 자원을 관리할 수 있습니다.

Ansible은 이러한 기능들을 통해 IT 인프라 및 소프트웨어 배포를 효율적으로 관리하고, 데브옵스 환경에서 자동화된 작업 흐름을 구성하는 데 사용됩니다.

 

Ansible 사용해야 하는 이유는?

  • 편한 사용: Ansible은 에이전트를 필요로 하지 않으며 YAML 언어를 사용하여 간편하게 구성할 수 있습니다.
  • Agentless 구조: 에이전트 없는 구조로 시스템에 추가 부담이 없으며 설치와 설정이 간편합니다.
  • 다양한 플랫폼 지원: Ansible은 다양한 운영 체제 및 클라우드 플랫폼에서 사용할 수 있어 효율적인 다중 환경 관리가 가능합니다.
  • 모듈화: Ansible은 모듈을 사용하여 특정 작업을 수행하므로 재사용성이 높고 유연한 구성이 가능합니다.

 

Ansible 구조 (Made by Nahidul Islam)

 

Ansible 기초 용어 정리

1) 제어 노드 (Control Node): 제어 노드는 Ansible 명령을 실행하는 주체로, 관리 노드에 명령을 전달합니다. Ansible 명령은 대체로 이 제어 노드를 통해 실행됩니다.

2) 관리 노드 (Managed Node): 관리 노드는 실제로 Ansible PlayBook에 정의된 작업들을 수행하는 노드입니다.

3) 인벤토리 (Inventory): 인벤토리는 관리 노드 및 PlayBook에서 사용될 변수를 정의한 파일입니다. 제어 노드와 관리 노드의 정보가 담겨 있습니다.

4) 모듈 (Modules): 모듈은 PlayBook 작성 시 작업(task)을 정의할 때 사용되는 요소로, 다양한 작업을 수행하는 Ansible의 기능입니다.

5) 플레이북 (Playbook): 플레이북은 관리 노드에서 수행할 작업들을 YAML 문법을 통해 정의한 파일입니다. 이를 통해 여러 작업들을 순차적으로 실행할 수 있습니다.

 

인벤토리 (Inventory) 설명

1) 관리 노드 설정:

IP 또는 호스트명을 이용하여 관리 노드를 설정할 수 있습니다. 인벤토리 파일을 생성하고 해당 파일을 검증하는 예시입니다.

# IP를 이용한 관리 노드 설정
cat <<EOT > inventory
10.10.1.11
10.10.1.12
10.10.1.13
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq
# 호스트명을 이용한 관리 노드 설정
cat <<EOT > inventory
tnode1
tnode2
tnode3
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq

 

Ansible 노드 간 통신확인

# 노드간 통신 확인
for i in {1..3}; do ping -c 1 tnode$i; done

 

 

2) 관리 노드 그룹 설정:

그룹을 생성하여 여러 관리 노드를 묶을 수 있습니다. 이를 통해 PlayBook에서 그룹명을 이용하여 여러 노드에 작업을 실행할 수 있습니다.

 

[webservers]
10.10.1.11
10.10.1.13

[db-servers]
10.10.1.12

 

 

중첩 그룹: 그룹을 중첩하여 묶을 수 있습니다. 이때, :children 접미사를 추가하여야 합니다.

[webservers]
web1.example.com
web2.example.com

[db-servers]
db01.example.com
db02.example.com

[datacenter:children]
webservers
dbservers

 

선언 간소화: 일련의 IP 주소나 호스트명을 간편하게 선언할 수 있습니다.

# 10.0.0.1~10.0.0.10 까지의 관리 노드 선언
10.0.0.[1:10]

# test1, test2, test3 라는 이름의 관리 노드 선언
test[1:3]

이러한 인벤토리 설정을 통해 Ansible은 효율적으로 관리 노드들을 인식하고 작업을 실행할 수 있습니다.

 

플레이북 ( Playbook ) 설명

*ansible.cfg 설정

ansible.cfg는 ansible 명령어 실행 시 특정 옵션값을 미리 설정해 놓는 파일입니다. 이 파일은 inventory, playbook 등의 설정을 담고 있습니다.

1) 플레이북 작성 && 구조 설명

# 제어 노드에 메세지를 출력하고, 관리노드에 메세지를 출력하는 Playbook

- hosts: all #어떤 host에 task를 전달할 것인가
  tasks: # 작업 정의
    - name: Print message # task 명 지정
      debug: # 어떤 module을 사용하는지 명시
        msg: Hello CloudNet@ Ansible Study # msg 내용 기입

  tasks: # 작업 정의
    - name: shell module # 작업명 정의
      shell: | # 어떤 module을 사용하는지 명시
        echo "Hello World2" # 관리 노드에 전달할 명령어

2) 플레이북 실행

#플레이북 문법 체크:
ansible-playbook --syntax-check first-playbook.yml
# 플레이북 실행하기: 
ansible-playbook first-playbook.yml

 

playbook restart-service.yml

---
- hosts: all
  tasks:
    - name: Restart sshd service
      ansible.builtin.service:
        name: sshd
        state: restarted

 

# (신규터미널) 모니터링 : 서비스 재시작 실행 여부 확인
ssh tnode1 tail -f /var/log/syslog

# 실행 전 check 옵션으로 플레이북의 실행 상태를 미리 점검 가능 : 출력 중 changed=1 확인
ansible-playbook --check restart-service.yml 


# 플레이북 실제 실행
ansible-playbook restart-service.yml
...

 

 

3. 변수 설명

변수 우선 순위

  • 추가변수 > 플레이 변수 > 호스트 변수 > 그룹 변수

1) 그룹 변수

그룹 변수는 인벤토리에 정의된 호스트 그룹에 적용되는 변수입니다. 아래는 간단한 인벤토리의 예시와 그룹 변수의 선언입니다.

#inventory
[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db

[all:vars]
user=ansible

[all:vars] 하위에 선언된 변수는 모든 관리 노드에 적용됩니다.

 

2) 호스트 변수

호스트 변수는 인벤토리에 정의된 각 호스트에 적용되는 변수입니다. 아래는 특정 그룹의 호스트에만 변수를 적용하는 예시입니다.

#inventory
[web]
tnode1
tnode2

[db]
tnode3 user=ansible1

[all:children]
web
db

[all:vars]
user=ansible

 

[db] 하위의 tnode3에만 변수가 적용됩니다.

 

3) 플레이 변수

플레이북 내에서 선언되는 변수는 해당 플레이에서만 적용됩니다. 아래는 플레이북의 예시와 플레이 변수의 활용입니다.

#playbook.yml

- hosts: all 
    vars:
        - message: test
  tasks: 
    - name: Print message 
      debug: 
        msg: "{{msg}}"
  tasks: 
        - name: shell module 
            shell: | 
                echo "{{msg}}"

 

hosts 하위 vars에 message라는 변수가 선언되어 있습니다.

 

4) 추가 변수

추가 변수는 명령어 실행 시 -e 옵션을 통해 전달되는 변수로, 우선 순위가 가장 높습니다.

ansible-playbook -e message=test test.yml

이렇게 -e를 통해 변수 값이 전달됩니다.

 

[도전과제1] Ansible 모듈을 활용하여 user 생성 및 삭제

도전과제1에서는 Ansible을 사용하여 사용자를 생성하고 삭제하는 간단한 작업을 수행하는 예제를 제시하겠습니다.

1. 사용자 생성 (user 생성 모듈 활용)

# create_user.yml

- hosts: all
  tasks:
    - name: Create a new user
      user:
        name: "{{ username }}"
        password: "{{ password | password_hash('sha512') }}"
        state: present

 

위의 플레이북은 create_user.yml이라는 이름으로 저장되어 있습니다. 이 플레이북은 user 모듈을 사용하여 사용자를 생성합니다. username과 password는 Ansible 실행 시 -e 옵션을 통해 전달되어야 합니다.

사용자 생성을 위해 다음과 같이 실행할 수 있습니다:

# create_user.yml

- hosts: all
  tasks:
    - name: Create a new user
      user:
        name: "{{ username }}"
        password: "{{ password | password_hash('sha512') }}"
        state: present

 

위의 플레이북은 create_user.yml이라는 이름으로 저장되어 있습니다. 이 플레이북은 user 모듈을 사용하여 사용자를 생성합니다. username는 Ansible 실행 시 -e 옵션을 통해 전달되어야 합니다.

사용자 생성을 위해 다음과 같이 실행할 수 있습니다:

ansible-playbook create_user.yml -e "username=newuser"

 

2. 사용자 삭제 (user 삭제 모듈 활용)

# delete_user.yml

- hosts: all
  tasks:
    - name: Delete an existing user
      user:
        name: "{{ username }}"
        state: absent

 

위의 플레이북은 delete_user.yml이라는 이름으로 저장되어 있습니다. 이 플레이북은 user 모듈을 사용하여 사용자를 삭제합니다. username은 Ansible 실행 시 -e 옵션을 통해 전달되어야 합니다.

사용자 삭제를 위해 다음과 같이 실행할 수 있습니다:

ansible-playbook delete_user.yml -e "username=newuser"

 

[도전과제2] Ansible 모듈을 활용하여 관리 노드의 uptime 시간 확인하기

도전과제2에서는 Ansible을 사용하여 관리 노드의 uptime 정보를 확인하는 간단한 작업을 수행하는 예제를 제시하겠습니다.

1. Uptime 확인 (command 모듈 활용)

# check_uptime.yml

- hosts: all
  tasks:
    - name: Get uptime information
      command: uptime
      register: uptime_output

    - name: Display uptime information
      debug:
        var: uptime_output.stdout_lines

위의 플레이북은 check_uptime.yml이라는 이름으로 저장되어 있습니다. 이 플레이북은 command 모듈을 사용하여 uptime 명령을 실행하고 결과를 uptime_output 변수에 저장합니다. 그런 다음 debug 모듈을 사용하여 uptime 정보를 출력합니다.

 

2. 플레이북 실행

ansible-playbook check_uptime.yml

이렇게하면 Ansible이 관리 노드에서 uptime 명령을 실행하고 결과를 출력합니다. stdout_lines에는 uptime 정보가 포함되어 있습니다.

이 예제는 Ansible을 사용하여 간단한 명령을 실행하고 결과를 수집하는 방법을 보여줍니다. 실제 환경에서는 더 많은 모듈과 옵션을 사용하여 시스템 모니터링 및 관리 작업을 수행할 수 있습니다.

 

[도전과제3] Ansible 모듈을 활용하여 관리 노드의 Kernel Version과 OS 종류 출력하기

도전과제3에서는 Ansible을 사용하여 관리 노드의 Kernel Version과 OS 종류를 확인하는 작업을 수행하는 예제를 제시하겠습니다.

1. Kernel Version과 OS 종류 확인 (ansible.builtin.setup 모듈 활용)

# check_kernel_os.yml

- hosts: all
  tasks:
    - name: Gather facts about the system
      ansible.builtin.setup:
        gather_subset:
          - distribution

    - name: Display Kernel Version and OS Type
      debug:
        msg: "{{ ansible_kernel }} {{ ansible_distribution }}"

위의 플레이북은 check_kernel_os.yml이라는 이름으로 저장되어 있습니다. 이 플레이북은 ansible.builtin.setup 모듈을 사용하여 시스템에 대한 다양한 정보를 수집하고, 그 결과에서 Kernel Version과 OS 종류를 출력합니다.

2. 플레이북 실행

ansible-playbook check_kernel_os.yml

 

이렇게하면 Ansible이 관리 노드에서 시스템 정보를 수집하고 Kernel Version과 OS 종류를 출력합니다.

이 예제에서는 Ansible의 ansible.builtin.setup 모듈을 사용하여 시스템 정보를 수집하는 방법을 보여주었습니다. Ansible은 다양한 시스템 정보를 수집할 수 있으며, 이를 통해 유연하게 관리 노드를 모니터링하고 관리할 수 있습니다.