[Ansible] Kubespray: Kubespray를 위한 Ansible 기초 - 3. Ad-hoc 명령어
서종호(가시다)님의 On-Premise K8s Hands-on Study 2주차 학습 내용을 기반으로 합니다.
TL;DR
이번 글의 목표는 Ansible 설정 파일 구성과 Ad-hoc 명령어 실행이다.
- 설정 파일(
ansible.cfg): 연결 사용자, 권한 상승, 설정 우선순위 - Ad-hoc 명령어: Playbook 없이 단일 명령을 즉시 실행하는 방법
- 주요 모듈:
ping,shell,command,copy,file등
Ansible 설정 파일
ansible.cfg 구조
ansible.cfg는 INI 형식으로 작성하며, 섹션별로 키-값 쌍으로 설정을 정의한다.
[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
[defaults] 섹션
Ansible 작업의 기본값을 설정한다.
| 매개변수 | 설명 |
|---|---|
inventory |
인벤토리 파일 경로 |
remote_user |
관리 호스트에 연결할 사용자. 미지정 시 현재 로컬 사용자 이름 사용 |
ask_pass |
SSH 암호 입력 프롬프트 표시 여부. SSH 키 인증 사용 시 false |
[privilege_escalation] 섹션
권한 상승(privilege escalation) 관련 설정이다. 일반 사용자로 접속 후 root 권한이 필요한 작업을 수행할 때 사용한다.
| 매개변수 | 설명 |
|---|---|
become |
권한 상승 활성화 여부. true면 연결 후 자동으로 지정된 사용자로 전환 |
become_method |
권한 상승 방식. sudo(기본값), su, pfexec, doas 등 |
become_user |
전환할 사용자. 기본값은 root |
become_ask_pass |
권한 상승 시 암호 입력 프롬프트 표시 여부 |
참고: become의 동작 원리
become = true로 설정하면 Ansible은 다음과 같이 동작한다:
remote_user로 SSH 접속become_method(예: sudo)를 사용해become_user(예: root)로 전환- 전환된 권한으로 작업 실행
이 방식은 root 직접 로그인을 피하고, 감사 로그를 남기며, 최소 권한 원칙을 따르기 위해 사용된다.
실습: 설정 파일 생성
# (server) #
cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT
# (server) #
cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
참고: 실습 환경에서의 설정
이 실습에서는
remote_user = root로 설정했다. 이는 실습 편의를 위한 것이며, 실제 운영 환경에서는 일반 사용자로 접속 후become을 통해 권한을 상승하는 방식을 권장한다.
설정 파일 우선순위
Ansible은 여러 위치에서 설정 파일을 찾으며, 다음 순서로 우선순위가 적용된다:
ANSIBLE_CONFIG환경변수로 지정된 파일- 현재 디렉터리의
ansible.cfg← 가장 많이 사용 - 홈 디렉터리의
~/.ansible.cfg /etc/ansible/ansible.cfg
현재 디렉터리에 ansible.cfg가 있으면 해당 설정이 우선 적용된다. 이것이 Kubespray 실행 시 특정 디렉터리에서 실행해야 하는 이유다. Kubespray는 자체 ansible.cfg를 포함하고 있어, 해당 디렉터리에서 실행해야 올바른 설정이 적용된다.
설정 확인 명령어
현재 적용된 Ansible 설정을 확인하려면 ansible-config 명령어를 사용한다.
# (server) #
# 현재 적용된 설정값 출력 (변경된 값만)
ansible-config dump --only-changed
# (server) #
# 사용 가능한 모든 설정 옵션 목록
ansible-config list
ansible-config dump: 현재 적용된 모든 설정값 출력.--only-changed옵션으로 기본값과 다른 설정만 확인ansible-config list: 사용 가능한 모든 설정 옵션과 설명 출력
Ad-hoc 명령어
개념
Ad-hoc 명령어는 Playbook 없이 단일 모듈을 즉시 실행하는 방법이다. 반복하지 않을 일회성 작업이나 빠른 확인 작업에 유용하다.
공식 문서에 따르면:
Ad hoc commands are great for tasks you repeat rarely. For example, if you want to power off all the machines in your lab for Christmas vacation, you could execute a quick one-liner in Ansible without writing a playbook.
기본 문법
ansible [pattern] -m [module] -a "[module options]"
| 요소 | 설명 |
|---|---|
pattern |
대상 호스트 또는 그룹 (예: all, web, tnode1) |
-m [module] |
실행할 모듈 이름 (기본값: command) |
-a "[options]" |
모듈에 전달할 인자 |
주요 옵션
| 옵션 | 설명 |
|---|---|
-m |
모듈 지정 |
-a |
모듈 인자 |
-i |
인벤토리 파일 지정 |
-f |
병렬 실행 프로세스 수 (기본값: 5) |
-u |
원격 사용자 지정 |
--become |
권한 상승 활성화 |
--ask-pass |
SSH 암호 입력 프롬프트 |
-C |
Check 모드 (실제 실행 없이 변경 사항만 확인) |
실습
ping 모듈
ping 모듈은 Ansible이 관리 호스트에 연결하고 Python을 실행할 수 있는지 확인한다.
주의: Ansible의
ping은 ICMP ping이 아니다. SSH 연결 + Python 실행 가능 여부를 테스트하는 모듈이다.
# (server) #
ansible -m ping web
tnode1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
tnode2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
SUCCESS: 연결 성공"ping": "pong": 정상 응답"changed": false: 호스트에 변경 사항 없음
Python 인터프리터 경고 해결
처음 실행 시 다음과 같은 경고가 나타날 수 있다:
[WARNING]: Host 'tnode1' is using the discovered Python interpreter at
'/usr/bin/python3.12', but future installation of another Python interpreter
could cause a different interpreter to be discovered.
이 경고는 Ansible이 Python 인터프리터를 자동 탐지(auto)했음을 알려준다. 명시적으로 지정하면 경고가 사라진다.
# (server) #
# 인벤토리에 Python 인터프리터 명시
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
경고 없이 실행됨:
# (server) #
ansible -m ping web
tnode1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
tnode2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
암호 입력 모드
--ask-pass 옵션을 사용하면 SSH 암호를 대화형으로 입력할 수 있다.
# (server) #
ansible -m ping --ask-pass web
SSH password:
tnode1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
tnode2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
참고: 실습 환경 설정에서 root 계정의 비밀번호를
qwe123으로 설정했기 때문에 암호 입력으로도 접속이 가능하다. SSH 키 인증이 설정되어 있으면--ask-pass없이도 접속된다.
shell 모듈
shell 모듈은 관리 호스트에서 셸 명령을 실행하고 결과를 반환한다. 파이프(|), 리다이렉션(>), 환경변수 등 셸 기능을 사용할 수 있다.
# (server) #
ansible -m shell -a "uptime" db
tnode3 | CHANGED | rc=0 >>
21:53:50 up 2:39, 1 user, load average: 0.06, 0.03, 0.00
출력 해석:
tnode3: 실행 대상 호스트CHANGED: 명령이 실행됨 (shell/command 모듈은 항상 CHANGED 반환)rc=0: Return Code. 0은 성공, 0이 아니면 실패>>이후: 명령 실행 결과
참고:
uptime명령어시스템 가동 시간, 현재 로그인 사용자 수, 시스템 부하 평균을 출력한다.
21:53:50: 현재 시간up 2:39: 시스템 가동 시간 (2시간 39분)1 user: 현재 로그인한 사용자 수load average: 0.06, 0.03, 0.00: 1분, 5분, 15분 평균 부하
다른 셸 명령도 실행해 보자:
# (server) #
ansible -m shell -a "tail -n 3 /etc/passwd" all
tnode3 | CHANGED | rc=0 >>
tcpdump:x:72:72::/:/sbin/nologin
vagrant:x:1000:1000::/home/vagrant:/bin/bash
vboxadd:x:991:1::/var/run/vboxadd:/bin/false
tnode1 | CHANGED | rc=0 >>
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
tnode2 | CHANGED | rc=0 >>
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
참고:
/etc/passwd파일Linux 사용자 계정 정보가 저장된 파일이다. 각 줄은
사용자명:x:UID:GID:설명:홈디렉터리:셸형식이다.
vagrant:x:1000:1000::/home/vagrant:/bin/bash: vagrant 사용자, UID/GID 1000, bash 셸 사용vboxadd: VirtualBox Guest Additions 관련 시스템 계정
command vs shell 모듈
| 모듈 | 특징 |
|---|---|
command |
기본 모듈. 셸을 거치지 않고 직접 실행. 파이프, 리다이렉션 불가 |
shell |
/bin/sh를 통해 실행. 셸 문법(파이프, 변수 등) 사용 가능 |
# command 모듈 (기본값, -m 생략 가능)
ansible -a "hostname" all
# shell 모듈 (셸 기능 필요 시)
ansible -m shell -a "echo $HOSTNAME | tr 'a-z' 'A-Z'" all
기타 유용한 모듈
copy 모듈 - 파일 복사
# 파일을 모든 호스트에 복사
ansible -m copy -a "src=/etc/hosts dest=/tmp/hosts" all
file 모듈 - 파일/디렉터리 관리
# 디렉터리 생성
ansible -m file -a "dest=/tmp/testdir state=directory mode=755" all
# 파일 삭제
ansible -m file -a "dest=/tmp/testdir state=absent" all
setup 모듈 - 시스템 정보 수집
# 모든 시스템 정보 (Facts) 수집
ansible -m setup all
# 특정 정보만 필터링
ansible -m setup -a "filter=ansible_distribution*" all
출력 색상의 의미

Ansible 실행 결과는 상태에 따라 다른 색상으로 표시된다:
| 색상 | 상태 | 의미 |
|---|---|---|
| 초록색 | SUCCESS / ok | 성공, 변경 없음 |
| 주황색 | CHANGED | 성공, 변경 있음 |
| 빨간색 | FAILED | 실패 |
| 파란색 | SKIPPED | 조건 불충족으로 건너뜀 |
shell 모듈과 멱등성
Ansible 개요 글에서 멱등성에 대해 살펴볼 때, shell 모듈은 멱등성이 보장되지 않는 대표적인 모듈이라고 했다. 실제로 위 실습에서 uptime이나 tail 명령은 시스템에 아무런 변경을 가하지 않았음에도 결과가 모두 CHANGED로 표시된다.

이유: shell과 command 모듈은 Ansible이 명령 실행 전후의 시스템 상태를 비교할 방법이 없다. 단순히 “명령이 실행되었다”는 사실만 알 수 있으므로, 항상 CHANGED를 반환한다.
반면, apt, copy, file 같은 모듈은 현재 상태를 확인한 후 필요한 경우에만 변경을 수행하므로 멱등성이 보장된다:
- 이미 설치된 패키지 →
ok(변경 없음) - 동일한 파일이 존재 →
ok(변경 없음) - 변경이 필요한 경우만 →
CHANGED
결과
이 글을 완료하면 다음과 같은 결과를 얻을 수 있다:
- 설정 파일 이해:
ansible.cfg의 섹션 구성과 설정 우선순위 - Ad-hoc 명령어: Playbook 없이 단일 모듈을 즉시 실행하는 방법
- 주요 모듈 사용:
ping,shell,copy,file등 기본 모듈 활용 - 출력 해석: 색상별 상태와 반환 코드의 의미
Ad-hoc 명령어는 빠른 확인이나 일회성 작업에 유용하지만, 반복적인 작업은 Playbook으로 작성하는 것이 좋다. Playbook은 작업을 문서화하고, 버전 관리가 가능하며, 재사용할 수 있다.
다음 글에서는 Playbook을 작성하여 여러 작업을 순차적으로 실행하는 방법을 알아본다.
댓글남기기