Control Node, Controller, Ansible Engine
앤서블이 설치되는 시스템
Managed Node, Target Node/Host ...
BM, VM, Instance, Network Device
조건 : 윈도우, 리눅스 상관 없음
관리 노드의 목록을 가지고 있는 파일(?)
~.ini
정적 인벤토리 : 관리 노드의 목록 파일
동적 인벤토리 : 클라우드, CMDB에서 관리 노드 목록 가져옴
도커, 컨테이너 생명주기가 짧을 수 없음 -> 정적으로 관리 쉽지 않음, 목록을 텍스트로만 관리하는게 쉽지 않음
사용하면 ssh 아니여도 시스템관리 가능
Ansible 기능 확장
Ansible 작업 실행 할 수 있는 기본 단위
Python Code로 만들어져 있음
Ansible 임시 실행
하나의 모듈을 실행 가능
하나의 모듈을 실행 -> 하나의 테스크(작업)
하나 이상의 테스크의 모음
하나 이상의 플레이 모음(파일 .yaml)
이 파일안에 여러개의 플레이가 있을 수 있음
하나의 플레이에는 여러 개의 테스크
https://docs.ansible.com/
https://docs.ansible.com/ansible_community.html
여기 용어가 많음
인벤토리 문서
default location : /etc/ansible/hosts
[vagrant@controller ~]$ cd /etc/ansible/
[vagrant@controller ansible]$ ls
ansible.cfg hosts roles
다른 인벤토리 사용하기 위해선 -i <path>
로 잡아줘야 함
hosts안에는 처음에는 전부 주석
앤서블을 사용하기 위한 전략
회사에 다루는 사람 혼자라면 상관x -> 근데 여러명 앤서블로 자동화
후자의 경우 인벤토리 파일을 사용하는게 유리
etc 필요할때도 있지만 사용해선 안되는 경우가 있음
---> 기본 인벤토리 파일은 사용하지 않는 것을 선호함
홈 디렉토리 존재의의 이유 : 루트를 제외하면 다른사람 홈디렉토리의 접근 불가 -> 개별공간
기본 위치에 있는 인벤토리 파일이 아닌 경우 : -i
옵션 사용
변수를 설정할때 =
equal 을 사용
대괄호는 설정들을 분류하기 위해 만듬 [] = Section
key=value
[Section]
key=value
key # value 없이 key만 있는 경우
yaml은 들여쓰기와 띄어쓰기가 굉장히 중요-> 굉장히 귀찮음 -> 일반적으로 ini
playbook 생성시 대체할 것이 없음
FQDN : 호스트와 도메인을 함께 명시하여 전체 경로를 모두 표기하는 것
mail.example.com # manage node
# 그룹
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
ansible 명령 시, 관리노드명 말고 그룹명 지정도 가능
[ ]
: 인벤토리 그룹원칙 : 하나의 노드는 하나의 그룹에만 속해야 한다->X ==> 하나의 노드가 여러 개의 그룹에 속할 수 있음 -> 노드와 그룹은 1:1은 아니다
all: # 그룹
hosts: # 지시어 (그룹이 없는 관리노드)
mail.example.com:
children:
webservers: ## 그룹
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts: # 호스트 목록
one.example.com:
two.example.com:
three.example.com:
그룹이 그룹을 가질 수 있는다 : 네스티드 그룹, 중첩 그룹
children all 그룹에서 가질수 있는 그룹
--> 사실 귀찮음 쓰지말자.. ini 최고!
정의하지 않아도 존재하는 그룹
주의
인벤토리 생성 원칙
간결하게...복잡하게 만들면 모든 오류의 주된 원인은 사람, 인벤토리 파일을 만드는 것도 사람
그룹이 그룹을 가지고.. 그룹밑에 호스트가 지정할대 잘못된 그룹 지정하면 오류-> 설정되면 안되는 시스템에 설정이 된다거나 설정이 되어야할 시스템에 안되는 경우
실제로 IaC에서 많은 경우가 발생예시로 넷플릭스 모든 시스템 관리 IaC임
서비스 안되던 시간 IaC 변수 설정 잘못해서 라우팅 테이블 세팅이 안되어서 생긴 오류들
그룹 만들때(그룹에 호스트를 분류할 때)
가장 많은 형태는 application단위로 구분
호소트의 범위 레인지를 지정할때
연속적인 이름을 가지고 있는 경우
inventory.ini
[webservers]
www[01:50].example.com
192.168.100.[10:19]
[webservers]
www[01:50:2].example.com
01에서 50까지 2씩 증가
Q.범위를 지정했는데 호스트가 아직 없어도 에러는 안뜨나요?
A. 전부 다 있어야함 -> 전부 ssh 접속을 시도 -> 동적으로 사용하는게 좋음
변수를 설정
변수를 쭉 나열 가능
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
인벤토리 변수
[atlanta]
host1
host2
[atlanta:vars] # 그룹에 vars 그룹에 변수를 지정하는
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
vars 안쓰면
host1 ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
일일이 다해야함
[atlanta]
host1
host2
[raleigh] # 레드햇의 본사
host2
host3
[southeast:children]
atlanta
raleigh
[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
[usa:children]
southeast
northeast
southwest
northwest
children 없으면 host 있으면 그룹명이 들어와야함
usa그룹도 하위에 children 그룹을 가지고 있음
칠드런 있으면 무조건 그룹
사실 위코드는 오류, 정의가 안 되어 있기 때문에
나중에 변수들은 특수한 용도들을 가지고 있는 변수
인벤토리 파일 구조를 볼 수 있음
ansible-inventory -i <INVENTORY_FILE> --graph
[vagrant@controller ~]$ ansible-inventory -i b.ini --graph
@all:
|--@ungrouped:
|--@usa:
| |--@southeast:
| | |--@atlanta:
| | | |--host1
| | | |--host2
| | |--@raleigh:
| | | |--host2
| | | |--host3
_meta내용은 변수
Json 형식 및 호스트/그룹 변수
ansible-inventory -i <INVENTORY_FILE> --list
[vagrant@controller ~]$ ansible-inventory -i b.ini --list
{
"_meta": {
"hostvars": {
"host1": {
"escape_pods": 2,
"halon_system_timeout": 30,
"self_destruct_countdown": 60,
"some_server": "foo.southeast.example.com"
},
"host2": {
"escape_pods": 2,
"halon_system_timeout": 30,
"self_destruct_countdown": 60,
"some_server": "foo.southeast.example.com"
},
"host3": {
"escape_pods": 2,
"halon_system_timeout": 30,
"self_destruct_countdown": 60,
"some_server": "foo.southeast.example.com"
}
}
},
"all": {
"children": [
"ungrouped",
"usa"
]
},
"atlanta": {
"hosts": [
"host1",
"host2"
]
},
"raleigh": {
"hosts": [
"host2",
"host3"
]
},
"southeast": {
"children": [
"atlanta",
"raleigh"
]
},
"usa": {
"children": [
"southeast"
]
}
}
ansible-inventory -i <INVENTORY_FILE> --host <HOST>
{}
[vagrant@controller ~]$ ansible-inventory -i b.ini --host host1
{
"escape_pods": 2,
"halon_system_timeout": 30,
"self_destruct_countdown": 60,
"some_server": "foo.southeast.example.com"
}
빈칸은 호스트의 있는 변수 목록이 나오는 공간
ansible <HOST_PATTERN> -i <INVENTORY_FILE> --list-hosts
[vagrant@controller ~]$ ansible host1 -i b.ini --list-hosts
hosts (1):
host1
[vagrant@controller ~]$ ansible atlanta -i b.ini --list-hosts
hosts (2):
host1
host2
앤서블을 어떻게 작동시킬 수 있는지 설정파일
https://docs.ansible.com/ansible/latest/reference_appendices/config.html
미리 설정하면 매번 반복적인 옵션을 지정하지 않아도 됨
ANSIBLE_CONFIG
(environment variable if set)ansible.cfg
(in the current directory)~/.ansible.cfg
(in the home directory)/etc/ansible/ansible.cfg
기본 설정 파일똑같은 설정파일이 있다고 할 때,
-u ec2-user 미리 계정을 설정 해둘 수 있음 3,4 에도 할 수있고 근데 3,4 ,에 내용이 다를 때 3번이 우선순위가 더 높음. 같은 설정에 대해 어디가 우선순위가 높은지
디렉토리와 관계없이 지정되어 있으면 지정 됨
[vagrant@controller ~]$ touch /tmp/a.cfg
[vagrant@controller ~]$ export ANSIBLE_CONFIG=/tmp/a.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
config file = /tmp/a.cfg
[vagrant@controller ~]$ unset ANSIBLE_CONFIG # 환경변수 해제
[vagrant@controller ~]$ mkdir a b
[vagrant@controller ~]$ touch a/ansible.cfg
[vagrant@controller ~]$ touch b/ansible.cfg
[vagrant@controller ~]$ cd a
[vagrant@controller a]$ ansible --version
ansible 2.9.27
config file = /home/vagrant/a/ansible.cfg
[vagrant@controller a]$ cd ../b
[vagrant@controller b]$ ansible --version
ansible 2.9.27
config file = /home/vagrant/b/ansible.cfg
[vagrant@controller ~]$ pwd
/home/vagrant
[vagrant@controller ~]$ touch .ansible.cfg
[vagrant@controller ~]$ cat .ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
config file = /home/vagrant/.ansible.cfg
[vagrant@controller ~]$ rm ~/.ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
# 홈디렉토리는 .ansible.cfg 이 차이를 명확하게 알아야함(사용자를 따라다니는 설정)
[vagrant@controller ~]$ pwd
/home/vagrant
[vagrant@controller ~]$ touch ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
config file = /home/vagrant/ansible.cfg
[vagrant@controller ~]$ cd /tmp
[vagrant@controller tmp]$ ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg # 현재 적용되는 설정파일
1번과 4번은 전역적인 관점
3번은 해당되는 사용자에게만 부여되는 설정
4번은 해당되는 디렉토리에 접근한, 해당되는 디렉토리에 작업에 대해서만
내가 자주쓰는 설정 3번, 해당되는 작업에 특화되는 설정은 2번에 나머지는 잘 쓰지 않음
홈디렉토리에 있는건 사용자를 따라다님
cfg지만 ini 파일처럼 section이 존재
[vagrant@controller ~]$ egrep '^\[' /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
디폴트가 어디에 설정되어 있는지
ini 형식으로 할때 디폴트 섹션의 인벤토리라는 키를 사용한다
[vagrant@controller ~]$ vi .ansible.cfg
[defaults]
inventory=./inventory.ini
[vagrant@controller ~]$ ansible all --list-hosts
hosts (2):
*.11
*.12
다음과 같이 설정시 -i 옵션을 통한 인벤토리 파일을 지정할 필요가 없음
/etc/ansible/ansible.cfg보면 주석같지만 사실 디폴트 값
앤서블의 전제
OpenSSH : SSH
패키지 설치, 서비스 스타트, enable 관리자 권한이 필요함
루트사용자는 최소한으로 사용해야함 리눅스 시스템의 최소한의 보안
루트사용자는 시스템의 모든 권한을 가지고 있음
루트로 바로 접속하는 경우도 접속할 수 조차도 없음
sudo vi /etc/ssh/sshd_config
ssh 서버의 설정파일
이 파일은 관리자 권한만 가능 읽기 권한이 없기 때문에
설정 중에 38 라인 PermitRootLogin
기본 값은 No 루트로의 SSH 접근이 해제 되어있음
모든 클라우드 똑같음 -> 위험하기 때문에
루트 바로접속은 위험성이 있음
/etc/sudoers
파일
%wheel ALL=(ALL) ALL
vagrant *.100=(root) /usr/bin/ls
%wheel : wheel 그룹
ALL : 모든 시스템에서
(ALL) : 모든 사용자로
마지막 ALL : 모든 명령어
/etc/sudoers.d/vagrant
%vagrant ALL=(ALL) NOPASSWD: ALL
NOPASSWD sudo 할때 패스워드 묻지 않음 (passwordless sudo)
패스워드 없는 계정 인증할때도 사용-> 패스워드가 없으면 인증을 할 수 없기 때문
-u REMOTE_USER
SSH 접속 계정 지정 옵션(기본 : 현재 사용자)-k, --ask-pass
: 기본값은 Fasle, Ture 시 패스워드를 물어보기[vagrant@controller ~]$ ansible *.11 -i inventory.ini --list-hosts -k
SSH password:
옵션을 사용하지 않으면 -> SSH 키 인증
ansible의 기본 인증 방법: SSH 키 인증
-b, --become
: 권한 상승--become-method <sudo|su>
--become-user
: 어떤사용자로-K, --ask-become-pass
: sudo 패스워드 묻기https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html
커맨드 모듈 인덱스
free_form : 파라미터, 자유 양식
[vagrant@controller ~]$ ansible *.11 -i inventory.ini -m command -a id
*.11 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[vagrant@controller ~]$ ansible *.11 -i inventory.ini -m command -a id -b
*.11 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
ansible.cfg 편집
[defaults]
remote_user=<SSH_USER>
ask_pass=<True|False>
host_key_checking=<Ture|False> # defaults는 True
# 클라가 서버에 최초로 접속할 때, 지문 물어봄 -> ansible에선 known_hosts에 있는 지 확인 yes/no 묻지 않음 -> known_hosts에 없으면 접속을 안함
# 원래는 안물어 봤는데 지금은 물어봄
# 그룹을 지정하면 호스트가 100개면 전부 yes 쳐야함
# False면 무조건 yes한다
[privilege_escalation]
become=<True|False>
become_ask_pass=<True|False>
become_method=<sudo|su>
become_user=<SUDO_USER>
ask_pass
의 기본값 falsehost_key_cheking
의 기본값 truebecome
기본값 falsebecome_ask_pass
기본값 falsebecome_method
의 기본값 sudoansible-config
설정파일 검증ansible-config list
ansible-config dump
현재 설정된 항목 모두 확인
초록색 이상 없지만 변경도 없음
노란색은 변경 되었을때
빨간색은 실행이 안되었을때, 문제가 있을때
ansible-config view
https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html
ansible-doc -l
모듈 확인 가능
인터넷 연결안되어있어도 모듈의 목록을 확인 하할 수 있음
포맷 - 모듈 이름 : 간단한 설명
ansible-doc <MODULE_NAME>
모듈명으로 쓰면 모듈에 대한 상세정보 확인 가능
옵션 = 파라미터
ansible <HOST_PATTERN> -m <MODULE> -a <PARAMETER>
패턴지정
관리노드 설정시 호스트 명들에 패턴을 지정할 수 있음
[vagrant@controller ~]$ cat inventory.ini
*.11
*.12
[web]
weba
webb
[db]
weba
dba
dbb
[vagrant@controller ~]$ ansible web:db --list-hosts # 합집합과 같음
hosts (4):
weba
webb
dba
dbb
[vagrant@controller ~]$ ansible 'web:!db' --list-hosts
hosts (1):
webb
[vagrant@controller ~]$ ansible 'web:&db' --list-hosts # 교집합과 같음
hosts (1):
weba
패턴 사용하지 말기 --> 문제 발생 소지가 있음
목록 형태는 상관없음 멀티그룹까지 ok !, & nono 단순하게 하기
교집합 위험성이 너무 큼 -> 차라리 그룹을 만들어서 abc를 하기
윈도우 모듈도 있음
윈도우는 윈도우용으로 사용해야 함