이 글은 CloudNet@ 팀 gasida님의 스터디 A101 1기 내용 및 실습으로 작성된 글입니다.
What is Ansible?
Ansible은 클라우드 프로비저닝, 구성 관리, 애플리케이션 배포, 서비스 내 오케스트레이션 및 기타 여러 IT 요구 사항을 자동화하는 매우 간단한 IT 자동화 엔진이다. Ansible의 주요 강점은 단순성과 사용 용이성이며, Linux 클라이언트를 원격으로 구성하기 위해 SSH 프로토콜을 사용한다. (Window는 WinRM 프로토콜 사용) 프로토콜을 사용할 수 없는 경우에는 API를 사용하여 서버, 워크스테이션, 도커, 네트워크 장비 등에 Ansible을 사용할 수 있다.
Ansible은 푸시 기반이므로 각 실행 사이에 대상 서버의 상태를 유지하지 않고, 반대로 실행될 때마다 새로운 상태 검사를 수행하며 이를 스테이트리스(stateless)라고 한다. 그리고 Linux 및 Windows를 자동화하기 위해 Ansible은 관리형 노드에 연결하고 Ansible 모듈이라고 하는 작은 프로그램을 해당 노드에 푸시한다. 이러한 모듈을 실행하고(SSH를 통해 실행) 완료하면 제거한다.
이 모듈은 가능한 *멱등성을 가지도록 설계되었고 필요한 경우에만 시스템을 변경한다. Ansible은 에이전트가 없기 때문에 관리 노드에 애플리케이션이나 서비스를 설치하지 않고도 장치와 계속 통신할 수 있다.
Ansible을 구동하는 모듈 및 라이브러리는 Python을 기반으로 하며, YAML 포맷을 기반으로 플레이북을 실행시켜서 원하는 자동화를 구현하거나 *Ad hoc 모드로 모듈을 실행시켜 상태를 조회할 수 있다.
* 멱등성: 동일한 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질
* Ad-hoc: 임시적인 수행을 의미, ansible의 playbook을 작성하여 수행하는 것이 아니라 임시적이나 특별하게 어떤 작업을 수행하기 위해 사용할 수 있는 실행 방법
Ansible 구조 및 주요 용어
Ansible의 구성요소는 크게 3가지로 Inventory(대상), Playbook(무엇을), Module(어떻게)는 각각 어떠한 대상에 명령을 어떻게 수행하는지를 의미한다.
Inventory(인벤토리, 호스트 파일)
- 관리되는 노드의 목록
인벤토리는 제어할 대상 즉, 명령을 수행할 대상인 서버의 목록과 그룹을 작성하는 파일이다. 다양한 서버들을 리스트화하고 그룹명을 지정하여 그룹으로 묶을 수 있으며, 그룹마다 변수를 적용할 수도 있다. 그리고 연속된 서버들의 경우 10.10.10.[10:30]과 같이 명시할 수 있다. 모든 서버들은 all 그룹에 포함되어 두 개 이상의 그룹에 포함될 수 있다.
Module(모듈)
- Ansible 코드 실행 단위
모듈은 Task로 하나의 명령어를 구혈한 모듈을 의미한다. 예를 들어 파일을 Target 서버로 복사할 때는 copy, file 등의 모듈 등을 사용하고 패키지를 사용할 때는 apt를 사용하기도 한다. 작업으로 단일 모듈을 호출하거나, 플레이북에서 여러 다른 모듈을 호출 할 수도 있다. 모듈은 모듈 리스트에서 확인할 수 있다.
Playbook(플레이북)
- 반복해서 실행하고자 하는 작업을 실행 순서대로 정렬한 작업 리스트
플레이북은 Yaml 파일로 인벤토리에서 정의한 서버들이 해야할 작업에 대해 정의한다. 작업들은 인벤토리에서 정의한 그룹별로 일괄로 수행할 수 있고, 이때 현재 호스트에서 명령을 수행하거나 파일을 복사하기 위하여 현재 호스트에서 파일을 읽고 이를 대상 서버에 파일을 출력하는 등 다양한 서버를 플레이북을 통해 관리할 수 있다.
Control Node
- Ansible이 설치된 (종류 관계 없음) 모든 시스템
어떤 제어노드에서든 /usr/bin/ansible 이나 /usr/bin/ansible-playbook 을 호출함으로써 command와 playbook을 실행할 수 있다.
노트북, 공유 데스크탑, 서버는 모두 ansible을 실행할 수 있으며, 즉 python이 설치되어있다면 어떤 컴퓨터든 컨트롤 노드로 사용할 수 있다.
단, Window 시스템을 제어 노드로 사용할 수 없다.
Managed Nodes
- Ansible로 관리하는 네트워크 장치
관리되는 노드는 때로 호스트(Host)라고 하며, Managed Node에는 ansible이 설치되어있지 않다.
실습
이번 스터디는 Visual Studio Code에서 진행된다고 하여, Stack 생성 후 SSH 연결 완료
Python 설치 확인 및 ansible 설치 진행
ansible 설치 명령어
apt install software-properties-common -y
add-apt-repository --yes --update ppa:ansible/ansible
apt install ansible -y
ansible, python , jinja 버전 및 기본적인 ansible config를 확인한다.
# Ansible 접근을 위한 SSH 인증 구성
- SSH Key 파일 방식으로 구성
key 파일 생성 전에는 .ssh 디렉터리에는 파일이 없는 것으로 확인된다.
아래 명령어를 사용하여 key file 생성
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
Private와 Public Key 생성된 것을 확인할 수 있고, Private Key의 경우는 절대 네버 유출되면 안된다.
for문을 사용해서 각 node에 공개키를 복사하였다.
node 접속 테스트 시 아래와 같이 잘(?) 접근되는 것을 확인할 수 있다.
# Ansible 인벤토리 생성
- IP로 Inventory 생성
디렉터리 밑에 inventory 파일(IP)을 생성하고, 인벤토리 검증을 한다.
- Host명으로 Inventory 생성
디렉터리 밑에 inventory 파일(Host Name)을 생성하고, 인벤토리 검증을 한다.
# 실습을 위한 Inventory 구성
Web과 DB 서버로 Inventory를 구성한 후에 인벤토리 검증을 진행한다.
현재 프로젝트의 디렉터리 내에 있는 ansible.cfg 앤서블 환경 설정 파일 구성 시, -i 를 사용하지 않아도 해당 파일에 정의된 인벤토리의 호스트 정호를 볼 수 있다.
# Playbook 생성해보기
playbook 작성 후 ping 테스트를 진행하는데, 이 ping은 우리가 생각하는 icmp가 아닌 나의 Node가 정상인지 아닌지 확인하는 모듈이다.
암호를 물어보는 옵션 --ask-pass를 사용하여 db 노드 확인을 해보고, user를 지정(?) 하는 옵션 -u 도 사용하여 노드 확인을 해보았다.
그리고 shell 모듈을 사용하여 간단한 명령어로 node들의 uptime이나 파일 등을 확인해보았다.
# 첫 번째 Playbook 생성하기
yml 파일을 생성해준 뒤에 --syntax-check 옵션을 사용하여 자체 문법을 확인할 수 있다.
first-playbook.yml의 경우는 보다시피 error 없이 잘 확인되었는데, first-playbook-with-error.yml는 에러가 났다.
왜 에러가 났을까 했는데, 아무래도 yml 파일이라 구문(띄어쓰기 등)이 맞지 않아서 error가 난 것으로 확인하여 구문 수정후에 다시 체크하니 문법 이상 없는 것으로 확인하였다.
생성한 플레이북을 실행해보았더니, 아까 만들었던 문구들이 출력되고 결과로 녹색으로 ok가 잘 떴다.
그리고 서비스를 재시작하는 playbook 도 생성하여 테스트를 진행하였다.
tail 로 로그 파일을 걸어 놓고 playbook 실행하였더니, started, stopped 등의 기록을 볼 수 있었다.
# 그룹 변수
inventory 파일에 [all:vars] 섹션을 넣고 그 아래 user 변수와 값(정보)을 추가했다. all이라는 그룹에서 user 변수를 사용할 수 있도록 정의하는 것이다.
그리고 create-user.yml 라는 사용자를 생성하는 yml을 만들었으며, 인벤토리에서 선언한 user라는 변수를 겹중괄호 사이에 넣어주면 해당 변수를 플레이북에서 사용할 수 있다. 중괄호와 변수명 사이는 항상 한 칸씩 띄워야 한다. (안띄면 에러남)
---
- hosts: all
tasks:
- name: Create User {{ user }}
ansible.builtin.user:
name: "{{ user }}"
state: present
ansible-playbook 명령어로 실행하였고, 각 node에 ansible 이라는 계정이 생성되는 것을 확인할 수 있었다.
우측에는 watch 명령어로 passwd 파일을 확인했고, playbook 을 돌리니까 ansible 계정이 생성 되었다.
for문을 통해 node에서 /etc/passwd를 cat으로 확인해보았고, 아래 이미지에 나오듯 node마다 ansible 계정이 있는 것을 확인했다.
# 호스트 변수
inventory 파일에 DB부분에 계정 변수를 넣어주고 create-user1.yml이라는 파일을 생성했다.
그리고 한쪽 터미널에는 node3를 watch로 걸어서 계정 정보를 보고 있었고, yml 파일을 돌리니 ansible1이라는 user 계정이 생성됨을 확인할 수 있다.
그룹변수와 호스트 변수가 있을 때 호스트 변수를 우선순위로 하는 것을 볼 수 있다. (ansible1 이라는 계정이 생성됨)
[web]
tnode1
tnode2
[db]
tnode3 user=ansible1
[all:children]
web
db
[all:vars]
user=ansible
# 플레이 변수
yml 파일을 아래와 같이 새로 만들고 (host 아래 vars를 추가하고 그 아래 user 정보 기재), 다른 터미널에 동일하게 watch를 걸어 놓고 playbook을 실행했다. ansible2라는 계정이 생성되는 것을 확인할 수 있었다.
그리고 별도의 디렉터리를 만들고 그 안에 새로운 yml 파일을 만들어서 user3이라는 yml 파일을 만들고 playbook을 실행했다.
ansible3이라는 계정이 생성되는 것을 확인했고, 플레이 변수 > 호스트 변수 > 그룹 변수 순으로 우선순위를 갖는다는 것을 확인했다.
---
- hosts: all
vars:
user: ansible2
tasks:
- name: Create User {{ user }}
ansible.builtin.user:
name: "{{ user }}"
state: present
# 추가 변수
ansible-playbook 이라는 명령어를 사용할 때 옵션으로 -e user=ansible4 라는 값을 추가하고 보니, ansible4라는 계정이 생성된 것을 볼 수 있었는데,
종합적으로 봤을 때 변수 우선순위는 추가변수 > 플레이변수 > 호스트 변수 > 그룹 변수 순서라는 걸 알게 되었다.
# Ansible Vault
비밀번호나 API key 등 중요한 데이터들은 인벤토리에 변수나 일반 ansible playbook에 텍스트로 저장된다. ansible 파일에 접근할 수 있는 사용자는 모든 파일 내용을 볼 수 있다. 이는 보안상 위험도가 높아 ansible을 사용하는 모든 파일을 암호화하고 내용을 해독할 수 있는 기능이다.
ansible-vault create라는 명령어로 암호화 파일을 만들었고, cat 명령어를 사용해서 해당 파일을 열어보면 암호화가 되어있다.
ll 명령어로 파일의 권한을 보니 600으로 일반 유저는 접근할 수 없는 것으로 보인다.
그래서 ubuntu 계정으로 시도했더니 역시나 permission denied가 뜬다. (완전 싫은 에러)
아래와 같이 ansible-vault view mysecret.yml 명령어를 사용하고 Vault Password를 잘 넣어주면 아까 만들었던 user, password 정보를 볼 수 있다.
ansible-vault view mysecret.yml
Vault password: # 위에서 만든 Password 입력
user: ansible
password: **********
# Facts
Ansble이 관리 호스트에서 자동으로 검색한 변수이며, Fact에는 플레이, 조건문, 반복문이나 관리 호스트에서 수집한 값에 의존하는 명령문의 일반 변수처럼 사용가능한 호스트별 정보가 포홤되어 있다.
아래 yml파일을 생성하고, ansible-playbook 으로 facts.yml을 실행하면, 아래와 같이 해당 node(호스트)의 수많은 정보들을 볼 수 있다. (ex. OS버전, 정보, Interface, disk 정보 등등)
실제로 엄청난 양의 데이터를 보여주는데, 스크린 샷을 하는데 한계가 있어서 한 화면 정도만 가지고 왔다.
ansible은 진짜 배워두면 너무 유용하게 여러 곳에 사용할 수 있을 것 같다.
참고
https://docs.ansible.com/ansible/latest/dev_guide/overview_architecture.html
https://www.ansible.com/overview/how-ansible-works
https://docs.rockylinux.org/ko/books/learning_ansible/01-basic/
https://delightwook.tistory.com/59
https://velog.io/@hanblueblue/%EB%B2%88%EC%97%AD-Ansible
'CloudNetaStudy > [Study] Ansible' 카테고리의 다른 글
[4주차] 보안설정 / 모니터링 자동화 (0) | 2024.02.09 |
---|---|
[3주차] 시스템 구축 및 환경 설정 자동화 (0) | 2024.02.02 |
[2주차] Ansible 반복문과 조건문 (0) | 2024.01.20 |