Ansible 시스템 구성 관리
Mont Kim / February 2023 (1390 Words, 8 Minutes)
Ansible을 이용한 시스템 구성관리
Ansible
1. 개요
1.1 Ansible이란
Ansible은 Ansible Works에서 개발한 Infrastructure As Code 툴로, 코드기반 관리 툴의 일종입니다
IT인프라를 코드 기반으로 자동 설치 및 구축,관리, 프로비저닝 하는 프로세스입니다.
1.2 Ansible의 장점
Puppet | Chef | Salt | Ansible | |
---|---|---|---|---|
개발사 | Puppet Labs | Opscode | SaltStack | AnsibleWorks |
등장 | 2005년 8월 | 2009년 1월 | 2011년 3월 | 2012년 3월 |
개발언어 | Ruby | Ruby,Erlang | Python | Python |
도입고객 | Google,Ebay,Disney.. | Facebook,Ancestry.com.. | Linkedin,HP Cloud.. | Evernotes, Rackspace.. |
정보량 | 매우많음 | 매우많음 | 적음 | 보통 |
사용률 | 매우많음 | 매우많음 | 적음 | 매우많음 |
코드베이스 | Puppet Forge | Chef Supermarket | Salt-Formula(Git) | Ansible Galaxy |
Web UI | Puppet Enterprise | Chef Manage | SaltStack Enterprise | Ansible Tower |
정의파일 | 독자 DSL,내장 루비 | 독자DSL (루비베이스) | YAML 독자DSL (Python 베이스) | YAML |
agent설치 | 필요 | 필요 | 필요or불필요(선택) | 불필요 |
간편도 | 어려움 | 어려움 | 어려움 | 아주쉬움 |
Github Star | 6.5K | 6.8K | 12K | 52K |
Python 기반으로 이루어져있으며 yaml로 작성된 playbook 기반으로 관리되는 도구입니다.
- 구성관리가 yaml로 작성되므로 이해하기 쉽습니다. 즉 러닝커브가 낮습니다.
- 중앙의 Ansible 서버에서 하나의 코드로 다양한 클라이언트의 운영체제를 통합하여 관리 할수 있습니다. 예를 들면 하나의 코드로 centos나 ubuntu에서 동일하게 동작합니다.
- 클라이언트 시스템에 ansible을 위한 agent를 따로 설치하지 않아도 됩니다. 즉 클라이언트에 ssh로 접속만 가능하면 되므로 ansible을 위한 추가적인 설정에 대한 부담이 없습니다.
- 여러번 적용하더라도 모든 시스템에 동일한 결과(멱등성)를 만들어 낼 수 있습니다.
- 기본으로 제공되는 수많은 모듈을 통해 기능을 다양하게 확장 할 수 있습니다.
1.3 Ansible의 구성요소
Inventory
- 관리되는 노드의 목록
인벤토리는 Host라고도 부릅니다. /etc/ansible/hosts 디렉토리에 관리하는 노드에 대한 IP주소와 같은 정보를 지정 할 수 있습니다.
또한 인벤토리는 관리 노드를 구성하여 쉽게 확장 가능하도록 그룹을 만들고 중첩시킬 수 있습니다.
자세한정보는 https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory 를 확인하면 됩니다.
Modules
- Ansible 코드의 실행 단위
Module은 하나의 Task에서 어떠한 목적을 가지는 일련의 기능 집합입니다. 모듈의 대표적인 예로는 ping, shell, apt ,service, user, copy등 약 2000개의 모듈이 존재하며 Ansible 명령어 또는 ansible playbook에서 해당 모듈을 사용하여 별도로 코딩없이 task 작성이 가능합니다
Tasks
- Ansible의 작업 단위
Task는 Playbook을 작성할때 동작하는 작업의 최소단위입니다. 정형화 된 작업을 열거하여 이해하기 쉽게 작성할 수 있는 장점이 있습니다. 모듈은 Python이나 Bash로 기술되어 있습니다.
Playbooks
- 반복해서 실행하고자 해당 작업을 실행 순서대로 저장해 놓은 정렬된 작업 리스트
Playbook에는 Task 뿐만아니라 변수도 포함 할 수 있습니다. Playbook은 YAML로 작성되어있으며 문법이 간단해 러닝커브가 낮습니다.
자세한 정보는 https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#about-playbooks 를 확인하면 됩니다.
2. 데모
데모에서는 목적에 맞는 총 6개의 인스턴스를 구성하였습니다.
내부망, 외부망의 물리적인 구분을 위해 DMZ Zone을 지정하고, HAPROXY를 설치하는 인스턴스에 Ansible을 설치하여 내부, 외부 모두 통신이 가능합니다.
Management 노드에는 레포지토리인 Nexus, 레지스트리인 Harbor, 코드버젼관리툴인 Gitlab 등을 설치하는 공간입니다. 개발자들이 접속하여 코드를 push하게되면 pipeline을 통해 CI/CD가 시작되는 공간입니다.
K8S가 설치되어있는 노드들은 RKE2로 설치되어있으며, Rancher를 통해 추가적인 helm 프로그램들이 설치됩니다.
해당 데모에서는 RKE2 설치와 Rancher 배포, ArgoCD의 설치까지만 진행되어있으며
추가적인 어플리케이션의 설치는 Rancher를 통한 UI를 이용하여 설치를 진행할 수 있습니다.
2.0 Vagrant
위와같은 구조로 Ansible을 사용하는 데모를 하기위해 이미지 프로비저닝 도구로 Vagrant를 이용하였습니다.
Vagrant는 Hashicorp 사에서 개발한 이미지 프로비저닝 도구로 Ansible을 테스트하기 굉장히 쉬운 환경을 구축해줍니다.
Box라는 이미지 프로비저닝 파일을 사용하여 이미지를 프로비저닝하며, 코드 몇줄만 선언하면 원하는 상태의 이미지를 프로비저닝할 수 있습니다.
2.1 Ansible 설치 (Vagrant 사용 X)
작업환경은 VM상 프로비저닝 가능한 Vagrant를 이용해 쉽게 구축이 가능합니다.
Vagrant 프로비저닝없이 따로 구축이 되어있는 환경에 ansible을 설치하고싶다면 위와 같은 과정을 따르면 됩니다.
apt install ansible -y
명령어를 수행하여 ansible server로 쓸 메인 서버를 설정해줍니다.
각 파일에 구성은 다음과 같습니다.
bash_ssh_conf_4_Ubuntu.sh
#! /usr/bin/env bash
now=$(date +"%m_%d_%Y")
cp /etc/ssh/sshd_config /etc/ssh/sshd_config_$now.backup
sed -i -e 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
systemctl restart sshd
add_ssh_auth.sh
#! /usr/bin/env bash
#ssh key generatge
sshpass -p vagrant ssh -T -o StrictHostKeyChecking=no vagrant@192.168.32.143
sshpass -p vagrant ssh -T -o StrictHostKeyChecking=no vagrant@192.168.32.145
sshpass -p vagrant ssh -T -o StrictHostKeyChecking=no vagrant@192.168.32.150
sshpass -p vagrant ssh -T -o StrictHostKeyChecking=no vagrant@192.168.32.151
sshpass -p vagrant ssh -T -o StrictHostKeyChecking=no vagrant@192.168.32.152
데모를 준비했던 Ansible 프로젝트에서는 해당 IP를 사용하여 시스템을 구축했습니다.
작업환경이 변경될경우 SSH 접속정보를 변경하여 입력해 할당해주시면 됩니다.
-
ansible_env_ready.yml
--- - name: Setup for the Ansible's Environment hosts: localhost gather_facts: no tasks: - name: Add "/etc/ansible/hosts" blockinfile: path: /etc/ansible/hosts block: | [Ansible-Server] 192.168.32.143 [Management] 192.168.32.145 [K8S-Master] 192.168.32.150 [Worker] 192.168.32.151 192.168.32.152 - name: Create vim env's directories $ files shell: "" with_items: - "mkdir -p /home/vagrant/.vim/autoload /home/vagrant/.vim/bundle" - "touch /home/vagrant/.vimrc" - "touch /home/vagrant/.bashrc" - name: Install vim apt: name: vim state: present - name: Install ssh apt: name: ssh state: present - name: Install ssh pass apt: name: sshpass state: present - name: Install git apt: name: git state: present - name: Download pathogen.vim shell: "curl -fLo /home/vagrant/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim" - name: Git clone vim-ansible-yml git: repo: https://github.com/chase/vim-ansible-yaml.git dest: /home/vagrant/.vim/bundle/vim-ansible-yaml - name: Configure vimrc lineinfile: path: /home/vagrant/.vimrc line: "" with_items: - "set number" - "execute pathogen#infect()" - "syntax on" - name: Configure Bashrc lineinfile: path: /home/vagrant/.bashrc line: "" with_items: - "alias ans='ansible'" - "alias anp='ansible-playbook'"
ansible을 설치하고 기본적인 환경을 구축하는 playbook입니다.
다른부분은 따로 신경 쓸 필요가 없지만 작업환경이 변경될경우, 인벤토리를 지정하는 block 부분을 수정하여 host에 지정될 정보를 수정하면 됩니다.
홈 디렉토리에 해당 파일들이 모두 준비되어있으면 각 명령어를 실행하여 Ansible 작업환경을 구축해줍니다.
sh bash_ssh_conf_4_Ubuntu.sh
ansible-playbook ansible_env_ready.yml
sh add_ssh_auth.sh
명령을 순차적으로 실행하여 ansible을 사용하는데 필요한 기본 설정을 완료해줍니다.
명령어가 모두 수행되고나면
ans all -m ping -k
명령어를 이용하여 ansible 서버가 관리하는 host들에 ping이 정상적으로 응답하는지 확인합니다.
2.2 Vagrant를 이용한 Ansible 설치
2.1 과정에서 VM을 Vagrant를 이용하여 생성하고, 바로 Ansible을 설치 할 수 있습니다.
Vagrant는 위 링크에서 설치가 가능합니다.
[Downloads | Vagrant by HashiCorp](https://www.vagrantup.com/downloads) |
Vagrant를 설치하였으면, VMware에서 프로비저닝을 하기위해 추가 addon을 설치합니다.
[Installation - VMware Provider | Vagrant by HashiCorp](https://www.vagrantup.com/docs/providers/vmware/vagrant-vmware-utility) |
두가지를 모두 설치하였으면 시스템 재부팅이 권장됩니다.
재부팅을 하고나서 CMD또는 Powershell 창에서 해당 명령어를 입력합니다.
vagrant plugin install vagrant-vmware-desktop
vagrant version
다운로드 받았던 vmware addon 설치확인과 vagrant가 정상적으로 작동하는지 확인이 가능합니다.
-
Vagrantfile
#====================# # K8S Master Nodes # #====================# # K8S-Server # config.vm.define "k8s-master" do |cfg| cfg.vm.box = "bento/ubuntu-18.04" cfg.ssh.insert_key = false cfg.vm.provider "vmware_desktop" do |v| v.cpus = 4 v.memory = 8192 end cfg.vm.host_name = "k8s-master" cfg.vm.network "public_network", ip: "192.168.32.150" cfg.vm.synced_folder "../data", "/vagrant", disabled: true end #================# # Worker Nodes # #================# $num_instances = 2 (1..$num_instances).each do |i| config.vm.define "node#{i}" do |cfg| cfg.vm.box = "bento/ubuntu-18.04" cfg.ssh.insert_key = false cfg.vm.provider "vmware_desktop" do |v| end cfg.vm.host_name = "node#{i}" cfg.vm.network "public_network", ip: "192.168.32.15#{i}" cfg.vm.synced_folder "../data", "/vagrant", disabled: true config.vm.provider "vmware_desktop" do |v| v.cpus = 2 v.memory = 4096 end end end #================# # Ansible Server # #================# config.vm.define "ansible-server" do |cfg| cfg.vm.box = "bento/ubuntu-18.04" cfg.vm.provider "vmware_desktop" do |v| v.cpus = 2 v.memory = 4096 end cfg.vm.host_name = "ansible-server" cfg.ssh.insert_key = false cfg.vm.network "public_network", ip: "192.168.32.143" cfg.vm.synced_folder "../data", "/vagrant", disabled: true cfg.vm.provision "shell", inline: "apt install ansible -y" cfg.vm.provision "shell", path: "bash_ssh_conf_4_Ubuntu.sh" cfg.vm.provision "file", source: "ansible_env_ready.yml", destination: "ansible_env_ready.yml" cfg.vm.provision "shell", inline: "ansible-playbook ansible_env_ready.yml" cfg.vm.provision "shell", path: "add_ssh_auth.sh", privileged: false end end
Vagrant가 정상적으로 설치되어있으면, 터미널에서 Vagrantfile이 존재하는 디렉토리로 이동한 후,
vagrant up
명령어를 수행하면 이미지 프로비저닝이 실행됩니다.
위 과정에서 ansible에서 사용되는 playbook과 script들을 ansible-server에 전송합니다.
최상위폴더에 담겨있는 두개의 스크립트 파일과 ansible_env_ready.yml을 통해 apt 명령어로 ansible 설치와, ansible에 필요한 환경을 구축하는 ansible playbook을 실행합니다.
따라서 vagrant를 사용하여 이미지 프로비저닝을 하게될경우, Ansible을 사용하는 기본적인 환경설정은 vagrant에서 진행을하여 별도로 설치할 필요가 없습니다.
프로비저닝이 정상적으로 완료되었으면
vagrant ssh ansible-server
등의 명령으로 프로비저닝한 이름으로 접속이 가능합니다.
꼭 vagrant로 접속하지않아도 vagrantfile에 할당한 ip에 ssh 프로그램을 이용하여 접속해도 무방합니다.
접속한 상태에서 ping 모듈을 이용하여 ansible의 hosts에 응답이 정상적으로 오는지 확인 합니다.
ans all -m ping -k
3. Playbook
Ansible을 설치하여 정상적으로 작동되는것을 확인하였으면
Playbook을 작성하여 관리할 대상에 내릴 명령어를 작성합니다
3.1 Playbook 작성법
기본적인 Playbook의 구조는 다음과 같습니다
---
- name: install nginx on the client
hosts: webservers
become: yes
tasks:
- name: install epel-release
action: " name=epel-release state=latest"
- name: install nginx web server
action: " name=nginx state=present"
- name: start nginx web server
service: name=nginx state=started
name: playbook을 실행할때 구분되는 section입니다. 주석대신에 사용하여 playbook 실행시 진행 경과를 확인 할 수있습니다.
hosts: 작업이 수행될 인벤토리 블록을 지정하는 영역입니다. 지정한 host들에서만 작업을 실행합니다.
become: 관리자 권한을 부여하는 항목입니다. yes 또는 true를 입력할경우 관리자 권한으로 해당 블록을 실행합니다.
task: task 상위에 할당한 옵션으로 실제 명령을 수행하는 과정입니다. module이 task부분에 할당되며, 하위의 또다른 playbook 또는 apt, shell 등의 명령어를 수행 할 수 있습니다.
해당 playbook에서는 이라는 Role을 사용하여 [webserver]라는 인벤토리 내부에 CentOS와 Ubuntu 노드들이 존재합니다.
CentOS일경우 YUM 모듈을, Ubuntu일경우 APT 모듈을 호출하여 해당 명령을 수행합니다.
3.2 동시 실행 옵션
Fork
Ansible은 ansible.cfg 파일에 선언되어있는 “병렬실행갯수:””를 설정할 수 있습니다.
default Fork = 5 으로 실행시킬경우 다섯개의 프로세스가 동시에 실행됩니다.
이 숫자를 조정하여 원하는만큼 병렬작업을 늘릴수있고, 이 최적화 설정값은 직접 찾아야합니다.(fork 옵션은 관리하는 환경에따라 최적의 값이 달라질 수 있습니다)
Serial
Serial 키워드로 Playbook 에서 Task나 Role등을 실행할경우 동시에 실행되는 갯수도 직접 지정이 가능합니다.
Fork와 다르게 플레이북에서 “해당 블록에만 동시에 실행되는” 갯수를 지정할수있다는 점이 상이합니다.
---
- name: test play
hosts: webservers
serial: 3
gather_facts: False
tasks:
- name: first task
command: hostname
- name: second task
command: hostname
해당 명령을 [webservers] 호스트로 지정된 여섯개의 인스턴스에 명령을 실행하게되면 다음과 같은 결과가 노출됩니다.