[K8S Deploy Study by Gasida] - Ansible 기초
앤서블 기본
동작원리
- 앤서블은 제어노드에 앤서블 코어가 설치되고 플레이북을 작성하여 실행할 수 있는 제어노드(Control Node) 와 플레이북이 실행되어 애플리케이션 설치나 클라우드 시스템의 가상서버 생성과 같은 작업이 수행되는 관리노드(Managed Nodes)로 구성된다.
- 앤서블은 리눅스, MacOS, BSC 계열 유닉스, WSL을 지원하는 원도우에 파이썬과 앤서블 코어만 설치하면 어디에서나 플레이북(YAML 형식의 작업들은 순서대로 작성해 놓은 파일)을 작성하고 이를 실행시킬 수 있다.
하드웨어 구동 환경(Architecture)
- 앤서블이 실행되고 관리되는 물리적/논리적 장치
- 제어 노드 (Control Node): 앤서블 도구(ansible-playbook 등)가 설치된 컴퓨터. 여기서 명령을 내리며, 파이썬이 설치된 리눅스나 맥 OS 환경이면 가능하다.
- 관리 노드 (Managed Nodes): 앤서블로 관리되는 대상 서버나 네트워크 장비. ‘호스트’라고도 불리며, 관리 노드에는 일반적으로 앤서블을 설치할 필요가 없다 (Agentless).
관리 대상 설정 (Targeting)
누구를 관리할지 정의하는 영역
- 인벤토리 (Inventory) : 관리 노드들의 목록을 담은 파일. 각 서버의 IP 주소나 그룹(예: webservers, dbservers) 정보를 관리하며 특정 그룹에만 명령을 내릴때 사용한다.
실행 콘텐츠 및 구조
무엇을 어떻게 실행할지 정의하는 시나리오
플레이북 (Playbooks): YAML 형식으로 작성된 설정 관리 파일. 전체 자동화 프로세스를 담고 있는 ‘설계도’로 생각할 수 있다.
플레이 (Plays): 플레이북 내부의 기본 단위로 ‘어떤 호스트’에게 ‘어떤 작업’을 시킬지 매핑하는 역할을 한다.
태스크 (Tasks): 실행할 구체적인 하나의 ‘작업’ 정의
핸들러 (Handlers): 특정 태스크가 상태를 변화(changed)시켰을 때만 실행되는 특수 태스크. (예: 설정 파일 수정 시 서비스 재시작)
롤 (Roles): 태스크, 변수, 파일 등을 용도별로 묶어 재사용 가능하게 만든 패키지 단위
확장 도구 및 구성 요소 (Tools & Extensions)
실제 작업을 수행하는 기술적 수단.
모듈 (Modules): 태스크가 실제로 실행하는 코드 뭉치. 사용자 추가, 패키지 설치 등 특정 목적을 수행하며, 관리 노드로 복사되어 실행된 후 삭제된다.
플러그인 (Plugins): 앤서블의 기능을 확장하는 코드. 연결 방식(SSH), 데이터 변환(필터), 로그 출력 방식 등을 제어한다.
컬렉션 (Collections): 플레이북, 롤, 모듈, 플러그인을 하나로 묶어 배포하는 표준 형식이다. Ansible Galaxy를 통해 공유되고 설치된다.
앤서블의 특징
- Agentless
- 데몬 형식의 에이전트에 기반한 자동화 도구는 관리를 위한 복잡한 추가 작업이나 운영체제 버전에 따라 추가 패키지나 모듈을 설치하는 등의 작업이 발생한다
- 앤서블은 에이전트 설치 없이 SSH로 접속하여 쉽게 대상 서버들을 관리할 수 있다. 이것이 앤서블의 가장 큰 특징이자 장점이다.
- 멱등성(Idempotent)
- 멱등성은 동일한 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질이다. 앤서블은 이러한 멱등성과 함께 시스템을 원하는 상태로 표현하여 유지하도록 설계되어 있어, 동일한 운영 작업을 여러 번 실행해도 같은 결과를 낸다.
- 쉬운 사용법과 다양한 모듈 제공
- 다른 자동화 도구에 비해 복잡하지 않아 자동화 절차 및 과정을 이해하기 쉽다.
- YAML 문법을 사용하여 쉽게 작성하고 읽을 수 있다.
- 파일 복사와 같은 일반 시스템 관리 모듈부터 다양한 환경의 퍼블릭 클라우드 관련 모듈 및 컬렉션까지 제공하므로, 쉽게 플레이북 예제를 찾아보고 자동화를 수행할 수 있다.
앤서블 설치
MacOS
1
2
brew install ansible
ansible --version
- 앤서블이 자동으로 로그인하기 위해서 SSH키 구성 세팅
1
2
3
4
5
6
$PASSWORD=
$USERNMAE=
$IP=
# 현재 로컬에 가지고 있는 공개키를 원격 호스트로 복사
sshpass -p $PASSWORD ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $USERNAME$@$IP
호스트 선정
- 아래와 같이 IP 또는 호스트명을 포함하는 인벤토리 파일을 생성한다.
1
2
3
4
5
6
7
8
9
10
11
12
# 호스트명 사용시 /etc/hosts 파일 확인 후 수정
cat /etc/hosts
# inventory 파일 생성
cat <<EOT > inventory
10.10.1.11
10.10.1.12
10.10.1.13
tnode1
tnode2
tnode3
EOT
- inventory 검증하기
1
ansible-inventory -i ./inventory --list | jq
- 그룹별 호스트 설정
- 그룹별로 호스트를 설정하면 앤서플 플레이북 실행시 그룹별로 처리할 수 있다.
- 중첩그룹 :
:children이라는 접미사를 추가하여 중첩그룹을 생성- webservers 및 db-servers 그룹의 모든 호스트를 포함하는 datacenter 그룹을 생성하는 예
1
2
3
4
5
6
7
8
9
10
11
[webservers]
web1.example.com
web2.example.com
[db-servers]
db01.example.com
db02.example.com
[datacenter:children] # :children 이라는 접미사를 추가하여 중첩그룹을 생성
webservers
dbservers
- 범위를 사용한 호스트 사양 간소화
- webservers : web1.example.com / web2.example.com
- db-servers : db01.example.com / db02.example.com
1
2
3
4
5
[webservers]
web[1:2].example.com
[db-servers]
db[01:02].example.com
- 이외 범위 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# IP 범위 설정 : 192.168.4.0 ~ 192.168.4.255 사이의 IP 범위를 표현
[defaults]
192.168.4.[0:255]
# 호스트명 범위 설정 : com01.example.com ~ com20.example.com 의 범위를 표현
[compute]
com[01:20].example.com
# DNS 범위 설정 : a.dns.example.com , b.dns.example.com , c.dns.example.com 을 의미함
[dns]
[a:c].dns.example.com
# IPv6 범위 설정 : 2001:db08::a ~ 2001:db08::f 사이의 IPv6 범위를 표현
[ipv6]
2001:db8::[a:f]
- Ansible Configuration Settings
- 현재 프로젝트 디렉터리 내에 ansible.cfg 라는 앤서블 환경 설정 파일을 구성 시, -i 옵션을 사용하지 않아도 ansible.cfg 설정 파일에 정의된 인벤토리의 호스트 정보를 확인
1
2
3
4
5
# ansible.cfg 파일 생성
cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
EOT
- -i 옵션 없이 inventory 검증
1
ansible-inventory --list | jq - 앤서블 config 우선순위
ANSIBLE_CONFIG(environment variable if set)ansible.cfg(in the current directory)~/.ansible.cfg(in the home directory)/etc/ansible/ansible.cfg
플레이북 작성
- ansible.cfg 파일을 생성하여 다양한 앤서블 설정을 적용
1
2
3
4
5
6
7
8
9
10
[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
- defaults 섹션
- 앤서블 작업을 위한 기본값 설정
| 매개 변수 | 설명 |
|---|---|
| inventory | 인벤토리 파일의 경로를 지정함. |
| remote_user | 앤서블이 관리 호스트에 연결할 때 사용하는 사용자 이름을 지정함. 이때, 사용자 이름을 지정하지 않으면 현재 사용자 이름으로 지정됨. |
| ask_pass | SSH 암호를 묻는 메시지 표시 여부를 지정함. SSH 공개 키 인증을 사용하는 경우 기본값은 false임. |
- privilege_escalation
- 보안/감사로 인해 원격 호스트에 권한 없는 사용자 연결 후 관리 액세스 권한을 에스컬레이션하여 루트 사용자로 가져올 때
| 매개 변수 | 설명 |
|---|---|
| become | 기본적으로 권한 에스컬레이션을 활성화할 때 사용하며, 연결 후 관리 호스트에서 자동으로 사용자를 전환할지 여부를 지정함. 일반적으로 root로 전환되며, 플레이북에서도 지정할 수 있음. |
| become_method | 권한을 에스컬레이션하는 사용자 전환 방식을 의미함. 일반적으로 기본값은 sudo를 사용하며, su는 옵션으로 설정할 수 있음. |
| become_user | 관리 호스트에서 전환할 사용자를 지정함. 일반적으로 기본값은 root임. |
| become_ask_pass | become_method 매개 변수에 대한 암호를 묻는 메시지 표시 여부를 지정함. 기본값은 false임. 권한을 에스컬레이션하기 위해 사용자가 암호를 입력해야 하는 경우, 구성 파일에 become_ask_pass = true 매개 변수를 설정하면 됨. |
- 리눅스에서 기본적으로 SSH 프로토콜을 사용하여 관리 호스트에 연결
- 리 호스트에 연결하는 방법을 제어하는 가장 중요한 매개 변수는 defaults 섹션에 설정
- 다른 사용자를 지정하려면 remote_user 매개 변수를 사용하여 해당 사용자 이름으로 설정
- 별도로 설정되어 있지 않으면 앤서블은 실행 시 로컬 사용자와 같은 사용자 이름을 사용하여 관리 호스트에 연결
Ad hoc commnads
Ad-hoc 명령이란 /usr/bin/ansible 명령줄 도구를 사용하여 하나 이상의 관리 노드에서 단일 작업을 실행하는 가장 빠르고 간단한 방법이다. 플레이북(Playbook)처럼 재사용은 어렵지만, 단순하고 반복되지 않는 작업을 즉시 처리할 때 매우 유용하다.
- 기본 구조
1
ansible [호스트_패턴] -m [모듈명] -a "[모듈_옵션]"
ansible ping module
- ping 모듈을 이용하여 web 그룹의 호스트로 정상 연결(pong반환)이면 ‘SUCCESS’ 출력 ← icmp(ping) 아니며, python 테스트 모듈
1
ansible -m ping web
Python 인터프립터 변경 가능성 경고 문구 제거
- 명시적으로 python interpreter를 지정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# inventory 그룹 구성
cat <<EOT > inventory
[web]
tnode1 ansible_python_interpreter=/usr/bin/python3
tnode2 ansible_python_interpreter=/usr/bin/python3
[db]
tnode3 ansible_python_interpreter=/usr/bin/python3
[all:children]
web
db
EOT
ansible-inventory -i ./inventory --list | jq
ansible shell module
- shell은 노드들에 명령 구문을 전달하고 해당 결과를 반환하는 모듈
1
2
3
4
5
ansible -m shell -a uptime db
ansible -m shell -a "free -h" web
ansible -m shell -a "tail -n 3 /etc/passwd" all

