노드 구성
192.168.100.120 control
192.168.100.121 node1
192.168.100.122 node2
192.168.100.123 node3
192.168.100.124 node4
192.168.100.125 node5
192.168.100.126 utility
모든 노드에 아래 사항 설정
192.168.100.120 control
192.168.100.121 node1
192.168.100.122 node2
192.168.100.123 node3
192.168.100.124 node4
192.168.100.125 node5
192.168.100.126 utility
# echo "admin ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/admin
# hostnamectl set-hostname node1
! playbook 작성 시 유의사항 : 들여쓰기 !
1. Ansible 설치 및 구성
제어 노드 control에서 에 Ansible을 다음과 같이 구성하시오. 필요한 패키지를 설치합니다. /home/admin/ansible/inventory라는 정적 인벤토리 파일을 생성하고 다음과 같이 구성합니다.
node1은 dev 호스트 그룹의 구성원입니다.
node2는 test 호스트 그룹의 구성원입니다.
node3 및 node4는 prod 호스트 그룹의 구성원입니다.
node5는 balancers 호스트 그룹의 구성원입니다.
prod 그룹은 webservers 호스트 그룹의 구성원입니다.
구성 파일 /home/admin/ansible/ansible.cfg 을 생성하고 다음과 같이 구성합니다.
호스트 인벤토리 파일은 /home/admin/ansible/inventory 입니다.
본 컨텐츠 컬렉션 디렉토리는 /home/admin/ansible/roles 입니다.
기본 컨텐츠 컬렉션 디렉토리는 /home/admin/ansible/mycollection 입니다.
-- utility 서버에서 control 서버로 접속
# ssh admin@192.168.100.120
-- ansible 패키지 설치
$ sudo dnf -y install ansible*
-- 문제에서 요구한 디렉토리 생성
$ mkdir -p /home/admin/ansible/roles
$ mkdir -p /home/admin/ansible/mycollection
$ cd ansible
-- 구성파일 생성
$ ansible-config init --disabled > /home/admin/ansible/ansible.cfg
$ vi ansible.cfg
=======================================================================================
[defaults]
inventory = /home/admin/ansible/inventory
remote_user = admin
host_key_checking = False
roles_path = /home/admin/ansible/roles:/usr/share/ansible/roles
collections_path = ./mycollection/:.ansible/collections:/usr/share/ansible/collections
[privilege_escalation]
become=True
:wq!
=======================================================================================
-- 구성파일 확인
$ ansible --version
$ ansible-galaxy list
-- inventory파일 생성
$ vi /home/admin/ansible/inventory
=======================================================================================
[dev]
node1
[test]
node2
[prod]
node3
node4
[balancers]
node5
[webservers:children]
prod
:wq!
=======================================================================================
-- inventory 확인
$ ansible-inventory --graph
-- ping 테스트
$ ansible all -m ping
ping 테스트 성공 시 출력 화면
참고) 시험과정에 ansible-navigator 사용 가능 ansible-navigator 사용 시 podman 미리 로그인해보기
$ podman login utility.lab.example.com -u admin -p redhat
ansible-navigator images
ansible-navigator collections
2. YUM 저장소 생성
시스템 관리자로서 관리 대상 노드에 소프트웨어를 설치해야 합니다. 다음 작업을 수행하는 /home/admin/ansible/yum_repo.yml 플레이북을 생성하세요.
각 관리되는 노드에 다음 yum 저장소를 만듭니다. 저장소 1 구성:
file: EX294_BASE
name: EX294_BASE
description: "EX294 base software"
baseurl: file:///repository/BaseOS
gpgcheck: yes
gpgkey: file:///repository/RPM-GPG-KEY-redhat-release
enabled: yes
저장소 2 구성:
file: EX294_STREAM
name: EX294_STREAM
description: "EX294 stream software"
baseurl: file:///repository/AppStream
gpgcheck: yes
gpgkey: file:///repository/RPM-GPG-KEY-redhat-release
enabled: yes
시험에서는 http:// 경로로 주어지지만 실습을 위해 로컬 리포지토리 경로인 ftp:///로 변형했음.
-- 모듈명 검색
$ ansible-doc -l | grep yum
-- doc
$ ansible-doc yum_repository
-- playbook
$ vi /home/admin/ansible/yum_repo.yml
================================================================================
- name: Configure YUM repositories
hosts: all
tasks:
- name: Configure EX294_BASE repository
yum_repository:
file: EX294_BASE
name: EX294_BASE
description: "EX294 base software"
baseurl: file:///repository/BaseOS
gpgcheck: yes
gpgkey: file:///repository/RPM-GPG-KEY-redhat-release
enabled: yes
- name: Configure EX294_STREAM repository
yum_repository:
file: EX294_STREAM
name: EX294_STREAM
description: "EX294 stream software"
baseurl: file:///repository/AppStream
gpgcheck: yes
gpgkey: file:///repository/RPM-GPG-KEY-redhat-release
enabled: yes
:wq!
================================================================================
-- playbook실행
$ ansible-playbook yum_repo.yml
-- 검증
$ ansible all -a 'yum repoinfo'
$ ansible all -a 'yum -y install ftp'
$ ansible all -a 'rpm -q ftp'
검증 로그
더보기
$ ansible all -a 'yum repoinfo' node5 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Repo-id : EX294_BASE Repo-name : EX294 base software Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 08:25:21 AM KST) Repo-filename : /etc/yum.repos.d/EX294_BASE.repo Repo-id : EX294_STREAM Repo-name : EX294 stream software Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 08:25:21 AM KST) Repo-filename : /etc/yum.repos.d/EX294_STREAM.repo Repo-id : InstallMedia-AppStream Repo-name : RHEL 9 - AppStream Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream/ Repo-expire : Never (last: Thu 17 Apr 2025 08:25:21 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Repo-id : InstallMedia-BaseOS Repo-name : RHEL 9 - BaseOS Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : Never (last: Thu 17 Apr 2025 08:25:21 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Total packages: 14,238Last metadata expiration check: 2:44:59 ago on Thu 17 Apr 2025 08:25:21 AM KST. node3 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Repo-id : EX294_BASE Repo-name : EX294 base software Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:30:26 AM KST) Repo-filename : /etc/yum.repos.d/EX294_BASE.repo Repo-id : EX294_STREAM Repo-name : EX294 stream software Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:30:26 AM KST) Repo-filename : /etc/yum.repos.d/EX294_STREAM.repo Repo-id : InstallMedia-AppStream Repo-name : RHEL 9 - AppStream Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream/ Repo-expire : Never (last: Thu 17 Apr 2025 09:30:26 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Repo-id : InstallMedia-BaseOS Repo-name : RHEL 9 - BaseOS Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : Never (last: Thu 17 Apr 2025 09:30:26 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Total packages: 14,238Last metadata expiration check: 1:39:54 ago on Thu 17 Apr 2025 09:30:26 AM KST. node2 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Repo-id : EX294_BASE Repo-name : EX294 base software Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 11:01:08 AM KST) Repo-filename : /etc/yum.repos.d/EX294_BASE.repo Repo-id : EX294_STREAM Repo-name : EX294 stream software Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 11:01:08 AM KST) Repo-filename : /etc/yum.repos.d/EX294_STREAM.repo Repo-id : InstallMedia-AppStream Repo-name : RHEL 9 - AppStream Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream/ Repo-expire : Never (last: Thu 17 Apr 2025 11:01:08 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Repo-id : InstallMedia-BaseOS Repo-name : RHEL 9 - BaseOS Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : Never (last: Thu 17 Apr 2025 11:01:08 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Total packages: 14,238Last metadata expiration check: 0:09:12 ago on Thu 17 Apr 2025 11:01:08 AM KST. node4 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Repo-id : EX294_BASE Repo-name : EX294 base software Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:18:26 AM KST) Repo-filename : /etc/yum.repos.d/EX294_BASE.repo Repo-id : EX294_STREAM Repo-name : EX294 stream software Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:18:26 AM KST) Repo-filename : /etc/yum.repos.d/EX294_STREAM.repo Repo-id : InstallMedia-AppStream Repo-name : RHEL 9 - AppStream Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream/ Repo-expire : Never (last: Thu 17 Apr 2025 09:18:26 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Repo-id : InstallMedia-BaseOS Repo-name : RHEL 9 - BaseOS Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : Never (last: Thu 17 Apr 2025 09:18:26 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Total packages: 14,238Last metadata expiration check: 1:51:54 ago on Thu 17 Apr 2025 09:18:26 AM KST. node1 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Repo-id : EX294_BASE Repo-name : EX294 base software Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:14:02 AM KST) Repo-filename : /etc/yum.repos.d/EX294_BASE.repo Repo-id : EX294_STREAM Repo-name : EX294 stream software Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream Repo-expire : 172,800 second(s) (last: Thu 17 Apr 2025 09:14:02 AM KST) Repo-filename : /etc/yum.repos.d/EX294_STREAM.repo Repo-id : InstallMedia-AppStream Repo-name : RHEL 9 - AppStream Repo-revision : 1728462055 Repo-updated : Wed 09 Oct 2024 05:20:55 PM KST Repo-pkgs : 5,947 Repo-available-pkgs: 5,679 Repo-size : 8.6 G Repo-baseurl : file:///repository/AppStream/ Repo-expire : Never (last: Thu 17 Apr 2025 09:14:02 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Repo-id : InstallMedia-BaseOS Repo-name : RHEL 9 - BaseOS Repo-revision : 1728462076 Repo-updated : Wed 09 Oct 2024 05:21:16 PM KST Repo-pkgs : 1,172 Repo-available-pkgs: 1,172 Repo-size : 1.3 G Repo-baseurl : file:///repository/BaseOS Repo-expire : Never (last: Thu 17 Apr 2025 09:14:02 AM KST) Repo-filename : /etc/yum.repos.d/RHEL9.repo Total packages: 14,238Last metadata expiration check: 1:56:18 ago on Thu 17 Apr 2025 09:14:02 AM KST.
$ ansible all -a 'yum -y install ftp' node2 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 0:10:49 ago on Thu 17 Apr 2025 11:01:08 AM KST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ftp x86_64 0.17-89.el9 EX294_STREAM 64 k Transaction Summary ================================================================================ Install 1 Package Total size: 64 k Installed size: 112 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : ftp-0.17-89.el9.x86_64 1/1 Running scriptlet: ftp-0.17-89.el9.x86_64 1/1 Verifying : ftp-0.17-89.el9.x86_64 1/1 Installed products updated. Installed: ftp-0.17-89.el9.x86_64 Complete! node4 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 1:53:31 ago on Thu 17 Apr 2025 09:18:26 AM KST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ftp x86_64 0.17-89.el9 EX294_STREAM 64 k Transaction Summary ================================================================================ Install 1 Package Total size: 64 k Installed size: 112 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : ftp-0.17-89.el9.x86_64 1/1 Running scriptlet: ftp-0.17-89.el9.x86_64 1/1 Verifying : ftp-0.17-89.el9.x86_64 1/1 Installed products updated. Installed: ftp-0.17-89.el9.x86_64 Complete! node3 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 1:41:31 ago on Thu 17 Apr 2025 09:30:26 AM KST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ftp x86_64 0.17-89.el9 EX294_STREAM 64 k Transaction Summary ================================================================================ Install 1 Package Total size: 64 k Installed size: 112 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : ftp-0.17-89.el9.x86_64 1/1 Running scriptlet: ftp-0.17-89.el9.x86_64 1/1 Verifying : ftp-0.17-89.el9.x86_64 1/1 Installed products updated. Installed: ftp-0.17-89.el9.x86_64 Complete! node1 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 1:57:55 ago on Thu 17 Apr 2025 09:14:02 AM KST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ftp x86_64 0.17-89.el9 EX294_STREAM 64 k Transaction Summary ================================================================================ Install 1 Package Total size: 64 k Installed size: 112 k Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : ftp-0.17-89.el9.x86_64 1/1 Running scriptlet: ftp-0.17-89.el9.x86_64 1/1 Verifying : ftp-0.17-89.el9.x86_64 1/1 Installed products updated. Installed: ftp-0.17-89.el9.x86_64 Complete! node5 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 2:46:36 ago on Thu 17 Apr 2025 08:25:21 AM KST. Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ftp x86_64 0.17-89.el9 EX294_STREAM 64 k Transaction Summary ================================================================================ Install 1 Package Total size: 64 k Installed size: 112 k Downloading Packages: EX294 stream software 3.5 MB/s | 3.6 kB 00:00 Key imported successfully Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : ftp-0.17-89.el9.x86_64 1/1 Running scriptlet: ftp-0.17-89.el9.x86_64 1/1 Verifying : ftp-0.17-89.el9.x86_64 1/1 Installed products updated. Installed: ftp-0.17-89.el9.x86_64 Complete!Importing GPG key 0xFD431D51: Userid : "Red Hat, Inc. (release key 2) <security@redhat.com>" Fingerprint: 567E 347A D004 4ADE 55BA 8A5F 199E 2F91 FD43 1D51 From : /repository/RPM-GPG-KEY-redhat-release Importing GPG key 0x5A6340B3: Userid : "Red Hat, Inc. (auxiliary key 3) <security@redhat.com>" Fingerprint: 7E46 2425 8C40 6535 D56D 6F13 5054 E4A4 5A63 40B3 From : /repository/RPM-GPG-KEY-redhat-release
$ ansible all -a 'rpm -q ftp' node5 | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 node2 | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 node3 | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 node1 | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 node4 | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64
3. 패키지 설치
다음 요구 사항에 따라 /home/admin/ansible/packages.yml 플레이북을 생성하고 관리 대상 노드에 소프트웨어 패키지를 설치하세요.
php와 mariadb 패키지를 dev, test, prod 호스트 그룹의 노드에 설치합니다.
RPM Development Tools 패키지 그룹을 dev 호스트 그룹의 노드에 설치합니다.
dev 호스트 그룹의 모든 패키지를 최신 버전 으로 업데이트합니다.
$ vi /home/admin/ansible/packages.yml
======================================================================================
- name: 1. install packages
hosts: dev,test,prod
tasks:
- name: STEP1-1. install php mariadb
yum:
name:
- php
- mariadb-server
state: present
- name: 2. install dev Packages
hosts: dev
tasks:
- name: STEP2-1. install dev packages
yum:
name: "@RPM Development Tools"
state: present
- name: STEP2-2. update all Packages
yum:
name: "*"
state: latest
:wq!
======================================================================================
$ ansible-playbook packages.yml
PLAY [1. install package] **********************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [node3]
ok: [node4]
ok: [node2]
ok: [node1]
TASK [1-1. yum php, mariadb] *******************************************************************************************************************
ok: [node2]
ok: [node3]
ok: [node4]
ok: [node1]
PLAY [2. install RPM development] **************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [node1]
TASK [2-1. install RPM] ************************************************************************************************************************
ok: [node1]
TASK [2-2. upgrade] ****************************************************************************************************************************
ok: [node1]
PLAY RECAP *************************************************************************************************************************************
node1 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node4 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-- 검증
$ ansible dev,test,prod -a 'rpm -q php mariadb'
$ ansible dev -a 'yum grouplist'
$ ansible dev -a 'yum update'
검증 로그
더보기
$ ansible dev,test,prod -a 'rpm -q php mariadb' node1 | CHANGED | rc=0 >> php-8.0.30-1.el9_2.x86_64 mariadb-10.5.22-1.el9_2.x86_64 node3 | CHANGED | rc=0 >> php-8.0.30-1.el9_2.x86_64 mariadb-10.5.22-1.el9_2.x86_64 node2 | CHANGED | rc=0 >> php-8.0.30-1.el9_2.x86_64 mariadb-10.5.22-1.el9_2.x86_64 node4 | CHANGED | rc=0 >> php-8.0.30-1.el9_2.x86_64 mariadb-10.5.22-1.el9_2.x86_64 $ ansible dev -a 'yum grouplist' node1 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 1:51:14 ago on Thu 17 Apr 2025 09:14:02 AM KST. Available Environment Groups: Server Minimal Install Workstation Custom Operating System Virtualization Host Installed Environment Groups: Server with GUI Installed Groups: Container Management Development Tools Headless Management Network Servers RPM Development Tools System Tools Available Groups: Legacy UNIX Compatibility Console Internet Tools .NET Development Graphical Administration Tools Scientific Support Security Tools Smart Card Support $ ansible dev -a 'yum update' node1 | CHANGED | rc=0 >> Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use "rhc" or "subscription-manager" to register. Last metadata expiration check: 1:51:00 ago on Thu 17 Apr 2025 09:14:02 AM KST. Dependencies resolved. Nothing to do. Complete!
4. RHEL 시스템 역할(ROLE) 사용하기
다음 요구 사항을 충족하는 /home/admin/ansible/selinux.yml 플레이북을 작성하세요:
모든 관리 대상 노드에서 실행됩니다.
selinux role을 사용합니다.
SElinux 정책을 targeted 으로 구성합니다.
SElinux 상태를 enforcing 으로 설정합니다.
-- rhel-system-roles 패키지 설치
$ sudo dnf -y install rhel-system-roles
-- 패키지 정상 설치 확인
$ ansible-galaxy list
-- playbook 작성
$ vi /home/admin/ansible/selinux.yml
======================================================================================
- hosts: all
become: true
vars:
- selinux_policy: targeted
- selinux_state: enforcing
roles:
- rhel-system-roles.selinux
:wq!
======================================================================================
-- playbook 실행
$ ansible-playbook selinux.yml
-- 검증
$ ansible all -m shell -a 'grep ^SELINUX= /etc/selinux/config; getenforce'
5. Collection 설치
다음 컬렉션 아티팩트를 http://classroom/materials/ 에서 가져와 control 노드에 설치하십시오.
redhat-insights-1.0.7.tar.gz
community-general-5.5.0.tar.gz
redhat-rhel_system_roles-1.19.3.tar.gz
컬렉션은 기본 컬렉션 디렉토리인 /home/admin/ansible/mycollection 에 설치해야 합니다.
파일을 구해서 직접 /home/admin/ansible/mycollection에 넣고 진행하였음.
-- 문제에서 명시된 기본 디렉터리로 컬렉션 압축파일 가져오기
$ cd /home/admin/ansible/mycollection
$ wget http://classroom/materials/redhat-insights-1.0.7.tar.gz
$ wget http://classroom/materials/community-general-5.5.0.tar.gz
$ wget http://classroom/materials/redhat-rhel_system_roles-1.19.3.tar.gz
-- 컬렉션 요구사항 작성
$ vi requirements.yml
======================================================================================
collections:
- name: /home/admin/ansible/mycollection/redhat-insights-1.0.7.tar.gz
- name: /home/admin/ansible/mycollection/community-general-5.5.0.tar.gz
- name: /home/admin/ansible/mycollection/redhat-rhel_system_roles-1.19.3.tar.gz
:wq!
======================================================================================
-- 컬렉션 설치
$ ansible-galaxy collection install -r requirements.yml -p /home/admin/ansible/mycollection
-- 설치 검증
$ ansible-galaxy collection list
검증 로그
더보기
$ ansible-galaxy collection list # /usr/share/ansible/collections/ansible_collections Collection Version ------------------------ ------- freeipa.ansible_freeipa 1.13.2 microsoft.sql 2.2.3 redhat.rhel_metrics 2.3.0 redhat.rhel_mgmt 1.1.0 redhat.rhel_system_roles 1.88.9 # /home/admin/ansible/mycollection/ansible_collections Collection Version ------------------------ ------- community.general 5.5.0 redhat.insights 1.0.7 redhat.rhel_system_roles 1.19.3
5-2. NTP 및 Timezone 설정
redhat system role 인 timesync role을 사용한다. 아래 설정을 가지는 /home/admin/ansible/timesync.yml 이라는 플레이 북을 만듭니다.
모든 관리 호스트에서 실행 (Clients 를 의미)
timesync role 을 사용
time server 192.168.100.120을 사용하도록 role 구성
iburst 매개 변수를 활성화 하도록 역할 구성
timezone은 Asia/Seoul 로 구성
community.general 컬렉션 설치 필요
- name: Setting timezone
hosts: all
vars:
timesync_ntp_servers:
- hostname: 192.168.100.101
iburst: true
roles:
- rhel-system-roles.timesync
tasks:
- name: Setting Timezone
timezone:
name: Asia/Seoul
6. Ansible Galaxy를 사용하여 역할 설치하기
Ansible Galaxy와 요구사항 파일 (/home/admin/ansible/roles/requirements.yml )을 사용하여 다음 URL에서 역할을 다운로드하고 /home/admin/ansible/roles 디렉토리에 설치하세요:
URL: https://github.com/geerlingguy/ansible-role-haproxy , 이 역할의 이름은 balancer여야 합니다.
URL: https://github.com/geerlingguy/ansible-role-php , 이 역할의 이름은 phpinfo여야 합니다.
파일을 구할 수 없어 github로 대체해서 테스트
$ vi /home/admin/ansible/roles/requirements.yml
======================================================================================
- src: https://github.com/geerlingguy/ansible-role-haproxy
name: balancer
- src: https://github.com/geerlingguy/ansible-role-php
name: phpinfo
:wq!
======================================================================================
-- install
$ ansible-galaxy role install -r /home/admin/ansible/roles/requirements.yml -p /home/admin/ansible/roles
-- 검증
$ ansible-galaxy list
검증 로그
더보기
$ ansible-galaxy list # /home/admin/ansible/roles - apache, (unknown version) - balancer, (unknown version) - phpinfo, (unknown version) # /usr/share/ansible/roles - ipabackup, (unknown version) - ipaclient, (unknown version) - ipareplica, (unknown version)
...
7. ROLE 생성 및 사용하기
다음 요구 사항에 맞춰 /home/admin/ansible/roles 디렉토리에 apache 라는 역할을 생성하고 아래 조건을 만족해야 합니다:
httpd 소프트웨어 패키지가 설치되고, 시스템 시작 시 활성화 및 시작 상태여야 합니다.
방화벽이 활성화되어 실행 중이어야 하며, 웹 서버 접근을 허용하는 규칙을 사용해야 합니다.
index.html.j2 템플릿 파일이 존재하며, 이 파일을 사용해 다음과 같은 출력 파일을 생성해야 합니다:
/var/www/html/index.html
Welcome to HOSTNAME on IPADDRESS
여기서, HOSTNAME은 관리 대상 노드의 완전한 도메인 이름(FQDN)이고, IPADDRESS는 관리 대상 노드의 IP 주소입니다.
/home/admin/ansible/apache.yml 라는 이름의 플레이북을 생성합니다:
이 플레이북은 webservers 호스트 그룹의 노드에서 실행되며, apache 역할을 사용합니다.
firewalld 를 사용하기 위해선 ansible.posix 컬렉션 설치가 필요함. $ sudo ansible-galaxy collection install ansible.posix 시험 환경에선 필요한 컬렉션이 모두 설치되어 있음.
-- apache role 생성
$ ansible-galaxy role init --init-path /home/admin/ansible/roles apache
-> roles 밑에 apache 디렉토리가 생성됨
-- task 작성(./apache/tasks/main.yml 파일 이미 존재)
$ vi /home/admin/ansible/roles/apache/tasks/main.yml
======================================================================================
- name: Install Apache
yum:
name: httpd
state: latest
- name: Start and enable Apache service
systemd:
name: httpd
state: started
enabled: yes
- name: Start and enable firewalld
systemd:
name: firewalld
state: started
enabled: yes
- name: Configure firewalld to allow HTTP
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
- name: Deploy index.html template
template:
src: index.html.j2
dest: /var/www/html/index.html
======================================================================================
$ vi /home/admin/ansible/roles/apache/templates/index.html.j2
======================================================================================
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}
======================================================================================
-- playbook 작성
$ vi /home/admin/ansible/apache.yml
======================================================================================
- name: Deploy Apache role
hosts: webservers
roles:
- apache
======================================================================================
-- playbook 실행
$ ansible-playbook apache.yml
-- 검증
$ ansible webservers -a 'systemctl status httpd'
$ ansible webservers -a 'firewall-cmd --list-all'
$ ansible webservers --list-hosts
$ curl http://node3
$ curl http://node4
8. Ansible Galaxy에서 ROLE 사용하기
다음 요구 사항에 맞춰 /home/admin/ansible/roles.yml 플레이북을 생성하세요:
playbook에 하나의 플레이가 포함되어야 하며, 이 플레이는 balancers 호스트 그룹의 노드에서 실행되며 balancer 역할을 사용합니다.
이 역할은 webservers 호스트 그룹의 노드 간에 웹 서버 요청의 부하를 균형 맞추는 서비스를 구성합니다.
balancers 호스트 그룹의 노드(예: http://192.168.100.125 )에 접속하면 아래와 같은 출력이 생성됩니다: Welcome to node3.lab.example.com on 192.168.100.123
브라우저를 새로 고침하면 다른 웹 서버에서 아래와 같은 출력이 생성됩니다: Welcome to node4.lab.example.com on 192.168.100.124
playbook에 또 다른 플레이가 포함되어야 하며, 이 플레이는 webservers 호스트 그룹의 노드에서 실행되며 phpinfo 역할을 사용합니다.
webservers 호스트 그룹의 노드에서 /hello.php URL로 접속하면 아래와 같은 출력이 생성됩니다: Hello PHP World from FQDN
여기서 FQDN은 해당 노드의 완전한 도메인 이름입니다.
예시 출력: Hello PHP World from node3.lab.example.com 또한 설치된 PHP 버전 등 PHP 구성의 다양한 세부 정보도 표시됩니다.
http://192.168.100.124/hello.php 로 접속하면 아래와 같은 출력이 생성됩니다:Hello PHP World from node4.lab.example.com 또한 PHP 구성의 다양한 세부 정보도 표시됩니다.
위에서 github를 통해 haproxy와 phpinfo를 생성했으므로 검증 방법이 아래와 같지는 않음. 아래의 검증 방법은 시험에서 사용.
$ cd /home/admin/ansible/roles/
$ vi /home/admin/ansible/roles.yml
======================================================================================
- name: Use phpinfo role
hosts: webservers
roles:
- phpinfo
- name: Use balancer role
hosts: balancers
roles:
- balancer
======================================================================================
$ ansible-playbook /home/admin/ansible/roles.yml
-- 검증
$ curl http://node5
$ curl http://node3/hello.php
$ curl http://node4/hello.php
9. Logical Volume 생성 및 사용
다음 작업을 실행하는 /home/admin/ansible/lv.yml 라는 playbook을 생성하세요. 이 플레이북은 모든 관리 대상 노드에서 실행됩니다:
다음 요구 사항을 충족하는 논리 볼륨을 생성합니다:
논리 볼륨은 research 볼륨 그룹에 생성됩니다.
논리 볼륨 이름은 data입니다.
논리 볼륨 크기는 1500 MiB입니다.
ext4 파일 시스템으로 논리 볼륨을 포맷합니다.
요청한 논리 볼륨 크기를 생성할 수 없을 경우, 오류 메시지를 표시하고 대신 크기를 800 MiB로 사용합니다. Could not create logical volume of that size
만약 볼륨 그룹 research가 존재하지 않으면 오류 메시지를 표시합니다: Volume group does not exist
논리 볼륨은 어떤 방법으로도 마운트하지 않습니다.
사전에 볼륨 그룹(research) 생성 필요
$ fdisk -l
$ fdisk /dev/sdb
n p 1 enter enter w
$ pvcreate /dev/sdb1
$ vgcreate research /dev/sdb1
node1, node2 에는 충분한 용량 할당 node3 에는 1G만 할당 node4, node5에는 미할당
-- 참고
$ ansible-doc lvol
-- playbook작성
$ vi /home/admin/ansible/lv.yml
======================================================================================
- name: Create lv
hosts: all
tasks:
- block
- name: Create LV 1500m
lvol:
vg: research
lv: data
size: 1500m
- name: filesystem
filesystem:
fstype: ext4
dev: /dev/research/data
rescue:
- debug:
msg: Could not create logical volume of that size
- name: Create LV 800m
lvol:
vg: research
lv: data
size: 800m
- name: filesystem
filesystem:
fstype: ext4
dev: /dev/research/data
when: ansible_lvm.vgs.research is defined
- debug:
msg: Volume group does not exist
when: ansible_lvm.vgs.research is undefined
======================================================================================
-- playbook 실행
$ ansible-playbook /home/admin/ansible/lv.yml
PLAY [create lv] *******************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [node5]
ok: [node2]
ok: [node4]
ok: [node3]
ok: [node1]
TASK [create lv 1500m] *************************************************************************************************************************
skipping: [node5]
skipping: [node4]
ok: [node2]
fatal: [node3]: FAILED! => {"changed": false, "err": " Volume group \"research\" has insufficient free space (255 extents): 375 required.\n", "msg": "Creating logical volume 'data' failed", "rc": 5}
changed: [node1]
TASK [filesystem format] ***********************************************************************************************************************
skipping: [node5]
skipping: [node4]
ok: [node2]
changed: [node1]
TASK [debug] ***********************************************************************************************************************************
ok: [node3] => {
"msg": "Could not create logical volume of that size"
}
TASK [create lv 800m] **************************************************************************************************************************
changed: [node3]
TASK [filesystem format] ***********************************************************************************************************************
changed: [node3]
TASK [debug] ***********************************************************************************************************************************
skipping: [node1]
skipping: [node2]
ok: [node5] => {
"msg": "Volume group does not exist"
}
skipping: [node3]
ok: [node4] => {
"msg": "Volume group does not exist"
}
PLAY RECAP *************************************************************************************************************************************
node1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
node2 : ok=3 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
node3 : ok=4 changed=2 unreachable=0 failed=0 skipped=1 rescued=1 ignored=0
node4 : ok=2 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
node5 : ok=2 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
-- 검증
$ ansible all -a 'lvs'
검증 로그
더보기
$ ansible all -a 'lvs' node5 | CHANGED | rc=0 >> LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert root rhel -wi-ao---- 44.53g swap rhel -wi-ao---- <3.88g node3 | CHANGED | rc=0 >> LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert data research -wi-a----- 800.00m root rhel -wi-ao---- 44.53g swap rhel -wi-ao---- <3.88g node1 | CHANGED | rc=0 >> LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert data research -wi-a----- 1.46g root rhel -wi-ao---- 44.53g swap rhel -wi-ao---- <3.88g node2 | CHANGED | rc=0 >> LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert data research -wi-a----- 1.46g root rhel -wi-ao---- 44.53g swap rhel -wi-ao---- <3.88g node4 | CHANGED | rc=0 >> LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert root rhel -wi-ao---- 44.53g swap rhel -wi-ao---- <3.88g
10. hosts 파일 생성
http://rhgls.domain1.example.com/material/hosts.j2에서 초기 템플릿 파일을 /home/admin/ansible 에 다운로드합니다.
템플릿을 완성하여 /etc/hosts 와 동일한 형식의 각 인벤토리 호스트에 대한 라인이 생성될 수 있도록합니다.
http://rhgls.domain1.example.com/materials/hosts.yml에서 파일을 /home/admin/ansible/hosts.yml 로 다운로드합니다. 플레이북은 변경하지 마세요.
이 플레이북은 템플릿을 사용하여 dev 호스트 그룹의 호스트에서 /etc/myhosts 파일을 생성합니다.
플레이북을 실행하면 dev 호스트 그룹의 호스트에서 /etc/myhosts 파일에 각 관리 호스트에 대한 라인이 아래와 같이 있어야합니다.
127.0.0.1 localhost localhost.localdomain localhosts4 localhosts4.localdomain4 ::1 localhost localhost.localdomain localhosts6 localhosts6.localdomain6
172.24.1.6 node1.damain1.example.com node1
172.24.1.7 node2.damain1.example.com node2
172.24.1.8 node3.damain1.example.com node3
172.24.1.9 node2.damain1.example.com node4
172.24.1.10 node5.damain1.example.com node5
참고 : 인벤토리 호스트 이름이 나타나는 순서는 중요하지 않습니다.
hosts.yml 파일이 없어서 실습 불가능. 하지만, 나름 구했음. - 어차피 주어지는 플레이북을 사용하고 수정이 불가능하기 때문에 실습할 때만 만들어주고 시험 때는 플레이북 실행만 해주면 됨. - hosts.yml 파일은 아래와 같이 주어짐.
- hosts: all
become: true
tasks:
- name: template hosts file
template:
src: hosts.j2
dest: /etc/myhosts
when: ansible_hostname in groups ['dev']
- hosts: dev로 주면 안됨. all로 주고 when을 통해 조건을 줘서 dev 그룹만 걸러내야 함.
-- 템플릿 다운로드
$ cd /home/admin/ansible
$ wget http://rhgls.domain1.example.com/material/hosts.j2
$ wget http://rhgls.domain1.example.com/materials/hosts.yml
-- 템플릿 편집
$ vi hosts.j2
======================================================================================
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for i in groups.all %}
{{ hostvars[i].ansible_default_ipv4.address }} {{ hostvars[i].ansible_facts.fqdn }} {{ i }}
{% endfor %}
======================================================================================
-- playbook 실행
$ ansible-playbook /home/admin/ansible/hosts.yml
-- 검증
$ ansible dev -a 'cat /etc/myhosts'
검증 로그
더보기
$ ansible all -a 'cat /etc/myhosts'node5 | FAILED | rc=1 >> cat: /etc/myhosts: No such file or directorynon-zero return code node3 | FAILED | rc=1 >> cat: /etc/myhosts: No such file or directorynon-zero return code node2 | FAILED | rc=1 >> cat: /etc/myhosts: No such file or directorynon-zero return code node1 | CHANGED | rc=0 >> 127.0.0.1 localhost localhost.localdomain localhosts4 localhosts4.localdomain4 ::1 localhost localhost.localdomain localhosts6 localhosts6.localdomain6 192.168.100.121 node1 node1 192.168.100.122 node2 node2 192.168.100.125 node5 node5 192.168.100.123 node3 node3 192.168.100.124 node4 node4 node4 | FAILED | rc=1 >> cat: /etc/myhosts: No such file or directorynon-zero return code
11. 파일 내용 수정하기
다음과 같이 /home/admin/ansible/issue.yml 이라는 플레이북을 작성하세요.
이 플레이북은 인벤토리 호스트 전체에서 실행됩니다.
이 플레이북은 /etc/issue 파일의 내용을 다음과 같이 변경합니다:
dev 호스트 그룹의 호스트에서는 다음과 같이 변경됩니다: Development
test 호스트 그룹의 호스트에서는 다음과 같이 변경됩니다: Test
prod 호스트 그룹의 호스트에서는 다음과 같이 변경됩니다: Production
-- playbook 작성
$ vi /home/amdin/ansible/issue.yml
======================================================================================
- hosts: all
tasks:
- name: Copy using Development
copy:
content: Development
dest: /etc/issue
when: ansible_hostname in groups.dev
- name: Copy using Test
copy:
content: Test
dest: /etc/issue
when: ansible_hostname in groups.test
- name: Copy using Production
copy:
content: Production
dest: /etc/issue
when: ansible_hostname in groups.prod
======================================================================================
-- playbook 실행
$ ansible-playbook issue.yml
PLAY [all] *************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [node5]
ok: [node3]
ok: [node4]
ok: [node2]
ok: [node1]
TASK [Copy using Development] ******************************************************************************************************************
skipping: [node2]
skipping: [node5]
skipping: [node3]
skipping: [node4]
changed: [node1]
TASK [Copy using Test] *************************************************************************************************************************
skipping: [node1]
skipping: [node5]
skipping: [node3]
skipping: [node4]
changed: [node2]
TASK [Copy using Production] *******************************************************************************************************************
skipping: [node1]
skipping: [node2]
skipping: [node5]
changed: [node4]
changed: [node3]
PLAY RECAP *************************************************************************************************************************************
node1 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
node2 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
node4 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
node5 : ok=1 changed=0 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
-- 검증
$ ansible all -a 'cat /etc/issue'
검증 로그
더보기
$ ansible all -a 'cat /etc/issue' node5 | CHANGED | rc=0 >> \S Kernel \r on an \m node2 | CHANGED | rc=0 >> Test node3 | CHANGED | rc=0 >> Production node1 | CHANGED | rc=0 >> Development node4 | CHANGED | rc=0 >> Production
12. 웹 콘텐츠 디렉토리 생성하기
/home/admin/ansible/webcontent.yml 이라는 플레이북을 다음과 같이 작성하세요:
플레이북은 dev 호스트 그룹의 관리 대상 노드에서 실행됩니다.
다음 요구 사항을 갖는 /webdev 디렉토리를 생성하세요.
그룹 소유권이 webdev 로 설정됩니다.
일반 권한 : 소유자=읽기+쓰기+실행, 그룹=읽기+쓰기+실행, 다른 사용자=읽기+실행 특수 권한 : 그룹 ID 설정됨
심볼릭 링크 /var/www/html/webdev 를 /webdev 로 생성하세요.
/webdev/index.html 파일을 생성하고, 해당 파일 내용은 "Development"라는 단일 텍스트 라인이어야 합니다.
dev 호스트 그룹의 호스트에서 이 디렉토리를 브라우징하면(http://node1.domain1.example.com/webdev/), "Development"가 출력되어야 합니다.
node1에 httpd 설치 필요 node1에 webdev 그룹 생성 필요 node1에 firewall 설정 필요 실제 시험에서는 webdev group 과 httpd 서비스가 자동으로 기동 및 설정 되어있음
-- 참고
$ ansible-doc file
-- playbook 작성
$ vi webcontent.yml
======================================================================================
- name: webcontent
hosts: dev
tasks:
- name: Create a directory
file:
path: /webdev
state: directory
group: webdev
mode: '2775'
- name: Create a symbolic link
file:
state: link
src: /webdev
dest: /var/www/html/webdev
- name: Copy using Content
copy:
content: 'Development'
dest: /webdev/index.html
setype: httpd_sys_content_t
======================================================================================
-- 검증
$ ansible all -a 'ls -al /webdev'
node5 | FAILED | rc=2 >>
ls: cannot access '/webdev': No such file or directorynon-zero return code
node1 | CHANGED | rc=0 >>
total 4
drwxrwsr-x. 2 root webdev 24 Apr 16 14:45 .
dr-xr-xr-x. 20 root root 267 Apr 16 14:40 ..
-rw-r--r--. 1 root root 11 Apr 16 14:45 index.html
node2 | FAILED | rc=2 >>
ls: cannot access '/webdev': No such file or directorynon-zero return code
node3 | FAILED | rc=2 >>
ls: cannot access '/webdev': No such file or directorynon-zero return code
node4 | FAILED | rc=2 >>
ls: cannot access '/webdev': No such file or directorynon-zero return code
$ ansible all -a 'ls -al /var/www/html'
node5 | FAILED | rc=2 >>
ls: cannot access '/var/www/html': No such file or directorynon-zero return code
node1 | CHANGED | rc=0 >>
total 0
drwxr-xr-x. 2 root root 20 Apr 16 14:45 .
drwxr-xr-x. 4 root root 33 Apr 15 10:32 ..
lrwxrwxrwx. 1 root root 7 Apr 16 14:45 webdev -> /webdev
node2 | CHANGED | rc=0 >>
total 0
drwxr-xr-x. 2 root root 6 Aug 12 2024 .
drwxr-xr-x. 4 root root 33 Apr 15 10:32 ..
node3 | CHANGED | rc=0 >>
total 4
drwxr-xr-x. 2 root root 24 Apr 15 14:15 .
drwxr-xr-x. 4 root root 33 Apr 15 10:32 ..
-rw-r--r--. 1 root root 74 Apr 15 14:15 index.html
node4 | CHANGED | rc=0 >>
total 4
drwxr-xr-x. 2 root root 24 Apr 15 14:15 .
drwxr-xr-x. 4 root root 33 Apr 15 10:32 ..
-rw-r--r--. 1 root root 74 Apr 15 14:15 index.html
13. 하드웨어 보고서 생성하기
/home/admin/ansible/hwreport.yml 이름의 playbook을 생성하여 다음 정보가 있는 모든 관리 노드에 /root/hwreport.txt 출력 파일을 생성하십시오.
인벤토리 호스트 이름
총 메모리 용량(MB)
BIOS 버전
디스크 장치 vda의 크기
디스크 장치 vdb의 크기
출력 파일의 각 줄에는 하나의 키 = 값 쌍이 포함됩니다.
이 Playbook은 다음을 수행해야합니다.
http://rhgls.domain1.example.com/materials/hwreport.empty 파일을 다운로드하고 /root/hwreport.txt 로 저장합니다.
/root/hwreport.txt 를 올바른 값으로 수정합니다.
하드웨어 항목이 존재하지 않으면 연관된 값은 NONE으로 설정해야합니다.
수동으로 모든 노드에 /root/hwreport.txt 생성 후 진행 편의상 node1에만 생성 후 진행하였음
$ cat /root/hwreport.txt
HOST=
MEMORY=
BIOS=
DISK_SIZE_VDA=
DISK_SIZE_VDB=
-- 참고
$
$ vi /home/admin/ansible/hwreport.yml
- name: Make hwreport
hosts: all
vars:
hw_all:
- hw_name: HOST
hw_cont: "{{ inventory_hostname | default('NONE',true) }}"
- hw_name: MEMORY
hw_cont: "{{ ansible_memtotal_mb | default('NONE',true) }}"
- hw_name: BIOS
hw_cont: "{{ ansible_bios_version | default('NONE',true) }}"
- hw_name: DISK_SIZE_VDA
hw_cont: "{{ ansible_devices.vda.size | default('NONE',true) }}"
- hw_name: DISK_SIZE_VDB
hw_cont: "{{ ansible_devices.vdb.size | default('NONE',true) }}"
tasks:
- name: create hwreport.txt
get_url:
url: http://rhgls.domain1.example.com/materials/hwreport.empty
dest: /root/hwreport.txt
- name: hwreport
lineinfile:
path: /root/hwreport.txt
regexp: '^{{ item.hw_name }}='
line: "{{ item.hw_name }}={{ item.hw_cont }}"
loop: "{{ hw_all }}"
-- playbook 실행
$ ansible-playbook hwreport.yml
-- 검증
$ ansible all -a 'cat /root/hwreport.txt'
검증 로그
더보기
$ ansible all -a 'cat /root/hwreport.txt' node5 | FAILED | rc=1 >> cat: /root/hwreport.txt: No such file or directorynon-zero return code node3 | FAILED | rc=1 >> cat: /root/hwreport.txt: No such file or directorynon-zero return code node1 | CHANGED | rc=0 >> HOST=node1 MEMORY=3843 BIOS=Hyper-V UEFI Release v4.0 DISK_SIZE_VDA=NONE DISK_SIZE_VDB=NONE node2 | FAILED | rc=1 >> cat: /root/hwreport.txt: No such file or directorynon-zero return code node4 | FAILED | rc=1 >> cat: /root/hwreport.txt: No such file or directorynon-zero return code
14. 비밀번호 저장소 생성하기
다음과 같이 사용자 비밀번호를 저장하기 위한 Ansible 보안 저장소(vault)를 생성합니다:
저장소 이름은 /home/admin/ansible/locker.yml 입니다.
저장소에는 다음과 같은 이름과 값의 두 가지 변수가 포함됩니다:
pw_developer 의 값은 Imadev 입니다.
pw_manager 의 값은 Imamgr 입니다.
저장소를 암호화하고 복호화하기 위한 비밀번호는 whenyouwishuponastar 입니다.
비밀번호는 /home/admin/ansible/secret.txt 파일에 저장됩니다.
-- 비밀번호 저장파일 생성
$ echo "whenyouwishuponastar" > /home/admin/ansible/secret.txt
-- 비밀번호 파일 지정
$ vi ansible.cfg
vault_password_file=/home/admin/ansible/secret.txt
-- vault 생성
$ ansible-vault create /home/admin/ansible/locker.yml
pw_developer: Imadev
pw_manager: Imamgr
-- 검증
$ ansible-vault view locker.yml
검증 로그
더보기
$ ansible-vault view locker.yml pw_developer: Imadev pw_manager: Imamgr
15. 사용자 계정 생성하기
http://rhgls.domain1.example.com/materials/user_list.yml에서 생성할 사용자 목록을 다운로드하여 /home/admin/ansible에 저장합니다.
이전에 생성한 비밀번호 보관함인 /home/admin/ansible/locker.yml을 사용하여 /home/admin/ansible/users.yml이라는 플레이북을 생성하여 다음과 같이 사용자 계정을 생성합니다:
직무가 developer인 사용자는 다음과 같이 처리됩니다:
dev 및 test 호스트 그룹의 관리 노드에서 생성됩니다.
pw_developer 변수에서 비밀번호를 할당받으며, 30일 후에 비밀번호가 만료되도록 설정합니다.
부가 그룹 devops 의 멤버가 됩니다.
직무가 manager인 사용자는 다음과 같이 처리됩니다:
prod 호스트 그룹의 관리 노드에서 생성됩니다.
pw_manager 변수에서 비밀번호를 할당받으며, 30일 후에 비밀번호가 만료되도록 설정합니다.
부가 그룹 opsmgr 의 멤버가 됩니다.
비밀번호는 SHA512 해시 형식을 사용해야 합니다.
이 플레이북은 이전에 생성한 비밀번호 파일 /home/admin/ansible/secret.txt를 사용하여 작동해야 합니다.
user_list.yml 파일이 없어서 실습 불가능 user_list.yml 예시(답을 토대로 임의로 만들어봤음)
- users:
- name: bob
job: developer
password_expire_max: 30
- name: sally
job: manager
password_expire_max: 30
- name: fred
job: developer
password_expire_max: 30
시험에선 user_list.yml 파일 다운로드 후 내용 확인할 것
-- 파일 다운로드
$ wget http://rhgls.domain1.example.com/materials/user_list.yml
-- 파일내용 확인
$ cat user_list.yml
-- playbook작성
$ vi /home/admin/ansible/users.yml
- hosts: dev,test
become: true
vars_files:
- /home/admin/ansible/locker.yml
- /home/admin/ansible/user_list.yml
tasks:
- name: create a group
group:
name: devops
state: present
- name: run to developer
user:
name: '{{ item.name }}'
comment: '{{ item.job }}'
password: "{{ pw_developer | password_hash('sha512') }}"
groups: devops
append: yes
password_expire_max: "{{ item.password_expire_max }}"
loop: '{{ users }}'
when: item.job == 'developer'
- hosts: prod
become: true
vars_files:
- /home/admin/ansible/locker.yml
- /home/admin/ansible/user_list.yml
tasks:
- name: create a group
group:
name: opsmgr
state: present
- name: run to manager
user:
name: '{{ item.name }}'
comment: '{{ item.job }}'
password: "{{ pw_manager | password_hash('sha512') }}"
groups: opsmgr
append: yes
password_expire_max: 30
loop: '{{ users }}'
when: item.job == 'manager'
-- 검증
$ ansible dev,test -a 'id bob'
검증 로그
더보기
[admin@control ansible]$ ansible dev,test -a 'id bob' node2 | CHANGED | rc=0 >> uid=1006(bob) gid=1006(bob) groups=1006(bob),1001(devops) node1 | CHANGED | rc=0 >> uid=1006(bob) gid=1007(bob) groups=1007(bob),1002(devops)
[admin@control ansible]$ ansible dev,test -a 'id fred' node2 | CHANGED | rc=0 >> uid=1008(fred) gid=1008(fred) groups=1008(fred),1001(devops) node1 | CHANGED | rc=0 >> uid=1008(fred) gid=1009(fred) groups=1009(fred),1002(devops)
[admin@control ansible]$ ansible prod -a 'id sally' node4 | CHANGED | rc=0 >> uid=1007(sally) gid=1007(sally) groups=1007(sally),1001(opsmgr) node3 | CHANGED | rc=0 >> uid=1007(sally) gid=1007(sally) groups=1007(sally),1001(opsmgr)
[admin@control ansible]$ ssh bob@node1 bob@node1's password: Imadev Register this system with Red Hat Insights: rhc connect Example: # rhc connect --activation-key <key> --organization <org> The rhc client and Red Hat Insights will enable analytics and additional management capabilities on your system. View your connected systems at https://console.redhat.com/insights You can learn more about how to register your system using rhc at https://red.ht/registration [bob@node1 ~]$ exit logout Connection to node1 closed.
[admin@control ansible]$ ssh sally@node3 sally@node3's password: Imamgr Register this system with Red Hat Insights: rhc connect Example: # rhc connect --activation-key <key> --organization <org> The rhc client and Red Hat Insights will enable analytics and additional management capabilities on your system. View your connected systems at https://console.redhat.com/insights You can learn more about how to register your system using rhc at https://red.ht/registration [sally@node3 ~]$ exit logout Connection to node3 closed.
16. Ansible Vault 키 업데이트
다음과 같이 기존 ansible 보안 저장소의 비밀번호를 변경하세요:
http://rhgls.domain1.example.com/materials/salaries.yml 에서 Ansible 보안 저장소를 다운로드하여 /home/admin/ansible 저장합니다.
현재 저장소의 비밀번호는 insecure4sure 입니다.
새 저장소 비밀번호는 bbe2de98389b 입니다.
새로운 비밀번호로 저장소는 암호화된 상태로 유지됩니다.
salaries.yml 파일이 없으므로 위에서 생성한 locker.yml 파일을 통해 실습함.
$ cd /home/admin/ansible
$ wget http://rhgls.domain1.example.com/materials/salaries.yml
$ ansible-vault rekey --ask-vault-pass salaries.yml
Vault password: insecure4sure
New Vault password: bbe2de98389b
Confirm New Vault password: bbe2de98389b
Rekey successful
-- 검증
$ cat /home/admin/ansible/salaries.yml
검증 로그
더보기
변경전 [admin@control ansible]$ cat /home/admin/ansible/locker.yml $ANSIBLE_VAULT;1.1;AES256 65346336643864316330336133376363313034636137363635396462353961376139663039363464 3732663137316138616435326531373565376461323361610a373330623338353662663632326665 32346265633038323931613366373261633161653336656235616163393837336536323639303132 3233303138623261340a643164396233353362363761656330613836346332336537623163326264 33306665383937396633336166343365373535306339313462323434333839626139663363646466 3731326135316461343537393438383631393937656362646164 [admin@control ansible]$ ansible-vault rekey --ask-vault-pass locker.yml Vault password: New Vault password: Confirm New Vault password: Rekey successful 변경후 [admin@control ansible]$ cat /home/admin/ansible/locker.yml $ANSIBLE_VAULT;1.1;AES256 33626534313337393737343966303131396163636331663062333731633064396134383333323435 3034626164316664633662386231356132653263663633370a313966336536636539663466316237 65316637313365633866306233643562636162633830663337316432316335333631623235343363 3632373738393631370a373630356164366238323837633733303639346533323239653730313131 66393036333737383961663734653938323733303964343963303136623736386532356262616566 3363666237373236363332356431353537356535643233666533
17. cron 작업 설정하기
/home/admin/ansible/cron.yml 라는 이름의 playbook을 만드세요. 이 playbook은 모든 관리 대상 호스트에서 실행되며 다음과 같이 사용자 natasha의 크론 작업을 만듭니다.
사용자 natasha는 매 2분마다 실행되고 logger "EX294 in progress"를 실행하는 크론 작업을 설정해야 합니다.
모든 노드에 natasha 유저 생성 필요.
- name: add user natasha
user:
name: natasha
group: admin
시험에는 natasha 유저가 이미 생성되어 있음.
$ vi /home/admin/ansible/cron.yml
- name: cron
hosts: all
tasks:
- name: add cron
cron:
name: add cron natasha
minute: "*/2"
user: natasha
job: logger "EX294 in progress"
$ ansible-playbook /home/admin/ansible/cron.yml
$ ansible all -a 'crontab -u natasha -l'
검증 로그
더보기
$ ansible all -a 'crontab -u natasha -l' node5 | CHANGED | rc=0 >> #Ansible: add cron natasha */2 * * * * logger "EX294 in progress" node1 | CHANGED | rc=0 >> #Ansible: add cron natasha */2 * * * * logger "EX294 in progress" node2 | CHANGED | rc=0 >> #Ansible: add cron natasha */2 * * * * logger "EX294 in progress" node3 | CHANGED | rc=0 >> #Ansible: add cron natasha */2 * * * * logger "EX294 in progress" node4 | CHANGED | rc=0 >> #Ansible: add cron natasha */2 * * * * logger "EX294 in progress"
참고
https://www.geuni.tech/linux/rhce_practice
https://maru1000.tistory.com/92
https://yeahro.tistory.com/22
https://seungjuitmemo.tistory.com/264