[90DaysOfDevOps] Day 63~69 - Automate Configuration Management(Ansible)
Main Reference
90DaysOfDevOps/2022/ko/Days/day65.md at main · MichaelCade/90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things Dev...
github.com
Day 63
IaC
구성관리 = 애플리케이션, 시스템, 서버를 원하는 상태로 유지하는 프로세스
- 대표적인 구성관리 도구
- Chef
- Chef는 인프라 자동화를 통해 모든 환경, 모든 규모에서 구성이 일관되게 적용되도록 보장합니다.
- Chef는 Ruby와 Erlang으로 작성된 OpsCode에서 개발한 오픈 소스 도구입니다.
- Chef는 이기종 인프라를 보유하고 있으며 성숙한 솔루션을 찾고 있는 조직에 가장 적합합니다.
- Recipes와 Cookbooks은 시스템의 구성 코드를 결정합니다.
- 프로 - 방대한 Recipes 컬렉션을 사용할 수 있습니다.
- 장점 - 강력한 버전 제어를 제공하는 Git과 잘 통합됩니다.
- 단점 - 학습 곡선이 가파르며 상당한 시간이 필요함, 메인 서버에서 제어할 수 있는 권한이 많지 않습니다.
- 아키텍처 - 서버/클라이언트, 설정 용이성 - 보통, 언어 - 절차적 - 작업 수행 방법 지정
- Puppet
- Puppet은 자동 배포를 지원하는 구성 관리 도구입니다.
- Puppet은 Ruby로 빌드되며 매니페스트 작성에 DSL을 사용합니다.
- Puppet은 확장성에 중점을 둔 이기종 인프라에서도 잘 작동합니다.
- 장점 - 지원을 위한 대규모 커뮤니티가 있습니다. 잘 발달된 보고 메커니즘입니다.
- 단점 - 고급 작업을 수행하려면 Ruby 언어에 대한 지식이 필요합니다. 메인 서버에 대한 제어 권한이 많지 않습니다.
- 아키텍처 - 서버/클라이언트, 설정 용이성 - 보통, 언어 - 선언적 - 수행할 작업만 지정 가능
- Ansible
- Ansible은 구성 관리, 클라우드 프로비저닝, 배포 및 오케스트레이션을 자동화하는 IT 자동화 도구입니다.
- Ansible Playbook의 핵심은 YAML로 작성되어 있습니다.
- Ansible은 빠르게 시작하고 실행하는 데 중점을 두는 환경이 있을 때 잘 작동합니다.
- 서버에 지침을 제공하는 Playbook에서 작동합니다.
- 장점 - 원격 노드에 에이전트가 필요하지 않습니다. YAML은 배우기 쉽습니다.
- 단점 - 성능 속도가 다른 도구보다 느린 경우가 많습니다. YAML은 Ruby만큼 강력하지는 않지만 학습 곡선이 적습니다.
- 아키텍처 - 클라이언트 전용, 설정 용이성 - 매우 쉬움, 언어 - 절차적 - 작업 수행 방법 지정
- SaltStack
- SaltStack은 구성 관리와 원격 실행을 자동화하는 CLI 기반 도구입니다.
- SaltStack은 Python 기반이며, 명령어는 YAML 또는 해당 DSL로 작성됩니다.
- 확장성과 복원력을 최우선으로 고려하는 환경에 적합합니다.
- 장점 - 가동 및 실행 시 사용이 간편합니다. 우수한 보고 메커니즘입니다.
- 단점 - 설정 단계가 까다롭습니다. 다른 서비스보다 훨씬 덜 개발된 새로운 웹 UI가 있습니다.
- 아키텍처 - 서버/클라이언트, 설정 용이성 - 보통, 언어 - 선언적 - 수행할 작업만 지정함
- Ansible vs Terraform
Day 64
- ansible 설치
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
- ping 날리기
ansible localhost -m ping
이제 환경의 다른 Node를 제어하는 방법을 살펴보기 전에,
로컬 머신에 대해 ansible localhost -m ping 명령을 실행하여 ansible의 기능을 확인할 수도 있습니다.
이 명령은 Ansible 모듈을 사용하며, 여러 시스템에서 하나의 작업을 빠르게 수행할 수 있는 방법이기도 합니다.
또는 실제 모듈의 실제 사용법은 ansible webservers -m service -a "name=httpd state=started"와 같이
모든 웹서버에 httpd 서비스가 실행 중인지 여부를 알려주는 것일 수 있습니다.
호스트
위에서 localhost를 사용하여 시스템에 대한 간단한 핑 모듈을 실행하는 방법으로는 네트워크에 다른 컴퓨터를 지정할 수 없습니다.
예를 들어 VirtualBox가 실행 중인 Windows 호스트에는 IP 10.0.0.1의 네트워크 어댑터가 있지만 아래에서 볼 수 있듯이 핑으로 연결할 수 있지만 ansible을 사용하여 해당 작업을 수행할 수 없습니다.
이러한 작업으로 자동화할 호스트 또는 Node를 지정하려면 이를 정의해야 합니다.
시스템의 /etc/ansible 디렉토리로 이동하여 정의할 수 있습니다.
편집하려는 파일은 호스트 파일이며, 텍스트 편집기를 사용하여 호스트를 정의할 수 있습니다.
아래로 스크롤하여 [macos]라는 새 그룹을 만들고 해당 호스트에 대한 10.0.0.1 IP 주소를 추가하고 파일 저장
그러나 Ansible이 시스템에 연결하려면 SSH를 사용할 수 있어야 합니다...
ansible macos -m ping을 실행하면 SSH를 통한 연결에 실패하여 연결할 수 없다는 메시지가 표시됩니다.
이제 인벤토리에 호스트를 추가하기 시작했는데, 모든 장치를 정의하는 곳이기 때문에 이 파일의 다른 이름인 네트워크 장치, 스위치 및 라우터도 여기에 추가하고 그룹화할 수 있습니다.
하지만 호스트 파일에는 Linux 시스템 그룹에 액세스하기 위한 자격 증명도 추가했습니다.
그러면 이제 ansible Linux -m ping을 실행하면 성공해야하는데
저는 안됩니다
이제 구성을 자동화하려는 대상 시스템인 Node 요구 사항이 있습니다.
이 시스템에는 Ansible을 위한 어떤 것도 설치하지 않습니다(소프트웨어를 설치할 수는 있지만 필요한 Ansible의 클라이언트는 없습니다). Ansible은 SSH를 통해 연결하고 SFTP를 통해 모든 것을 전송합니다. (원하는 경우 SSH를 구성한 경우 SCP 대 SFTP를 사용할 수 있습니다.)
↓ ssh 에러 해결 시도
https://doinge-coding.tistory.com/entry/mac-os에서-원격로그인-기능-켜기-ssh-port-22-Connection-refused-에러-해결법
https://velog.io/@zihooy/M1-VM-ware-LinuxUbuntu
https://pinggoopark.tistory.com/343
https://blog.naver.com/leekdh1965/220662059675
https://lifegoesonme.tistory.com/517
https://iamjjanga.tistory.com/28
https://iamjjanga.tistory.com/28
https://velog.io/@kk21/MAC-SSH-접속-에러-Host-key-verification-failed
Ansible 명령
리눅스 머신에 대해 ansible Linux -m ping을 실행하고 응답을 얻을 수 있는 것을 보셨겠지만, 기본적으로 Ansible을 사용하면 많은 adhoc 명령을 실행할 수 있습니다.
하지만 이 명령을 시스템 그룹에 대해 실행하여 해당 정보를 다시 가져올 수 있습니다.
명령을 반복하거나 이러한 명령을 실행하기 위해 개별 시스템에 로그인해야 하는 경우 Ansible이 도움이 될 수 있습니다.
예를 들어, 아래의 간단한 명령은 Linux 그룹에 추가하는 모든 시스템에 대한 모든 운영 체제 세부 정보를 출력합니다.
ansible linux -a "cat /etc/os-release"
다른 사용 사례로는 시스템 재부팅, 파일 복사, 패커 및 사용자 관리 등이 있습니다. adhoc 명령과 Ansible 모듈을 결합할 수도 있습니다.
adhoc 명령은 선언적 모델을 사용하여 지정된 최종 상태에 도달하는 데 필요한 작업을 계산하고 실행합니다.
adhoc 명령은 시작하기 전에 현재 상태를 확인하고 현재 상태가 지정된 최종 상태와 다르지 않으면 아무 작업도 수행하지 않음으로써 일종의 무임승차를 하는 셈입니다.
Day 65
Ansible Playbook
이 섹션에서는 적어도 Ansible의 경우 하나의 명령으로 여러 서버를 실행하여,
긴 서버 목록을 재부팅하는 것과 같은 간단한 명령을 수행하고,
각 서버에 개별적으로 연결해야 하는 번거로움을 줄일 수 있다는 점이 가장 큰 장점이라고 할 수 있습니다.
하지만 실제로 베어 운영 체제를 가져와서 해당 시스템에서 실행할 소프트웨어와 서비스를 선언하고 모두 원하는 상태로 실행되도록 하는 것은 어떨까요?
이것이 바로 Ansible Playbook이 필요한 이유입니다.
Playbook을 사용하면 서버 그룹을 가져와서 해당 그룹에 대해 구성 및 설치 작업을 수행할 수 있습니다.
Ansible = 작업장의 도구, Ansible Playbook = 작업 메뉴얼, Inventory = 재료
Playbook 을 실행하면, Ansible 은 Playbook 파일 내용을 읽고, 작업을 수행할 Node 에게 작업을 전달해준다
hosts 는 해당 playbook 작업을 적용할 Node 를 지정한다.
인벤토리를 지정하지 않으면 ansible/hosts 에 입력된 모든 hosts 를 대상으로 범위를 지정하고,
인벤토리 파일이 지정되어 있으면, 해당 인벤토리 파일에 적힌 hosts 를 대상으로 범위를 지정한다.
hosts 에 all 을 입력하면, hosts 나 인벤토리 파일의 모든 hosts 에게 명령을 전달하며,
특정 Session 입력시 해당 Session 에 해당하는 hosts 에게만 명령을 전달한다
Playbook 형식
Playbook > Play > Task
Playbook은 다양한 Play와 Task로 구성된 Play 방법을 팀에게 알려주는 것으로,
Play를 스포츠나 게임의 세트 피스라고 생각하면 각 Play에 Task가 연관되어 있고, Play를 구성하는 여러 Task가 있을 수 있으며, Playbook에는 여러 가지 다른 Play가 있을 수 있습니다.
Playbook은 YAML로 작성되어 있습니다.
- name: Simple Play
hosts: localhost
connection: local
tasks:
- name: Ping me
ping:
- name: print os
debug:
msg: "{{ ansible_os_family }}"
ansible-playbook simple_play.yml 명령을 사용하면 다음과 같이 나옴
'gathering facts'라는 첫 번째 Task가 발생한 것을 볼 수 있지만, 우리가 트리거하거나 요청하지 않았음
이 모듈은 원격 호스트에 대한 유용한 변수를 수집하기 위해 Playbook에서 자동으로 호출됩니다. ansible.builtin.setup
두 번째 Task는 Ping을 설정하는 것이었는데, 이것은 ICMP Ping이 아니라 원격 또는 로컬 호스트에 대한 연결 성공 시 pong을 반환하는 파이썬 스크립트입니다. ansible.builtin.ping
그런 다음 첫 번째 Task로 정의한 세 번째 또는 두 번째 Task는 OS를 알려주는 메시지 인쇄를 비활성화하지 않는 한 실행됩니다.
이 Task에서는 조건문을 사용하고 있으므로 모든 유형의 운영 체제에 대해 이 Playbook을 실행할 수 있으며,
그러면 OS 이름이 반환됩니다. 편의상 이 출력은 단순히 메시지를 출력하고 있지만 다음과 같이 말하는 Task를 추가할 수 있습니다:
tasks:
- name: "shut down Debian flavoured systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
< Vagrant 파일을 사용하여 4대의 머신 배포하는 playbook 만들기 >
Vagrant로 환경 설정하기
Vagrant를 사용하여 Node 환경설정하기
합리적인 4 Node로 유지하려고 하지만 300 Node 또는 3000 Node도 될 수 있으며
이것이 서버를 구성할 수 있는 Ansible 및 기타 구성 관리 도구의 힘이라는 것
Vagrant.configure("2") do |config|
servers=[
{
:hostname => "db01",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.130",
:ssh_port => '2210'
},
{
:hostname => "web01",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.131",
:ssh_port => '2211'
},
{
:hostname => "web02",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.132",
:ssh_port => '2212'
},
{
:hostname => "loadbalancer",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.134",
:ssh_port => '2213'
}
]
config.vm.base_address = 600
servers.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = machine[:box]
node.vm.hostname = machine[:hostname]
node.vm.network :public_network, bridge: "Intel(R) Ethernet Connection (7) I219-V", ip: machine[:ip]
node.vm.network "forwarded_port", guest: 22, host: machine[:ssh_port], id: "ssh"
node.vm.provider :virtualbox do |v|
v.customize ["modifyvm", :id, "--memory", 2048]
v.customize ["modifyvm", :id, "--name", machine[:hostname]]
end
end
end
end
이 파일 해석이 궁금해서 ↓
이 Vagrant 설정 파일은 4개의 가상 머신을 생성하고 구성하는 데 사용됩니다. 각 가상 머신은 다음과 같은 속성을 가지고 있습니다:
1. **db01**: 호스트 이름이 `db01`이며 IP 주소는 `192.168.169.130`입니다. SSH 포트는 호스트의 포트 `2210`으로 포워딩됩니다.
2. **web01**: 호스트 이름이 `web01`이며 IP 주소는 `192.168.169.131`입니다. SSH 포트는 호스트의 포트 `2211`으로 포워딩됩니다.
3. **web02**: 호스트 이름이 `web02`이며 IP 주소는 `192.168.169.132`입니다. SSH 포트는 호스트의 포트 `2212`으로 포워딩됩니다.
4. **loadbalancer**: 호스트 이름이 `loadbalancer`이며 IP 주소는 `192.168.169.134`입니다. SSH 포트는 호스트의 포트 `2213`으로 포워딩됩니다.
이 설정 파일은 Ansible을 사용하여 가상 머신에 접속할 때 필요한 IP 주소 및 포트 정보를 제공합니다.
각 가상 머신은 `public_network`을 사용하여 호스트 네트워크에 연결되어 있으며, SSH 포트 포워딩을 통해 호스트의 각 포트에 대한 SSH 접속을 허용합니다.
또한 각 가상 머신은 VirtualBox 프로바이더를 사용하여 구성되며, 메모리는 2048MB로 설정되어 있습니다.
호스트의 네트워크 브리지는 `Intel(R) Ethernet Connection (7) I219-V`로 설정되어 있습니다.
이 설정 파일을 사용하여 Vagrant를 실행하면 정의된 가상 머신이 생성되고 구성됩니다.
이후에는 Ansible을 사용하여 각 가상 머신에 접속하여 필요한 작업을 수행할 수 있습니다.
vagrant up 명령을 사용하여 VirtualBox에서 이러한 머신을 스핀업하면 메모리를 더 추가할 수 있고,
각 머신에 대해 다른 private_network 주소를 정의할 수도 있지만 우분투 데스크톱에서는 이 방법으로 작동함.
리소스가 제한되어 있는 경우 vagrant up web01 web02를 실행하여 여기서 사용 중인 웹서버만 불러올 수도 있습니다.
Ansible 호스트 구성
이제 환경이 준비되었으므로 Ansible을 확인할 수 있으며,
이를 위해 우분투 데스크톱(이 데스크톱을 사용할 수도 있지만 아래 네트워크에 액세스하는 네트워크에 있는 모든 Linux 기반 머신을 동일하게 사용할 수 있음)을 컨트롤로 사용하고,
ansible 호스트 파일에서 새 Node를 그룹에 추가해 보겠습니다.
이 파일을 인벤토리로 생각할 수 있으며, 이에 대한 대안으로 -i filename을 사용하여 ansible 명령의 일부로 호출되는 또 다른 인벤토리 파일을 사용할 수 있습니다.
이는 프로덕션, 테스트 및 스테이징 환경마다 다른 파일을 가질 수 있으므로 호스트 파일을 사용하는 것보다 유용할 수 있습니다.
기본 호스트 파일을 기본으로 사용하므로 지정할 필요가 없습니다.
기본 호스트 파일에 다음 추가하기
Node에 대해 명령을 실행할 수 있는지 확인하기 위해 ansible nodes -m command -a hostname을 실행해 보겠습니다.
이 간단한 명령은 연결이 있는지 테스트하고 호스트 이름을 다시 보고합니다.
ssh 연결
이 단계에서는 제어 Node와 서버 Node 사이에 SSH 키를 설정하는 과정을 진행하겠습니다.
다음 단계에서는 호스트의 파일에 변수를 추가하여 사용자 이름과 비밀번호를 제공하는 방법을 사용할 수 있습니다.
이 방법은 결코 모범 사례가 될 수 없으므로 권장하지 않습니다.
- ssh-keygen
= ssh-keygen은 SSH 키를 생성하는 명령어입니다. 이 명령어를 사용하여 SSH 키 쌍을 생성할 수 있으며, 이 키 쌍은 공개 키와 개인 키로 구성됩니다.
기본적으로 ssh-keygen 명령어를 사용하면 사용자의 홈 디렉토리에 .ssh 폴더 아래에 기본적인 키 쌍이 생성됩니다. 개인 키는 id_rsa 파일로, 공개 키는 id_rsa.pub 파일로 저장됩니다.
- ssh-copy-id localhost
모든 VM이 켜져 있다면 ssh-copy-id web01 && ssh-copy-id web02 && ssh-copy-id loadbalancer && ssh-copy-id db01을 실행하면 비밀번호를 입력하라는 메시지가 표시됩니다(이 경우 비밀번호는 vagrant입니다).
모든 VM을 실행하지 않고 웹서버만 실행하고 있으므로 ssh-copy-id web01 && ssh-copy-id web02를 발급했습니다.
Playbook을 실행하기 전에 그룹과 연결되었는지 확인하기
- ansible webservers -m ping을 실행하여 연결을 테스트하기
Ansible Playbook 구성해보기
첫 번째 Ansible Playbook은 웹 서버를 구성하는 것으로, 호스트 파일에서 [webservers] 그룹 아래에 웹 서버를 그룹화했습니다.
Playbook을 실행하기 전에 web01과 web02에 apache가 설치되어 있지 않은 것을 확인할 수 있습니다.
아래 스크린샷 상단은 이 Playbook을 실행하기 위해 ansible 컨트롤 내에서 생성한 폴더 및 파일 레이아웃을 보여줍니다.
playbook1.yml이 있고, template 폴더에는 index.html.j2와 ports.conf.j2 파일이 있습니다.
그런 다음 web01에 SSH로 접속하여 apache가 설치되어 있는지 확인합니다.
command not found로 설치되어 있지 않다는 걸 알 수 있으니
- hosts: webservers
become: yes
vars:
http_port: 8000
https_port: 4443
html_welcome_msg: "Hello 90DaysOfDevOps"
tasks:
- name: ensure apache is at the latest version
apt:
name: apache2
state: latest
- name: write the apache2 ports.conf config file
template:
src: templates/ports.conf.j2
dest: /etc/apache2/ports.conf
notify:
- restart apache
- name: write a basic index.html file
template:
src: templates/index.html.j2
dest: /var/www/html/index.html
notify:
- restart apache
- name: ensure apache is running
service:
name: apache2
state: started
handlers:
- name: restart apache
service:
name: apache2
state: restarted
이걸 실행해서 해결해주기
이 playbook 해석
- host: webserver는 이 Playbook을 실행할 그룹이 웹서버라는 그룹이라는 것을 의미
- become: yes는 Playbook을 실행하는 사용자가 원격 시스템에서 루트가 된다는 의미, 루트 비밀번호를 입력하라는 메시지가 표시됨
- vars : 웹서버 전체에서 원하는 몇 가지 환경 변수를 정의
그런 다음 Task를 시작
- Task 1 : apache가 최신 버전을 실행 중인지 확인하는 것
- Task 2 : template 폴더에 있는 소스에서 ports.conf 파일을 작성하는 것
- Task 3 : 기본 index.html 파일을 생성하는 것
- Task 4 : apache가 실행 중인지 확인하는 것
그리고 handlers : Handler는 알림을 받을 때만 실행되는 태스크
이 단계에서는 5개의 VM을 배포했다고 생각할 수 있습니다(Ansible 컨트롤 역할을 하는 Ubuntu 데스크톱 머신 포함).
Playbook 실행
< web01과 web02를 개별 웹 서버로 만드는 Playbook 만들기 >
Node에 대해 Playbook을 실행할 준비가 되었습니다.
Playbook을 실행하려면 ansible-playbook playbook1.yml을 사용하면 됩니다.
Playbook 내에서 Playbook이 실행될 호스트를 정의했으며, 정의한 Task를 안내합니다.
명령이 완료되면 Play와 Task를 보여주는 출력이 표시되며, 아래 이미지에서 원하는 상태를 설치하는 데 시간이 걸리는 것을 확인할 수 있습니다.
그런 다음 Node로 이동하여 Node에 소프트웨어가 설치되었는지 확인하여 이를 다시 확인할 수 있습니다.
위와 같이 두 개의 독립형 웹서버를 배포했으므로
이제 정의한 각각의 IP로 이동하여 새 웹 사이트를 가져올 수 있다
(부럽다)
- 로컬 호스트를 사용하여 로컬 호스트에 대해 Playbook을 실행할 수 있다
- Ubuntu VM으로만 작업하고 있지만 Ansible은 대상 시스템에 구애받지 않는다
- 시스템을 관리하기 위해 이전에 언급했던 대안은 서버별로 서버를 관리할 수 있습니다(서버 수가 많을 경우 확장성이 떨어지고 Node가 3개일 때도 문제가 있음)
- Linux 섹션에서 다시 다룬 셸 스크립팅을 사용할 수도 있지만 이러한 Node는 잠재적으로 다를 수 있으므로 가능하지만 누군가 스크립트를 유지 및 관리해야 한다
↓ 심플 playbook 배포글 참고
https://medium.com/@linolowlevel/creating-simple-ansible-playbook-b719c5829213
Creating Simple Ansible Playbook
Automate your task with ansible
medium.com
Day 66-7
Role과 Ansible Galaxy
현재 4개의 VM을 배포했으며 이 중 2개의 VM을 웹 서버로 구성했지만
데이터베이스 서버와 로드 밸런서 또는 프록시 등 좀 더 구체적인 기능이 있습니다.
이 작업을 수행하고 리포지토리를 정리하기 위해 Ansible 내에서 Role을 사용할 수 있습니다.
이를 위해 공유 리포지토리에서 Ansible Role을 관리하기 위해 존재하는 ansible-galaxy 명령을 사용합니다.
ansible-galaxy를 사용하여 웹서버에 대한 세부 정보를 넣을 apache2의 Role을 생성할 것입니다.
ansible-galaxy init roles/apache2는 위에 표시된 폴더 구조를 생성합니다.
기존 작업과 template을 새 구조의 관련 폴더로 이동하기
- 복사하여 붙여넣으면 파일을 쉽게 옮길 수 있지만, tasks/main.yml을 변경하여 이 파일이 apache2_install.yml을 가리키도록 해야 합니다. (오호...)
- 또한 새로운 Role을 참조하도록 Playbook을 변경해야 합니다. playbook1.yml과 playbook2.yml에서 작업과 Handler를 두 버전 간에 변경하면서 다른 방식으로 결정합니다. 아래와 같이 이 Role을 사용하도록 Playbook을 변경해야 합니다:
- hosts: webservers
become: yes
vars:
http_port: 8000
https_port: 4443
html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!"
roles:
- apache2
우리가 만들 ansible-galaxy를 사용하면서 몇 가지 Role을 더 만들 것입니다:
- common = 모든 서버용(ansible-galaxy init roles/common)
- nginx = 로드밸런서용(ansible-galaxy init roles/nginx)
vagrant up web01 web02만 사용했다면
이제 vagrant up loadbalancer를 실행하면 로드 밸런서/프록시로 사용할 다른 Ubuntu 시스템이 나타납니다.
호스트 파일에 이 새 시스템을 이미 정의했지만, 사용할 수 있을 때까지 ssh 키가 구성되지 않았으므로 시스템이 가동되고 준비되면 ssh-copy-id loadbalancer도 실행해야 합니다.
다시 Role로 넘어가서 ~.~
Role이 뭘까?
예를들어서 프로젝트를 진행한다고 했을 때 마구잡이로 프로그래밍을 하게되면 유지보수하기도, 미래에 재사용하기도 어렵습니다.
이런 문제들을 방지하기위해 코드의 구성을 체계화하고 모듈화를 시키는 것이 일반적입니다.
이와 비슷하게 Ansible에서 Playbook에 대한 체계화를 시켜주는 것이 Role입니다.
Role은 여러 연관된 Task들을 체계화시키고 여러 playbook에 추가시켜 사용할 수 있습니다
---
매번 동일한 내용을 플레이북을 만들때마다 쓰게 되어 플레이북도 많아지고 중복되는 내용이 많았습니다.
그래서 재사용의 필요성을 느꼈고, 재사용을 하기 위해선 template과 role을 잘 사용 해야 합니다.
role은 말그대로 역할을 정의하고 그에 대해서 directory별로 분리합니다.
- Common은 모든 서버에서 사용되는 반면, 다른 Role은 사용 사례에 따라 다르지만, 이제 설치하려는 애플리케이션은 가짜처럼 일반적이며 이것이 왜 그런지 많은 이유를 알 수는 없지만 그 목적을 보여줍니다. (??)
- Common Role 폴더 구조에서 작업 폴더로 이동하면 main.yml이 있습니다. 이 YAML에서 이 파일을 install_tools.yml 파일로 가리켜야 하며, - import_tasks: install_tools.yml 줄을 추가하여 이를 수행합니다.
- 이전에는 include였으나 곧 사용되지 않을 예정이므로 import_tasks를 사용합니다.
- name: "Install Common packages"
apt: name={{ item }} state=latest
with_items:
- neofetch
- tree
- figlet
그런 다음 playbook에서 각 호스트 블록에 대한 Common Role을 추가합니다.
- hosts: webservers
become: yes
vars:
http_port: 8000
https_port: 4443
html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!"
roles:
- common
- apache2
Nginx
로드밸런서 VM에 nginx를 설치하고 구성하기
일반적인 폴더 구조 기반으로 nginx를 구성합니다.
- 먼저 playbook에 호스트 블록을 추가하겠습니다. 이 블록에는 Common Role과 새로운 nginx Role이 포함됩니다.
- hosts: webservers
become: yes
vars:
http_port: 8000
https_port: 4443
html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!"
roles:
- common
- apache2
- hosts: proxy
become: yes
roles:
- common
- nginx
이것이 의미가 있으려면 실행할 작업을 정의해야 하며, 같은 방식으로 이번에는 설치용 파일과 구성용 파일 두 개를 가리키도록 작업의 main.yml을 수정해야 합니다.
업데이트된 playbook 실행
- anible-playbook playbook4.yml을 사용하여 playbook4.yml을 실행해보기
이제 웹 서버와 로드밸런서가 구성되었으므로 이제 로드밸런서의 IP 주소인 http://192.168.169.134/ 로 이동할 수 있어야 합니다.
만약 안보인다면 사용 중인 환경의 서버 IP주소 때문일 수 있음
upstream webservers {
server 192.168.169.131:8000;
server 192.168.169.132:8000;
}
server {
listen 80;
location / {
proxy_pass http://webservers;
}
}
templates\mysite.j2 에서 찾을 수 있으며 웹 서버 IP 주소로 업데이트 해주기
Day 68
Tag, Variable, Inventory 및 Database 서버 구성
1. Tag
playbook을 남겨두었으므로 모든 작업을 실행하고 해당 playbook 내에서 play해야 합니다.
즉, 웹서버와 로드밸런서 play 및 작업을 모두 실행해야 완료할 수 있습니다.
하지만 Tag를 사용하면 원하는 경우 이러한 작업을 분리할 수 있습니다.
이는 환경에 매우 크고 긴 playbook이 있는 경우 효율적인 방법이 될 수 있습니다.
Tag는 작업 수준에서도 추가할 수 있으므로 원하는 위치와 작업을 세분화할 수 있습니다.
예를 들어 애플리케이션 중심 Tag가 될 수도 있고, 작업을 살펴보고 설치, 구성 또는 제거에 따라 작업에 Tag를 지정할 수도 있습니다.
tag: always 이것은 명령에 어떤 --tags를 사용하든 상관없이 항상 값으로 Tag가 지정된 항목이 있으면 ansible-playbook 명령을 실행할 때 항상 실행되도록 보장합니다.
Tag를 사용하여 여러 Tag를 함께 묶을 수도 있으며, ansible-playbook playbook5.yml --tags proxy,web을 실행하도록 선택하면 해당 Tag가 있는 모든 항목이 실행됩니다.
물론 이 예제에서는 playbook을 실행하는 것과 같은 의미이지만, 다른 play가 여러 개 있는 경우에는 이 방법이 의미가 있을 것입니다.
둘 이상의 Tag를 정의할 수도 있습니다.
1.2. Variable
- Ansible Facts
- User created
1.2.1. Ansible Facts
playbook을 실행할 때마다 "Gathering facts"라는 정의되지 않은 작업이 있었는데,
이러한 Variable 또는 fact를 사용하여 자동화 작업을 수행할 수 있습니다.
ansible proxy -m setup 명령을 실행하면 JSON 형식의 많은 출력을 볼 수 있습니다.
이 파일을 열면 명령에 대한 모든 종류의 정보를 볼 수 있습니다. IP 주소, 아키텍처, 바이오스 버전을 확인할 수 있습니다.
이 정보를 활용하여 playbook에 사용하려는 경우 유용한 정보가 많이 있습니다.
- 웹서버의 IP 주소를 하드코딩한 nginx template mysite.j2 내에서 이러한 Variable 중 하나를 잠재적으로 사용하는 것입니다.
- mysite.j2에 for 루프를 생성하면 [webservers] 그룹을 순환하여 2개 이상의 웹서버를 자동으로 동적으로 생성하거나 이 로드 밸런서 구성에 추가할 수 있습니다.
1.2.2. User created
- User created Variable은 우리가 직접 만든 Variable입니다.
- playbook을 살펴보면 vars:가 있고 거기에 3개의 Variable 목록이 있는 것을 볼 수 있습니다.
- 그러나 Variable을 해당 파일로 이동하여 playbook에 Variable이 없도록 할 수 있습니다.
- 이 Variable을 전역 Variable로 연결하기 때문에 여기에 NTP 및 DNS 서버도 추가할 수 있습니다.
- Variable은 우리가 만든 폴더 구조에서 설정됩니다. 그 Variable 중 하나는 http_port로, 아래와 같이 mysite.j2 내의 for 루프에서 이 Variable을 다시 사용할 수 있습니다:
- 또한, 어떤 웹서버를 사용하고 있는지 파악할 수 있도록 roles/apache2/templates/index.HTML.j2 파일에 분석 가능한 사실을 정의할 수도 있습니다
- .Variable을 변경하여 ansible-playbook playbook6.yml 명령을 실행한 결과, 로드밸런서에 도달하면 그룹에 있는 웹서버 중 하나에 도달한 것을 볼 수 있습니다.
- 또한 host_vars라는 폴더를 추가하고 web01.yml을 생성하여 원하는 경우 특정 메시지를 표시하거나 호스트별로 표시되는 내용을 변경할 수 있습니다.
https://nice-engineer.tistory.com/entry/Ansible-%ED%83%9C%EA%B7%B8-Tag
[Ansible] 태그 (Tag)
✔️ 태그 (Tag) Tags — Ansible Documentation If you want to apply the same tag or tags to multiple tasks without adding a tags line to every task, you can define the tags at the level of your play or block, or when you add a role or import a file. An
nice-engineer.tistory.com
2. Inventory 파일
- 지금까지 호스트를 결정하기 위해 /etc/ansible 폴더에 있는 기본 호스트 파일을 사용했습니다.
- 그러나 프로덕션 및 스테이징과 같이 환경마다 다른 파일을 사용할 수 있습니다.
- 서버와 노드의 다양한 Inventory에 대해 여러 개의 파일을 만들 수 있습니다.
- 우리는 ansible-playbook -i dev playbook.yml을 사용하여 이를 호출합니다.
- 호스트 파일 내에 Variable을 정의한 다음 이를 출력하거나 playbook의 다른 곳에서 해당 Variable을 활용할 수도 있습니다.
- 예를 들어 아래 예제 및 교육 과정에서는 호스트 파일에서 생성된 환경 Variable을 로드밸런서 웹 페이지 template에 추가하여 웹 페이지 메시지의 일부로 환경을 표시했습니다.
Ansible inventory 작성하기
Inventory Ansible을 사용하기 앞서 Ansible로 관리하려는 노드들 즉 Managed node들에 대해서 관리하려면 Inventory 파일을 먼저 작성을 해야한다. 이 Inventory 파일을 hostfile 이라고도 불리며, ansible 실행 시
blog.softpine.dev
https://nearhome.tistory.com/113
[Ansible] 인벤토리(Inventory) 란?
인벤토리 란? 정적 인벤토리 INI 형식 YAML 형식 동적 인벤토리 인벤토리 확인 패턴 인벤토리 란? Ansible은 인프라에 존재하는 여러 호스트를 관리합니다. 이런 호스트의 목록 또는 그룹을 지정하는
nearhome.tistory.com
3. Database 서버 배포
- vagrant 파일이 있는 곳에서 vagrant up db01을 사용하여 이 작업을 수행할 수 있습니다.
- 전원이 켜지고 액세스할 수 있게 되면 ssh-copy-id db01을 사용하여 SSH 키를 복사하여 액세스할 수 있도록 해야 합니다.
- ansible-galaxy init roles/mysql을 사용하여 "MySQL"이라는 새 Role에 대한 새 폴더 구조를 만들어 보겠습니다.
playbook에서 Database 구성을 위한 새로운 play 블록을 추가하겠습니다.
/etc/ansible/hosts 파일에 그룹 Database가 정의되어 있습니다.
그런 다음 Database 그룹에 공통 Role과 이전 단계에서 생성한 MySQL이라는 새 Role을 갖도록 지시합니다.
또한 Database 그룹에 Database Tag를 지정하고 있는데, 이는 앞서 설명한 것처럼 원하는 경우 이러한 Tag에 대해서만 실행하도록 선택할 수 있음을 의미합니다.
- hosts: webservers
become: yes
roles:
- common
- apache2
tags:
web
- hosts: proxy
become: yes
roles:
- common
- nginx
tags:
proxy
- hosts: database
become: yes
roles:
- common
- mysql
tags: database
>> Role 폴더 구조 내에서 트리가 자동 생성되었으므로 Handler, Tasks 수정하기
Tasks - install_mysql.yml, main.yml & setup_mysql.yml
- install_mysql.yml - 이 작업은 MySQL을 설치하고 서비스가 실행 중인지 확인하기 위해 수행됩니다.
- main.yml은 이러한 파일에서 작업을 가져오도록 제안하는 포인터 파일입니다.
- setup_mysql.yml - 이 작업은 Database와 Database 사용자를 생성합니다.
- 비밀번호, 사용자 이름 및 Database와 같은 일부 구성을 결정하기 위해 몇 가지 Variable을 사용하고, 이 Variable은 모두 group_vars/all/common_variables.yml 파일에 저장되어 있습니다.
playbook실행
ansible-playbook playbook7.yml을 실행하면 이전에 수행한 모든 작업이 포함된 playbook을 실행할 수 있고,
ansible-playbook playbook7.yml --tags database 명령으로 Database 그룹에 배포하여 새 구성 파일만 실행하도록 선택할 수도 있습니다.
MySQL에 연결하기 위해 sudo /usr/bin/mysql -u root -p를 사용하고 프롬프트에서 root에 대한 vagrant 암호를 제공했습니다.
연결이 완료되면 먼저 DevOps라는 사용자가 생성되었는지 확인합니다. select user, host from mysql.user;
이제 SHOW DATABASES; 명령을 실행하여 생성된 새 Database를 확인할 수 있습니다.
Day 69
< Ansible 자동화 플랫폼을 구성하는 다른 제품들 >
1. Red Hat Ansible Automation Platform
- 조직 전반에서 자동화를 구축하고 운영하기 위한 기반
- 이 플랫폼에는 전사적인 자동화를 구현하는 데 필요한 모든 도구가 포함
2. Ansible 자동화 컨트롤러 | AWX
자동화 컨트롤러와 AWX는 제공하는 기능이 매우 유사하기 때문에 이 두 가지를 함께 묶었습니다.
AWX
- Red Hat이 후원하는 오픈 소스 커뮤니티 프로젝트로, 사용자 환경 내에서 Ansible 프로젝트를 더 잘 제어할 수 있도록 지원합니다.
- AWX는 자동화 컨트롤러 구성 요소가 파생된 업스트림 프로젝트입니다.
엔터프라이즈 솔루션을 찾고 계신다면 자동화 컨트롤러를 찾으시거나 이전에 Ansible Tower라고 들어보셨을 것입니다.
Ansible 자동화 컨트롤러
- Ansible 자동화 플랫폼의 컨트롤 플레인입니다.
- 자동화 컨트롤러는 지원 비용을 지불하는 엔터프라이즈 제품입니다.
AWX와 자동화 컨트롤러는 다음과 같은 기능을 제공합니다.
- 사용자 인터페이스
- 역할 기반 액세스 제어
- workflow
- CI/CD 통합
3. Ansible Vault
- ansible-vault를 사용하면 Ansible 데이터 파일을 암호화하고 해독할 수 있습니다.
- Ansible 바이너리에는 이 민감한 정보를 마스킹할 수 있는 ansible-vault가 내장되어 있습니다.
- 비밀 관리는 점차 HashiCorp Vault나 AWS 키 관리 서비스와 같은 도구와 함께 더 많은 시간을 할애해야 하는 또 다른 영역이 되었습니다.
Ansible 테스트 지원 도구
- Ansible Molecule - Molecule 프로젝트는 Ansible 역할의 개발 및 테스트를 지원하도록 설계되었습니다.
- Ansible Lint - playbook, 역할 및 컬렉션을 Lint하기 위한 CLI 도구입니다.