소개
이 랩에서는 원격 호스트에서 명령을 실행하기 위한 강력한 도구인 Ansible Command 모듈을 살펴봅니다. Command 모듈을 사용하면 Ansible 플레이북과 태스크에서 직접 명령줄과 상호 작용할 수 있어 원격 시스템을 관리하는 데 다재다능한 방법을 제공합니다. 이 랩을 통해 Ansible Command 모듈을 사용하여 다양한 명령을 실행하고, 변수와 인수를 사용하며, 명령 출력을 캡처하는 방법을 배우게 됩니다.
이 랩에서는 원격 호스트에서 명령을 실행하기 위한 강력한 도구인 Ansible Command 모듈을 살펴봅니다. Command 모듈을 사용하면 Ansible 플레이북과 태스크에서 직접 명령줄과 상호 작용할 수 있어 원격 시스템을 관리하는 데 다재다능한 방법을 제공합니다. 이 랩을 통해 Ansible Command 모듈을 사용하여 다양한 명령을 실행하고, 변수와 인수를 사용하며, 명령 출력을 캡처하는 방법을 배우게 됩니다.
이 단계에서는 Command 모듈을 사용하여 간단한 명령을 실행하는 첫 번째 Ansible 플레이북을 생성합니다.
먼저, 프로젝트 디렉토리로 이동합니다.
cd ~/project
이제 원하는 텍스트 편집기를 사용하여 simple_command.yml이라는 새 파일을 만듭니다. 예를 들어, nano 편집기를 사용할 수 있습니다.
nano simple_command.yml
다음 내용을 파일에 추가합니다.
---
- name: 간단한 명령 실행
hosts: localhost
tasks:
- name: 'ls' 명령 실행
command: ls -l
이 플레이북을 자세히 살펴보겠습니다.
hosts: localhost 줄은 플레이북이 로컬 머신에서 실행됨을 지정합니다.tasks 섹션에는 실행할 태스크 목록이 포함되어 있습니다.command: ls -l 줄은 Command 모듈을 사용하여 ls -l 명령을 실행합니다. 이 명령은 파일과 디렉토리를 자세한 형식으로 나열합니다.파일을 저장하고 편집기를 종료합니다 (nano 에서 Ctrl+X, Y, Enter 를 누릅니다).
이제 다음 명령으로 플레이북을 실행합니다.
ansible-playbook simple_command.yml
다음과 유사한 출력을 볼 수 있습니다.
PLAY [Execute a simple command] ************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Run 'ls' command] ********************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
이 출력은 플레이북이 성공적으로 실행되어 로컬 머신에서 ls -l 명령을 실행했음을 나타냅니다.
이 단계에서는 Ansible Command 모듈과 함께 변수를 사용하는 방법을 배웁니다. 변수를 사용하면 플레이북을 더욱 유연하고 재사용 가능하게 만들 수 있습니다.
variable_command.yml이라는 새 파일을 만듭니다.
nano variable_command.yml
다음 내용을 파일에 추가합니다.
---
- name: Command 모듈과 변수 사용
hosts: localhost
vars:
file_path: /etc/passwd
line_count: 5
tasks:
- name: 파일의 마지막 몇 줄 표시
command: "tail -n {{ line_count }} {{ file_path }}"
register: command_output
- name: 명령 출력 표시
debug:
var: command_output.stdout_lines
이 플레이북은 몇 가지 새로운 개념을 소개합니다.
vars 섹션은 플레이북 전체에서 사용할 수 있는 변수를 정의합니다.{{ variable_name }} 구문을 사용하여 명령 내에서 변수를 참조합니다.register 키워드는 명령의 출력을 command_output이라는 변수에 저장합니다.debug 모듈은 command_output 변수의 내용을 표시하는 데 사용됩니다.파일을 저장하고 편집기를 종료합니다.
이제 플레이북을 실행합니다.
ansible-playbook variable_command.yml
다음과 유사한 출력을 볼 수 있습니다.
PLAY [Use variables with the Command module] ***********************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Display the last few lines of a file] ************************************
changed: [localhost]
TASK [Show the command output] *************************************************
ok: [localhost] => {
"command_output.stdout_lines": [
"games:x:5:60:games:/usr/games:/usr/sbin/nologin",
"man:x:6:12:man:/var/cache/man:/usr/sbin/nologin",
"lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin",
"mail:x:8:8:mail:/var/mail:/usr/sbin/nologin",
"news:x:9:9:news:/var/spool/news:/usr/sbin/nologin"
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
이 출력은 /etc/passwd 파일의 마지막 5 줄을 보여주며, Command 모듈과 함께 변수를 사용하는 방법을 보여줍니다.
이 단계에서는 Ansible 을 사용하여 명령의 출력을 캡처하고 추가로 처리하는 방법을 배웁니다.
process_output.yml이라는 새 파일을 만듭니다.
nano process_output.yml
다음 내용을 파일에 추가합니다.
---
- name: 명령 출력 캡처 및 처리
hosts: localhost
tasks:
- name: 디스크 사용량 정보 가져오기
command: df -h
register: df_output
- name: 모든 파티션 표시
debug:
msg: "{{ df_output.stdout_lines }}"
- name: 루트 파티션 찾기
set_fact:
root_partition: "{{ df_output.stdout_lines | select('match', '\\s+/$') | first | default('') }}"
- name: 루트 파티션 정보 표시
debug:
msg: "루트 파티션: {{ root_partition }}"
when: root_partition != ''
- name: 사용률 백분율 추출
set_fact:
root_usage: "{{ root_partition.split()[-2].rstrip('%') | int }}"
when: root_partition != ''
- name: 루트 파티션 사용량 표시
debug:
msg: "루트 파티션 사용량은 {{ root_usage }}% 입니다"
when: root_partition != ''
- name: 루트 파티션이 80% 이상 찼는지 확인
fail:
msg: "경고: 루트 파티션이 80% 이상 찼습니다!"
when: root_partition != '' and root_usage > 80
- name: 루트 파티션을 찾을 수 없는 경우 메시지 표시
debug:
msg: "df 출력에서 루트 파티션 (/) 을 찾을 수 없습니다"
when: root_partition == ''
이 플레이북은 더 강력하며 루트 파티션을 쉽게 감지할 수 없는 경우를 처리합니다.
default('') 필터를 사용하여 루트 파티션을 찾을 수 없는 경우 오류를 방지합니다.파일을 저장하고 편집기를 종료합니다.
이제 플레이북을 실행합니다.
ansible-playbook process_output.yml
다음과 유사한 출력을 볼 수 있습니다.
PLAY [Capture and process command output] ************************************************
TASK [Gathering Facts] *******************************************************************
ok: [localhost]
TASK [Get disk usage information] ********************************************************
changed: [localhost]
TASK [Display all partitions] ************************************************************
ok: [localhost] => {
"msg": [
"Filesystem Size Used Avail Use% Mounted on",
"overlay 20G 618M 20G 4% /",
"tmpfs 64M 0 64M 0% /dev",
"tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup",
"shm 64M 128K 64M 1% /dev/shm",
"/dev/vdb 100G 17G 84G 17% /etc/hosts"
]
}
TASK [Find root partition] ***************************************************************
ok: [localhost]
TASK [Display root partition information] ************************************************
skipping: [localhost]
TASK [Extract usage percentage] **********************************************************
skipping: [localhost]
TASK [Display root partition usage] ******************************************************
skipping: [localhost]
TASK [Check if root partition is over 80% full] ******************************************
skipping: [localhost]
TASK [Display message if root partition not found] ***************************************
ok: [localhost] => {
"msg": "Root partition (/) not found in df output"
}
PLAY RECAP *******************************************************************************
localhost : ok=7 changed=1 unreachable=0 failed=1 skipped=1 rescued=0 ignored=0
이 출력은 모든 파티션을 표시하고, 루트 파티션을 식별하며, 사용량을 확인합니다. 정확한 값은 시스템에 따라 다를 수 있습니다.
이 단계에서는 Ansible Command 모듈의 동작을 제어하기 위해 사용할 수 있는 몇 가지 옵션을 살펴봅니다.
command_options.yml이라는 새 파일을 만듭니다.
nano command_options.yml
다음 내용을 파일에 추가합니다.
---
- name: Command 모듈 옵션 탐색
hosts: localhost
tasks:
- name: 특정 작업 디렉토리로 명령 실행
command: pwd
args:
chdir: /tmp
- name: 환경 변수를 사용하여 명령 실행
command: echo $MY_VAR
environment:
MY_VAR: "Hello from Ansible"
- name: 명령을 실행하고 오류 무시
command: ls /nonexistent_directory
ignore_errors: yes
- name: 타임아웃으로 명령 실행
command: sleep 2
async: 5
poll: 0
register: sleep_result
- name: sleep 명령 상태 확인
async_status:
jid: "{{ sleep_result.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 5
delay: 1
이 플레이북은 Command 모듈의 다양한 옵션을 보여줍니다.
chdir: 명령을 실행하기 전에 작업 디렉토리를 변경합니다.environment: 명령에 대한 환경 변수를 설정합니다.ignore_errors: 명령이 실패하더라도 플레이북 실행을 계속합니다.async 및 poll: 타임아웃과 함께 명령을 비동기적으로 실행합니다.파일을 저장하고 편집기를 종료합니다.
이제 플레이북을 실행합니다.
ansible-playbook command_options.yml
다음과 유사한 출력을 볼 수 있습니다.
PPLAY [Explore Command module options]
TASK [Gathering Facts]
ok: [localhost]
TASK [Run a command with a specific working directory]
changed: [localhost]
TASK [Run a command with environment variables]
changed: [localhost]
TASK [Run a command and ignore errors]
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/nonexistent_directory"], "delta": "0:00:00.006113", "end": "2024-09-06 09:40:43.373350", "msg": "non-zero return code", "rc": 2, "start": "2024-09-06 09:40:43.367237", "stderr": "ls: cannot access '/nonexistent_directory': No such file or directory", "stderr_lines": ["ls: cannot access '/nonexistent_directory': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Run a command with a timeout]
changed: [localhost]
TASK [Check sleep command status]
FAILED - RETRYING: Check sleep command status (10 retries left).
FAILED - RETRYING: Check sleep command status (9 retries left).
FAILED - RETRYING: Check sleep command status (8 retries left).
FAILED - RETRYING: Check sleep command status (7 retries left).
FAILED - RETRYING: Check sleep command status (6 retries left).
FAILED - RETRYING: Check sleep command status (5 retries left).
FAILED - RETRYING: Check sleep command status (4 retries left).
FAILED - RETRYING: Check sleep command status (3 retries left).
FAILED - RETRYING: Check sleep command status (2 retries left).
FAILED - RETRYING: Check sleep command status (1 retries left).
fatal: [localhost]: FAILED! => {"ansible_job_id": "5877920468.2517", "attempts": 10, "changed": false, "finished": 0, "started": 1}
PLAY RECAP
이 출력은 우리가 탐구한 Command 모듈 옵션의 다양한 동작을 보여줍니다.
이 마지막 단계에서는 Ansible Command 모듈을 보다 현실적인 Docker 친화적인 시나리오에서 사용합니다. 즉, SSH 서비스의 상태를 확인하고 필요한 경우 관리합니다.
check_service_docker.yml이라는 새 파일을 만듭니다.
nano check_service_docker.yml
다음 내용을 파일에 추가합니다.
---
- name: Docker 에서 SSH 서비스 확인 및 관리
hosts: localhost
become: yes ## Ansible 이 sudo 를 사용하도록 허용합니다.
tasks:
- name: SSH 서비스 상태 확인
command: service ssh status
register: ssh_status
ignore_errors: yes
- name: SSH 서비스 상태 표시
debug:
msg: "SSH 서비스 상태: {{ ssh_status.stdout }}"
- name: SSH 서비스가 실행 중이 아니면 시작
command: service ssh start
when: ssh_status.rc != 0
- name: SSH 서비스가 실행 중인지 확인
command: service ssh status
register: ssh_status_after
- name: 최종 SSH 서비스 상태 표시
debug:
msg: "SSH 서비스 상태는 이제: {{ ssh_status_after.stdout }}"
- name: SSH 포트가 수신 대기 중인지 확인
command: netstat -tuln | grep :22
register: ssh_port_check
ignore_errors: yes
- name: SSH 포트 상태 표시
debug:
msg: "SSH 포트 22 는 {{ 'open' if ssh_port_check.rc == 0 else 'closed' }}"
이 플레이북은 다음 작업을 수행합니다.
service 명령을 사용하여 SSH 서비스의 상태를 확인합니다.파일을 저장하고 편집기를 종료합니다.
이제 sudo 권한으로 플레이북을 실행합니다.
sudo ansible-playbook check_service_docker.yml
다음과 유사한 출력을 볼 수 있습니다.
PLAY [Check and manage SSH service in Docker] *****************************************
TASK [Gathering Facts] ****************************************************************
ok: [localhost]
TASK [Check SSH service status] *******************************************************
changed: [localhost]
TASK [Display SSH service status] *****************************************************
ok: [localhost] => {
"msg": "SSH service status: * sshd is running"
}
TASK [Start SSH service if not running] ***********************************************
skipping: [localhost]
TASK [Verify SSH service is running] **************************************************
changed: [localhost]
TASK [Display final SSH service status] ***********************************************
ok: [localhost] => {
"msg": "SSH service status is now: * sshd is running"
}
TASK [Check if SSH port is listening] *************************************************
changed: [localhost]
TASK [Display SSH port status] ********************************************************
ok: [localhost] => {
"msg": "SSH port 22 is open"
}
PLAY RECAP ****************************************************************************
localhost : ok=6 changed=3 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
이 출력은 SSH 서비스가 이미 실행 중이었으므로 시작할 필요가 없음을 보여줍니다. 플레이북은 서비스 상태를 성공적으로 확인하고 확인했으며, SSH 포트가 열려 있는지도 확인했습니다.
이 랩에서는 Ansible Command 모듈의 다재다능함과 강력함을 탐구했습니다. 다음을 수행하는 방법을 배웠습니다.
이러한 기술은 Ansible 을 사용하여 시스템 관리 작업을 자동화하고 원격 호스트를 효율적으로 관리하기 위한 견고한 기반을 형성합니다. Ansible 을 계속 사용하면서 Command 모듈이 자동화 도구 상자에서 다재다능한 도구임을 알게 될 것입니다.
Command 모듈이 강력하지만, 가용할 때는 특수 Ansible 모듈 (예: 서비스를 관리하기 위한 service 모듈) 을 사용하는 것이 더 좋습니다. 이러한 특수 모듈은 더 나은 멱등성을 제공하며 더 복잡한 시나리오를 즉시 처리할 수 있습니다.
자동화 기술을 더욱 향상시키고 IT 운영을 간소화하기 위해 Ansible 의 기능을 계속 연습하고 탐구하십시오.