맘가는 대로

앤서블 인벤토리 설정 본문

자동화/앤서블

앤서블 인벤토리 설정

ALIVEisANSWER 2019. 6. 9. 16:53

앤서블 실습 환경 구성을 마쳤으니 실제로 앤서블을 사용해볼 차례다.

 

앤서블을 사용하기 위해서는 앤서블을 통해 조작할 서버들에 대한 정보가 필요하다.

 

그러기 위해 서버들에 대한 접속 정보를 모은 인벤토리(inventory) 파일이 필요하다.

 

 

인벤토리 파일은 두 가지의 설정 방법이 있으며 정적 파일과 동적 파일로 나뉜다.

 

정적 파일은 다시 ini 와 yaml 양식으로 나뉘어지며,

 

동적 파일은 거의 모든 종류의 실행 파일이 대상이며 단지 출력 결과가 JSON 형태이면 된다.

 

 

정적 파일의 경우 앤서블 사용자가 직접 서버의 정보를 파일에 기재하는 방법이며, 소수의 서버들을 대상으로 할 때 유용하다.

 

동적 파일의 경우 클라우드를 사용할 때 접속 정보를 이용해 사용하고 있는 서버의 정보를 가져오는 경우등에 해당하며, 접속 정보만을 이용해 대량의 서버의 정보를 가져올 때 유용하다. 혹은 DB 등의 정보 집합체에서 원하는 서버를 가져오는 스크립트를 활용할 수 도 있다.

 

둘을 비교하자면, 정적 파일은 작성과 정보를 보는데에 편리하지만 서버의 대수가 많아질 경우 불편해질 수 있다. 동적 파일은 서버의 정보를 가져오는데에 편리하지만 해당 인벤토리 파일만으로는 서버의 정보를 바로 알 수 없다.

 

따라서 두 인벤토리 파일은 각각 장단점이 있는 만큼 자신의 목적에 맞게 잘 활용해야 한다. 다만, 두 방법 모두 보완하는 방법들이 있기 때문에 크게 고민할 필요는 없다.

 

 

자, 이제 직접 실습 환경을 구성하고 인벤토리 파일을 작성해보자.

 

 

인벤토리 파일

인벤토리 파일 작성에 앞서 베이그런트를 통한 실습 환경 구성에는 조금 편리한 구성이 제공되기 때문에 편리한 부분이 있다.

 

일반적으로 설정 관리(CM: Config Management) 도구들은 서버들의 접근을 인증서 파일을 이용해서 한다. 앤서블의 경우 해당 파일이 SSH 키파일이 된다.

 

베이그런트를 사용할 때에는 Vagrantfile 이 있는 디렉토리의 점디렉토리로 .vagrant 디렉토리 생성되며, 해당 디렉토리 이하에 생성된 VM 별로 키파일을 보관하게 된다. 베이그런트를 통한 앤서블 실습시 사용할 키는 이 .vagrant 디렉토리를 이용할 것이다.

 

인벤토리 파일 형식은 YAML 형식으로 할 것이다.

 

물론, INI 형식도 많이 사용되지만, INI 는 형태적으로 늘어나는 변수들에 대해 계속 문장이 길어지는 형태로 작성을 해야하기 때문에 불편한 면도 있고, 중요한 것은 다른 곳에서도 정말 많이 소개를 하고 있기 때문에 YAML 형태로 할 것이다.

 

따라서 최종적으로 KEY 파일은 vagrant 가 모아놓은 파일을 사용할 것이며, 인벤토리 파일 형태는 YAML 형태로 할 것이다.

 

우선, 이를 위해 이전에 만들어 놓았던 Vagrantfile 을 아래와 같이 변경한다.

베이그런트는 초기 VM 생성과정에서 자동적으로 Vagrantfile 이 있는 디렉토리를 VM 의 /vagrant 디렉토리에 있는 파일들을 복사한다. 다만, 점파일(디렉토리)들은 제외되어 복사되기 때문에 키파일이 있는 디렉토리가 복사될 수 있게끔 synced_folder 설정을 통해 복사를 한차례 더 진행한다.

 

이제 베이그런트를 통해 실습 환경을 구성하고 직접 인벤토리 파일을 만들도록 해보자.

 

인벤토리 파일을 YAML 형식으로 구성할 때에는 구성 형식을 아래와 같이 해야 한다.

 

all:
  hosts:
    ...
  children:
    ...:
      hosts:
        ...
      children:
        ...:

all 은 최초에 반드시 들어가야 한다.

 

다음 hosts 와 children 구획이 들어가야 한다. hosts 구획에서는 계속 작성을 해나가면 되며, children 구획에서는 다시 all 이 사용된 것처럼 hosts 와 children 구획을 써나가야 한다. 다만, children 구획은 반드시 필요하지 않지만, hosts 구획에서 최소 1 개의 서버가 있어야 한다.

 

현재 실습 환경은 ansible 노드와 원격 서버 1 대로 하고 있다. 따라서 all 의 hosts 는 ansible 로, children 구획에서 test 구획을 구성하여 원격 서버 정보를 기록할 것이다.

 

ansible 서버부터 정보를 작성해보자. 파일 이름은 마음대로 해도 되지만, 역할과 형태를 바로 알아볼 수 있도록 hosts.yaml 로 할 것이다.

 

기본을 작성하면 아래와 같이 된다.

 

인벤토리 파일의 yaml 형태를 충족하지만 이렇게 할 경우 DNS 를 통해 ansible 에 대한 서버 IP 를 조회할 것이고, SSH 를 통한 접속을 시도할 것이다.

 

가볍게 테스트를 해보기 위해 아래의 명령어를 입력해보자.

 

ansible -i hosts.yaml -m ping all

-i 옵션을 통해 인벤토리 파일을 지정해주고 -m 옵션을 통해 모듈을 지정해준다. all 은 인벤토리에서 all 로 포함된 모든 서버들에 대해 작업을 진행하라는 의미이다. 인벤토리에서 all 이 반드시 포함되는 이유가 어느정도 이해되는가?

 

ping 모듈은 ICMP 를 이용한 네트워크 접근을 시도하는 것이 아닌 접속과 모듈의 실행 가능 여부를 모두 확인할 수 있는 모듈이다.

 

다만, 아래의 오류가 발생한다.

 

SSH 접속을 하게 될 경우 앤서블은 보통 사용자 계정을 기준으로 하고 있기 때문에 베이그런트를 사용할 경우 vagrant 계정으로 시도하게 될 것이다. 문제는 아직 키파일 정보가 없다는 것이다.

 

더 중요한 문제는 앤서블을 실행중인 ansble 서버에서 ansible 서버에 대해 명령을 내리는 형태가 되는데, 네트워크 통신은 물론, SSH 접속까지 하기 때문에 어느 정도 오버헤드가 있는 형태가 되며, 설정을 함에 있어서도 불편한 점이 생긴다.

 

따라서 접속 형태를 로컬로 바꿔준다. 정말 깔끔하게 해결된다.

 

 

ansible 서버에 대한 정보를 주기 위해 ansible 뒤에 쌍점을 넣은 뒤, 아래에 ansible_connection 정보로 로컬호스트임을 알려주었다. 그러면 SSH 접속을 하지 않고 바로 로컬호스트에서 모듈을 실행하기 때문에 네트워크 관련 오버헤드를 없애는 것은 물론, 반응 속도도 약간 빠르다.

 

이제 원격 서버를 넣어보자.

 

구성 원리는 같으니 빠르게 아래와 같이 작성할 수 있다.

 

다만, 앤서블 서버에서 node-1 에 대한 정보는 전무하다. 호스트 파일에도 별도로 정보를 주지 않았으니, IP 정보도 알 수 없다. 앤서블을 통해 IP 정보를 바로 얻는 것은 물론, 키파일도 알 수 있게 하자.

 

ansible_host 항목을 통해 IP 정보와 ansible_ssh_private_key_file 을 통해 키파일 정보를 줄 수 있다.

 

다시 테스트를 해보자.

 

키파일의 모드 속성이 적합하지 않기 때문에 거부당했다. 400 모드로 수정해주자.

 

이제서야 아무런 문제없이 작동을 하였다.

 

인벤토리 파일의 최종 형태는 아래와 같다.

 

all:
  hosts:
    ansible:
      ansible_connection: local
  children:
    test:
      hosts:
        node-1:
          ansible_host: 10.10.10.10
          ansible_ssh_private_key_file: /vagrant/.vagrant/machines/node-1/virtualbox/private_key

 

다만, 지금이야 수동으로 바꾸어줬다지만 매번 베이그런트로 VM 을 만들때마다 할 수는 없는 노릇이다. 따라서 이 과정도 자동화를 해야한다.

 

가능하면 베이그런트가 동작할 때 해주어야하기 때문에 Vagrantfile 에서 할 수 있는 것으로 하면 좋다. 확인해보니 베이그런트에서 디렉토리 동기화를 할 때에는 별도 파일만 해주는 기능이 없으니 프로비저닝에서 처리할 수 있도록 했다.

 

Vagrantfile 의 형태를 종합하자면 아래와 같을 것이다.

 

$NODE_COUNT=1

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.provider "virtualbox" do |v|
    v.cpus = 1
    v.memory = 256
  end
  config.vm.provision "shell", inline: "
    sudo timedatectl set-timezone Asia/Seoul
    sudo systemctl restart rsyslog
    sudo yum install -y vim
  "

  (1..$NODE_COUNT).each do |i|
    config.vm.define "node-#{i}" do |n|
      n.vm.hostname = "node-#{i}"
      n.vm.network "private_network", ip: "10.10.10.#{9 + i}"
    end
  end

  config.vm.define "ansible" do |a|
    a.vm.hostname = "ansible"
    a.vm.network "private_network", ip: "10.10.10.100"
    a.vm.synced_folder "./.vagrant", "/vagrant/.vagrant", type: "rsync"
    a.vm.provision "shell", inline: "
      sudo find /vagrant -name 'private_key' -exec chmod 400 {} \;
      sudo yum install -y ansible
    "
  end

end

마치며

시작이 반이라고 했던가. 실제 중요 작업을 하기전부터 진을 빼는 듯 하다. 다만, 인벤토리는 앤서블을 구성하는 중요한 요소로서 인벤토리 파일을 잘 다루는 것이 중요하다고 할 수 있다.

 

대부분 자동적으로 구성될 수 있게끔 할 수 있게 됐지만, 인벤토리 파일을 수동적으로 작성한 것이 있고, 실습 환경중 다수의 원격 서버에 대한 인벤토리 파일 구성을 할 수 있는 방법을 마련하지 않은 문제점이 있다.

 

동적 인벤토리 파일을 구성하는 것이 편하지만, 대부분의 동적 인벤토리 구성은 Vagrant 의 ssh-config 명령어에 의존하고 있으며, 해당 명령어는 VM 들이 전부 정상적으로 올라와야 정보를 주는 것이 있고, 제일 중요한 점은 현재 구성한 환경과 같이 VM 내부에서 앤서블을 작동시키는 것을 가정한 것이 아닌 호스트 서버에서 앤서블을 사용하는 것을 가정하고 인벤토리를 구성하기 때문에 다른 방법을 사용해야 한다.

 

다만, 앤서블 서버에서 따로 다른 서버들의 정보를 얻어올 수도 없다. 그래서 Vagrantfile 에서 VM 이 생길 때마다 파일에 정보를 출력하고 해당 정보들을 파일로 모아 앤서블 서버에 파일을 동기화하는 방법을 사용할 것이다.

 

이는 이후의 글에서 다시 탐구하도록 할 것이다.

출처

 

Working with Inventory — Ansible Documentation

Working with Inventory Ansible works against multiple systems in your infrastructure at the same time. It does this by selecting portions of systems listed in Ansible’s inventory, which defaults to being saved in the location /etc/ansible/hosts. You can sp

docs.ansible.com

 

'자동화 > 앤서블' 카테고리의 다른 글

Ansible 을 통해 파일 작성하기  (0) 2019.11.03
Ansible 로 LAMP 구성하기  (0) 2019.09.29
앤서블 실습 환경 구성  (0) 2019.06.08
앤서블의 구조와 작동 방식  (0) 2019.06.02
앤서블(Ansible)에 대해  (0) 2019.06.02
Comments