[오픈소스] Ansible (앤써블) - Inventory (인벤터리)

2022. 12. 19. 11:59오픈소스(Open Source)

Infrastructure As Code

   - IT 시스템 Infrastructure를 사람이 아닌 소프트웨어를 이용하여 자동으로 배포하고 관리하는 것을 말한다.

 

$ Infrastructure As Code의 장점
   - 소스코드로 작성 된 소프트웨어를 사용하므로, 관리 품질 향상
   - 다수의 시스템을 병렬 처리로 인한 인프라 관리자의 작업 시간 감소
   - 작업 시간 감소로 인한 효율적 처리가 가능하여, 관리 비용이 절감
   - 소프트웨어에서 정의 된 작업만 수행하므로, 오류 발생률이 낮다

 

$ Infrastructure As Code 실현도구
   - 원시적인 형태의 실현 도구로는 Shell Script 또한 포함된다.
   - 전용도구 : Ansible(앤서블), Chef(셰프), Pupper(퍼펫)

 

Ansible 특징

$ Agent Less
   - 퍼펫, 셰프등의 도구의 경우 관리 대상 시스템에 Agent가 구성되어야 한다.
   - Ansible의 경우 Agent 구성이 필요 없으며 대상 시스템에 직접 접근하여 관리.

 

$ 멱등성
   - 멱등성이란 ? “어떠한 작업을 여러 번 실행하여도 결과는 항상 같아야 한다“
   - Ansible은 절차적 작업이 아닌 선언적 작업으로 진행 된다

    EX) 절차적 작업 : A Service 패키지를 설치 및 실행 한다.
    EX) 선언적 작업 : A Service가 설치되어있고, 실행중인 상태를 확인 후 작업을 수행 한다. 만약 최종결과에 부합하는 상태일 경우에는 해당 작업은 수행되지 않는다.


$ 재사용성 
   - Ansible은 플레이북 단위로 작업을 수행한다 ( EX: Apache 설치 플레이북 )
   - 플레이북은 롤 설정이 가능하며, 다른 플레이북에서 해당 롤을 가져와 사용이 가능하다
    EX) 여러 앤서블 커뮤니티에서 이러한 롤을 공유하고 있어, 효과적인 플레이북을 구현 할 수 있다

   ( 자신이 만든 롤만 사용가능한 것이 아닌, 다른 시스템에서 생성 된 롤을 가져와 사용이 가능하다. )

 

Ansible 구성요소

$ Ansible Software 
   - Ansible을 사용하기 위한 소프트웨어
   - Ansible은 상주 프로세스가 없으며, 명령줄에 의해 동작

 

$ 인벤터리 ( Inventory ) 
   - Ansible을 이용하여 조작 할 관리대상 서버의 목록을 정의하는 역할
   - 인벤터리는 여러대의 관리대상 서버를 그룹화하여 정의가 가능하다
   - 정적 구성과 동적 구성으로 구분된다.
※ WEB Server Group, DB Server Group과 같이 목적에 따른 호스트 구분을 인벤터리에서 정의한다
※ 정적 인벤터리 : 관리대상 서버의 수가 적고, 변동사항이 많지 않은경우 관리자가 직접 명시하여 정의
※ 동적 인벤터리 : 관리대상 서버의 수가 많고, 변동사항이 많은 경우 동적으로 인벤터리 정의

 

$ 모듈 ( Module ) 
   - 모듈은 앤서블에서 실행되는 하나의 명령어를 말 한다.
   - 모듈은 관리대상 서버의 상태를 파악 후 변경사항이 있을 경우에만 작업을 수행
   [ Module 사용예 ]
   EX) 패키지 설치, 사용자 및 그룹 관리, 파일 관련 작업, 네트워크 관리, 클라우드 서비스 작업 등
※ 모듈은 파이썬 언어로 만들어지며, 앤서블 기본내장 모듈을 베이스로 동작


$ 플레이북 ( Playbook )
   - 플레이북은 실제 스크립트 작업 과정을 YAML 형식으로 정의한다.
   - 플레이북내에는 실제 작업수행에 필요한 모듈이 정의 된다.
   EX) YAML은 데이터 구조를 사람이 읽기 쉬운형태로 정의하는 데이터 정의형식을 말한다.
   ( 앤서블에서는 YAML 데이터 형식을 최대한 간결하게 표현하여 작업을 수행 )

 

$ Ansible 구성요소 정리
   - 인베터리 : 앤서블을 이용하여 작업할 관리대상 서버를 정의 ( 어디에서 ? )
   - 모듈 : 앤서블에서 실행되는 개별 작업 정의 ( 무엇을 ? )
   - 플레이북 : 모듈 호출의 중심이 되는 YAML 형식으로 정의 된 스크립트 ( 어떻게 ? )

Ansible 설치

[ CentOS ]
# yum –y install centos-release-ansible-29
# yum –y install ansible

[ Ubuntu ]
# sudo apt install software-properties-common
# sudo apt-add-repository –yes –update ppa:ansible/ansible
# sudo apt install ansible

 

Ansible Inventory

$ Ansible Inventory Host 
   - Ansible을 이용하여 조작 할 관리대상 서버의 목록을 정의하는 역할
   - /etc/ansible/hosts 파일에 호스트를 명시

# vi /etc/ansible/hosts
127.0.0.1
192.168.1.150
192.168.1.200
   - 기존 내용 전부 삭제 후 새로 입력
   
# ansible all -m ping
The authenticity of host '192.168.1.150 (192.168.1.150)' can't be established.
ECDSA key fingerprint is SHA256:kUOBWBZ0q/X7g6u47P3av/bOZH73IPsh0ywE+DgvXgA.
ECDSA key fingerprint is MD5:cc:d7:91:68:53:f3:db:47:a7:fb:82:39:de:64:e6:86.
Are you sure you want to continue connecting (yes/no)?

127.0.0.1 | UNREACHABLE! => {
  "changed": false,
  "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
  "unreachable": true
}

192.168.1.150 | UNREACHABLE! => {
  "changed": false,
  "msg": "Failed to connect to the host via ssh: Host key verification failed.",
  "unreachable": true
}

# vi /etc/ansible/ansible.cfg
70 # uncomment this to disable SSH key host checking
71 host_key_checking = False
   - 위 설정을 통해 처음 접속을 진행하는 호스트의 키값을 확인하는 작업을 수행하지 않도록 설정 할 수 있다.
   - Ansible 작업 시 통상적으로 위와 같이 설정 후 작업하는 것이 일반적인 설정 방법
   
# ansible all -m ping -k
SSH password: “Password”
127.0.0.1 | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

192.168.1.150 | SUCCESS => {

  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}


$ Ansible Inventory ( SSH Key Gen Access )

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): “enter”
Enter passphrase (empty for no passphrase): “enter”
Enter same passphrase again: “enter”
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:LmJ15gMjGzd9i0709PQbhHOc5IH2GyVO+ByiMZemDMg root@Controller
The key's randomart image is:

# chmod 600 ~/.ssh/*
# scp ~/.ssh/id_rsa.pub root@192.168.1.150:~/.ssh/authorized_keys
# scp ~/.ssh/id_rsa.pub root@192.168.1.200:~/.ssh/authorized_keys

# ssh 192.168.1.150
Last login: Thu Feb 25 15:00:39 2021 from controller
# exit
logout
Connection to 192.168.1.150 closed.

# ssh 192.168.1.200
Last login: Thu Feb 25 14:49:57 2021 from controller
# exit
logout
Connection to 192.168.1.200 closed.

# ansible all -m ping
192.168.1.200 | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

192.168.1.150 | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

$ Ansible Inventory 변수

# useradd ansible
# passwd ansible

# useradd ansible
# passwd ansible

# vi /etc/ansible/hosts
Local        ansible_host=127.0.0.1      ansible_connection=local
Compute      ansible_host=192.168.1.150  ansible_user=ansible
Network      ansible_host=192.168.1.200  ansible_user=ansible
   - Compute, Network 서버에서 사용자 계정 생성 및 패스워드 지정
   - 호스트 관련 정보를 저장하기 위해 Host 변수를 생성, 해당 변수에 호스트 접근시 사용 할 값을 저장
   - Loopback 연결의 경우 연결형식을 Local로 지정, SSH 연결의 경우 SSH 접속 정보를 함께 지정
   
# ansible all -m ping -k
SSH password: “Password”
Local | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}
  
Compute | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

$ Ansible Inventory 그룹

# vi /etc/ansible/hosts
[localhost]
Local   ansible_host=127.0.0.1       ansible_connection=local

[WEB]
Compute ansible_host=192.168.1.150   ansible_user=ansible

[DB]
Network ansible_host=192.168.1.200   ansible_user=ansible
   - Host 파일에서는 특정 여러 개의 호스트를 그룹화 시켜 등록할 수 있다.
   - EX ) WEB Server , DB Server 그룹을 별도로 명시하여 등록
   
# ansible WEB -m ping -k
SSH password: “Password”
Compute | SUCCESS => {
  "changed": false,
  "ping": "pong"
}

# ansible DB -m ping -k
SSH password: “Password”
Network | SUCCESS => {
  "changed": false,
  "ping": "pong"
}

$ Ansible Inventory 파일 추가 및 범위 지정

# ls -ld ~/.ansible/
drwx------ 4 root root 27 2월 19 11:25 /root/.ansible/

# vi ~/.ansible/inventory
[localhost]
127.0.0.[1:9] ansible_connection=local

[server]
Compute    ansible_host=192.168.1.150   ansible_user=ansible
Network    ansible_host=192.168.1.200   ansible_user=ansible
   - “ /etc/ansible/host “ 내용 삭제 후 작업 진행
   - 범위 표현을 위해 “[(N):(M)]”를 사용, 127.0.0.1 ~ 127.0.0.9까지 표현
   - 만약 도메인 표현의 경우 EX) web-[a:d].myweb.co.kr 이러한 문자 범위 형식 사용도 가능하다
   - web-a.myweb.co.kr ~ web-d.myweb.co.kr 까지의 범위

$ Ansible Inventory 파일 추가 생성 및 범위 지정

# ansible all -m ping -k -i ~/.ansible/inventory
127.0.0.1 | SUCCESS ~ 127.0.0.9 | SUCCESS
SSH password: “Password”
Local | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

Compute | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

$ Ansible Inventory 그룹 변수

# vi ~/.ansible/inventory
[localhost]
127.0.0.[1:9] ansible_connection=local

[server]
Compute   ansible_host=192.168.1.150
Network   ansible_host=192.168.1.200

[server:vars]
ansible_connection=ssh
ansible_user=ansible
   - 특정 그룹별 변수 선언을 위해 vars 지시자를 사용
   - 지정된 그룹에 해당하는 호스트의 공통적인 변수값을 지정할 때 주로 사용
   
# ansible all -m ping -k -i ~/.ansible/inventory
127.0.0.1 | SUCCESS ~ 127.0.0.9 | SUCCESS
SSH password: “Password”
Local | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}

Compute | SUCCESS => {
  "ansible_facts": {
    "discovered_interpreter_python": "/usr/bin/python"
  },
  "changed": false,
  "ping": "pong"
}