나의 삽질 저장소!

Ansible 시작하기! - ansible 이해하기 3편

by softPine

이전에 설치 문서를 읽고 Control node에 ansible을 정상적으로 설치가 되었다면, 이번에는 ansible의 동작에 대한 작동 방식을 이해하면서 기본적인 ansible 사용을 숙지하려고 한다. 이번 포스트에서 하려고 하는 것은 다음과 같다.

  • inventory에서 실행할 시스템 선택
  • 실행한 머신에 ssh 통신을 하여 연결
  • 하나 이상의 모듈을 원격 시스템에 복사하고 실행

ansible을 사용하여 좀 더 많은 기능등을 사용할 수 있지만 그 전에 ansbie에 대한 일반적인 사례를 이해해야 한다. 이번 포스트에서는 간단한 inventory 및 ad hoc 커맨드[각주:1]를 작성해 본다.

 

Inventory에서 시스템 선택

ansible은 inventory에서 관리하려는 시스템에 대한 정보를 읽는다. ad hoc 명령으로 ip 주소를 직접 전달할 수 있지만, ansible의 유연성과 반복성을 활용하려면 inventory가 필요하다.

 

기본 Inventory 생성하기

초기 inventory의 경로는 /etc/ansible/hosts 에 있다. 이 파일을 수정하거나 생성하여 관리하려는 원격 시스템을 추가한다. ip 또는 FQDN을 사용하여 나열하면 된다.

192.0.2.50
aserver.example.org
bserver.example.org

 

Inventory 기초

inventory는 IP 및 FQDN보다 훨씬 더 많은 것들을 저장할 수 있다. 별칭을 만들거나, 호스트 변수가 있는 단일 호스트에 대한 변수 값을 설정하거나, 그룹 변수가 있는 여러 호스트에 대한 변수 값을 설정할 수 있다.

 

원격 머신으로 연결하기

ansible은 ssh 프로토콜을 사용하여 원격 시스템과 통신한다. openssh를 기본 프로토콜로 사용하며 ssh와 마찬가지로 현재 사용자 이름을 사용하여 원격 시스템에 연결한다.

 

ssh 연결 확인하기

ssh를 사용하여 동일한 사용자 이름을 사용하여 inventory의 모든 노드에 연결할 수 있는지 확인한다. 필요한 경우 해당 시스템의 authorized_keys 파일에 ssh 공개 키를 추가한다.

나는 먼저 Amazon Linux 2를 사용하기에 Managed Node 역시 Amazon Linux 2다. 기본적으로 Amazon Linux 의 경우 pem key를 기반으로 접근을 해야 하기 때문에 미리 pem key로 접근할 수 있는 작업을 해놔야 한다. root 유저로 진행하지만 실제 ansible 유저는 ec2-user로 사용한다.

#--- Control node(ec2-user)
ssh-keygen

control node에 ec2-user로 접근하여 위 명령어로 key를 생성을 한 후 나머지 managed node에 접근하여 생성한 키의 public 키를 각각 managed node의 ec2-user의 $HOME/.ssh/authorized_keys 파일에 넣어준다. 이후에 control node에서 ec2-user의 id_rsa private 키 파일을 root 유저로 복사해온다.

 

ssh 연결 기초

다음과 같이 여러 방법으로 원격 사용자에 대한 이름을 재정의할 수 있다.

  • 명령줄에 -u 플래그를 사용하여 매개 변수 전달
  • inventory 파일에서 사용자 정보 설정
  • 구성 파일(ansible.cfg)에서 사용자 정보 설정
  • 환경 변수 설정

각 사용자 정보 전달 방법의 우선 순위는 다음 link 를 확인하여 참조한다.

 

모듈 실행과 복사

ssh 연결이 되면 ansible은 playbook 또는 명령 실행을 위해 필요한 모듈을 원격으로 연결된 시스템에 복사한다.

 

첫번째 ansible 커맨드 실행하기

root 유저에서 ping 모듈을 사용하여 inventory의 모든 노드에 ping(실제 ansible 유저는 -u 옵션을 사용해 ec2-user로 진행한다).

ansible all -m ping -u ec2-user

inventory의 각 호스트에 대한 출력은 다음과 같다.

aserver.example.org | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

또한 모든 노드에 실시간 명령을 실행해본다.

ansible all -a "/bin/echo hello" -u ec2-user

각 호스트에 대한 출력은 비슷할 것이다.

aserver.example.org | CHANGED | rc=0 >>
hello

 

첫번째 playbook 실행

playbook은 task를 재사용 가능한 단위로 통합하는데 사용한다.

ansible은 따로 playbook을 저장하지 않으며, 사용자가 직접 저장하고 관리하는 yaml 문서일 뿐이다. 필요에 따라 실행할 수 있도록 ansible에 전달한다.

먼저 디렉터리를 하나 생성 후 그 하위에 첫번째 playbook인 mytask.yaml 파일을 생성한다.

---
- name: My task
  hosts: all
  tasks:
     - name: Leaving a mark
       command: "touch /tmp/ansible_was_here"

작성이 완료되었다면 다음 명령을 실행해 본다.

ansible-playbook -u ec2-user mytask.yaml

명령이 실행되면 출력은 다음과 같을 것이다.

PLAY [My task] **************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************
ok: [aserver.example.org]
ok: [aserver.example.org]
ok: [192.0.2.50]
fatal: [192.0.2.50]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 192.0.2.50 port 22: No route to host", "unreachable": true}

TASK [Leaving a mark] *******************************************************************************************************************
[WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is
insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
changed: [aserver.example.org]
changed: [bserver.example.org]

PLAY RECAP ******************************************************************************************************************************
aserver.example.org        : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
bserver.example.org        : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.0.2.50                 : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0

 

파일 전송 기초

ansible은 파일을 전송하는데 SFTP를 사용한다. 관리하려는 시스템 또는 장치가 SFTP를 지원하지 않는 경우 ansible config 파일에서 scp 모드로 전환할 수 있다. 파일은 임시 디렉토리에 저장되고 거기에서 실행된다.

또한 명령을 실행하기 위해 권한이 필요한 경우(sudo 등) 다음 플래그를 사용한다.

# as bruce
ansible all -m ping -u bruce
# as bruce, sudoing to root (sudo is default method)
ansible all -m ping -u bruce --become
# as bruce, sudoing to batman
ansible all -m ping -u bruce --become --become-user batman

권한 에스컬레이션에 대한 이해가 필요한 경우 다음 Link를 참조한다.

 

 

  1. 특별한 목적을 위해서 라는 뜻의 라틴어. ad hoc 커맨드라 함은 특정 목적을 가진 커맨드이다. [본문으로]

블로그의 정보

나의 삽질저장소

softPine

활동하기