Ansible Command 모듈

AnsibleBeginner
지금 연습하기

소개

이 랩에서는 원격 호스트에서 명령을 실행하기 위한 강력한 도구인 Ansible Command 모듈을 살펴봅니다. Command 모듈을 사용하면 Ansible 플레이북과 태스크에서 직접 명령줄과 상호 작용할 수 있어 원격 시스템을 관리하는 데 다재다능한 방법을 제공합니다. 이 랩을 통해 Ansible Command 모듈을 사용하여 다양한 명령을 실행하고, 변수와 인수를 사용하며, 명령 출력을 캡처하는 방법을 배우게 됩니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 99%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

간단한 Ansible 플레이북 생성

이 단계에서는 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 명령을 실행했음을 나타냅니다.

Command 모듈과 변수 사용

이 단계에서는 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

이 출력은 모든 파티션을 표시하고, 루트 파티션을 식별하며, 사용량을 확인합니다. 정확한 값은 시스템에 따라 다를 수 있습니다.

Command 모듈 옵션 사용

이 단계에서는 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: 명령이 실패하더라도 플레이북 실행을 계속합니다.
  • asyncpoll: 타임아웃과 함께 명령을 비동기적으로 실행합니다.

파일을 저장하고 편집기를 종료합니다.

이제 플레이북을 실행합니다.

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 모듈 옵션의 다양한 동작을 보여줍니다.

Docker 환경에서 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' }}"

이 플레이북은 다음 작업을 수행합니다.

  1. service 명령을 사용하여 SSH 서비스의 상태를 확인합니다.
  2. 서비스의 현재 상태를 표시합니다.
  3. 서비스가 실행 중이 아니면 시작합니다.
  4. 잠재적인 시작 후 서비스 상태를 확인합니다.
  5. 서비스의 최종 상태를 표시합니다.
  6. SSH 포트 (22) 가 수신 대기 중인지 확인합니다.
  7. 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 모듈의 다재다능함과 강력함을 탐구했습니다. 다음을 수행하는 방법을 배웠습니다.

  1. Command 모듈을 사용하여 기본 명령을 실행하는 간단한 Ansible 플레이북을 만듭니다.
  2. Command 모듈과 함께 변수를 사용하여 플레이북을 더욱 유연하고 재사용 가능하게 만듭니다.
  3. 명령 출력을 캡처하고 처리하여 명령 결과에 따라 결정을 내릴 수 있습니다.
  4. 디렉토리 변경, 환경 변수 설정 및 오류 처리와 같은 다양한 Command 모듈 옵션을 사용하여 동작을 제어합니다.
  5. 시스템 서비스를 확인하고 관리하여 실제 시나리오에서 Command 모듈을 적용합니다.

이러한 기술은 Ansible 을 사용하여 시스템 관리 작업을 자동화하고 원격 호스트를 효율적으로 관리하기 위한 견고한 기반을 형성합니다. Ansible 을 계속 사용하면서 Command 모듈이 자동화 도구 상자에서 다재다능한 도구임을 알게 될 것입니다.

Command 모듈이 강력하지만, 가용할 때는 특수 Ansible 모듈 (예: 서비스를 관리하기 위한 service 모듈) 을 사용하는 것이 더 좋습니다. 이러한 특수 모듈은 더 나은 멱등성을 제공하며 더 복잡한 시나리오를 즉시 처리할 수 있습니다.

자동화 기술을 더욱 향상시키고 IT 운영을 간소화하기 위해 Ansible 의 기능을 계속 연습하고 탐구하십시오.