Ubuntu 22.04 에서 Ansible 2.10.8 설치 및 설정, 플레이북 활용

리눅스/OS 일반|2023. 10. 12. 11:34
반응형

Ansible 은 인프라스트럭처 관리와 소프트웨어 프로비저닝을 자동화하기 위한 오픈 소스 도구 및 프레임워크입니다. Ansible 은 다음 3가지의 핵심 구성 요소를 가지고 있습니다.
- 인벤토리 : 관리 대상 호스트 (서버, 가상 머신 등) 의 목록 및 그룹을 정의하는 INI 또는 YAML 파일
- 플레이북 : 작업 (task), 역할 (role), 변수, 조건문 등을 포함한 YAML 파일로, 여러 대상 호스트에서 작업을 수행
- 모듈 : 특정 작업을 수행하기 위한 실행 가능한 코드 블록

 

Ubuntu 22.04 기반에서 Ansible 을 설치, 설정하고 실제로 실행하는 방법을 알아보겠습니다.

 

[테스트를 위한 사전 준비]

- Ubuntu 22.04 기반 서버 3대 (Ansible 서버 1대, 대상 호스트 2대)

 

 

1. 설치

 

Ansible 설치는 굉장히 간단합니다.

Ansible 명령을 수행할 Ansible 서버에만 몇 개의 패키지를 설치하면 되며, 작업을 수행할 서버에 설치할 패키지 또는 Agent 는 없습니다.

(그렇기 때문에 본 매뉴얼의 모든 명령은 Ansible 서버에서만 실행합니다)

Ansible 는 SSH 기반으로 명령을 수행하기 때문에 sshpass 패키지까지 설치해줘야 합니다.

그리고 Ansible 은 Python 으로 제작되었기 때문에 Ansible 설치시 Python 도 같이 설치가 됩니다.

# apt -y update

# apt -y upgrade

# apt -y install ansible sshpass

# ansible --version
ansible 2.10.8
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]

 

 

2. 인벤토리 설정

 

1) 인벤토리 파일 생성

관리하는 서버의 정보를 담은 파일을 아래와 같이 생성합니다.

섹션 이름은 서버를 그룹핑하기 위한 명칭으로 적절히 설정하면 되고,

대상 호스트는 IP 또는 도메인으로 입력할 수 있습니다.

섹션 내에 여러대의 호스트 추가가 가능합니다.

# vi servers.ini

[web]
10.101.0.23
[db]
10.101.0.34

 

2) SSH 공개키 복사

Ansible 은 ssh 를 이용하여 대상 호스트로 명령을 수행합니다.

ssh 공개키를 생성하고 대상 호스트에 설정하여두면 Ansible 명령 실행시마다 패스워드를 입력하는 번거로움을 줄일 수 있습니다.

# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): (그냥 엔터)
Enter passphrase (empty for no passphrase): (그냥 엔터)
Enter same passphrase again: (그냥 엔터)
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:2bKuWWJfCBqiNnkCYgKZRmI6GEZDynqWbGM41/TsbAk root@kuru80-223962
The key's randomart image is:
+---[RSA 3072]----+
|=B               |
|X+.              |
|Oo  .            |
|++ + o   o       |
|B.@ E + S .      |
|=O.o * o +       |
|.= .. B + .      |
|. +  o * .       |
|      o.o        |
+----[SHA256]-----+

생성된 공개키를 대상 호스트로 복사합니다. 처음 호스트 접속시 패스워드가 필요하지만 키 복사가 완료된 후에는 패스워드가 필요 없게 됩니다.

# ssh-copy-id root@10.101.0.23

# ssh-copy-id root@10.101.0.34

 

3) 연결 테스트

Ansible 에서 주로 사용하는 옵션은 세가지가 있습니다. (help 에서는 더 많은 옵션이 출력됩니다)

-m : 모듈

-i : 인벤토리

-u : 유저명

유저명은 제외하고 아래와 같이 인벤토리 (servers.ini) 에 등록된 모든 호스트에 ping 테스트를 해봅니다.

참고로 all 말고 섹션명을 지정해주면 인벤토리 내의 특정 세션에 등록된 호스트로만 명령을 실행합니다.

# ansible -i servers.ini all -m ping
10.101.0.34 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.101.0.23 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

 

 

3. 옵션

 

Ansible 은 기본적으로 작업을 병렬 처리 합니다.

기본 동시 처리되는 호스트 개수는 5개 입니다.

# ansible-config dump |grep -i forks
DEFAULT_FORKS(default) = 5

 

서버의 자원이 충분하여 동시에 처리되는 양을 늘리고자 할 경우 아래와 같이 설정파일을 수정하여 동시처리 개수를 늘릴 수 있습니다.

설정파일은 아래 여러 가지 방법중 한가지 방법을 이용하여 설정할 수 있으며, 우선 순위대로 검색되는 구성 파일으로 적용되어집니다.

- ANSIBLE_CONFIG (환경변수)
- ansible.cfg (현재 디렉토리)
- ~/.ansible.cfg (홈디렉토리)
- /etc/ansible/ansible.cfg

 

디렉토리가 바뀌어도 항상 적용이 가능하도록 세번째 방법으로 설정해보겠습니다.

# vi ~/.ansible.cfg

[defaults]
forks = 10

 

저장만 해도 변경된 것이 확인되었습니다.

# ansible-config dump |grep -i forks
DEFAULT_FORKS(/root/.ansible.cfg) = 10

 

아래는 중요하거나 자주 사용하는 옵션입니다. 모두 [default] 섹션에 넣어주면 됩니다.

- remote_user

: 원격 호스트에 연결할 때 사용할 SSH 사용자 이름을 지정합니다. 기본값은 현재 사용자의 이름입니다. 이 옵션을 설정하여 명시적으로 원격 사용자를 지정할 수 있습니다.
예) remote_user = myuser

 

- private_key_file

: SSH 키 파일의 경로를 지정합니다. 이 옵션을 사용하여 사용자 지정 SSH 키 파일을 사용할 수 있습니다.
예) private_key_file = /path/to/ssh/keyfile

 

- inventory

: 인벤토리 파일의 경로를 지정합니다. 기본적으로 ansible.cfg 파일이 있는 디렉토리에서 inventory 파일을 검색하며, 이 옵션을 사용하여 사용자 정의 인벤토리 파일을 지정할 수 있습니다. 인벤토리 파일의 경로를 지정하면 ansible 명령 실행시 -i 옵션을 이용해 인벤토리 파일을 일일이 명시하지 않아도 됩니다.
예) inventory = /root/servers.ini

 

- roles_path

: 역할 (roles) 디렉토리의 기본 경로를 지정합니다. 이 옵션을 사용하여 역할을 저장하는 디렉토리를 사용자 정의할 수 있습니다.
예) roles_path = /path/to/custom/roles

 

- forks

: 병렬로 실행될 작업 수를 지정합니다. 기본값은 5이며, 시스템 리소스에 따라 적절한 값을 설정할 수 있습니다.
예) forks = 10

 

- become

: 작업을 슈퍼 유저(루트) 권한으로 실행할지 여부를 지정합니다. yes로 설정하면 슈퍼 유저로 작업을 실행합니다.
예) become = yes

 

- become_user

: 슈퍼 유저(루트) 권한으로 작업을 실행할 때 사용할 사용자를 지정합니다.
예) become_user = root

 

- timeout

: SSH 연결 또는 명령 실행의 타임아웃을 지정합니다. 기본값은 10초입니다.
예) timeout = 30

 

 

4. 플레이북 설정

 

플레이북 (playbook) 을 활용한 다양한 예시를 준비했습니다.

 

1) 대상 서버로 파일 복사하기

아래와 같이 플레이북 파일을 작성합니다.

# vi copy.yaml

---
- name: Copy a file to a remote server
  hosts: web
  tasks:
    - name: Copy a file
      copy:
        src: /root/servers.ini
        dest: /root/

 

- 플레이북 파일의 시작은 --- 로 시작하고, 여러개의 작업이 있을 경우 작업 단위마다 - 으로 구분해줘야 합니다.

- hosts : 섹션을 지정합니다. hosts 를 web 섹션으로 하지 않고 all 로 입력 할 경우 인벤토리에 등록된 모든 호스트로 파일을 복사하게 됩니다.

- name : 작업을 구분하기 위한 명칭입니다. (위, 아래 둘다)

- copy : 복사하려는 로컬 파일과 붙여넣으려는 대상 호스트의 디렉토리를 지정합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini copy.yaml

 

2) 패스워드 변경하기

대상 호스트의 root 패스워드를 변경합니다.

# vi chpasswd.yaml

---
- name: Update Remote Server Password
  hosts: all
  tasks:
    - name: Update password
      user:
        name: root
        update_password: always
        password: "{{ '12345678' | password_hash('sha512') }}"

 

- name: 플레이북의 이름을 정의합니다. 이 이름은 플레이북을 식별하기 위해 사용됩니다.
- hosts: 플레이북이 실행될 호스트 그룹을 지정합니다. "all"은 모든 호스트를 대상으로 하는 것을 의미합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- name: 각 작업의 이름을 지정합니다. 이것은 작업을 식별하기 위한 레이블입니다.
- user 모듈: 이 모듈은 사용자 관리 작업을 수행합니다.
- name: root: user 모듈에 전달된 사용자 이름으로 "root" 사용자를 지정합니다. 이 플레이북은 "root" 사용자의 비밀번호를 변경합니다.
- update_password: always: 사용자 모듈의 update_password 옵션을 "always"로 설정하면 항상 비밀번호를 업데이트하도록 강제합니다.
- password: user 모듈에서 변경할 비밀번호를 정의합니다. 이 플레이북에서는 "12345678"을 password_hash 필터를 사용하여 SHA-512로 해싱한 값을 비밀번호로 설정합니다. 해싱된 비밀번호를 사용하면 보안성을 향상시킬 수 있습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini chpasswd.yaml

 

3) 패키지 설치하기

이 예시는 원격 서버의 APT 패키지 관리자를 사용하여 패키지를 설치합니다.
# vi apt.yaml

---
- name: Install a package on a remote server
  hosts: web
  tasks:
    - name: Install package
      apt:
        name: apache2
        state: present

 

- name: 플레이북의 이름을 정의합니다. 이 이름은 플레이북을 식별하기 위해 사용됩니다.
- hosts: 플레이북이 실행될 호스트 그룹을 지정합니다. "web"은 모든 호스트를 대상으로 하는 것을 의미합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- apt 모듈: 패키지 설치 작업을 수행합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini apt.yaml

 

4) 데몬 컨트롤 하기

이 예제에서는  Ubuntu 에서 Apache 웹 서버를 시작하는 플레이북을 사용합니다.
# vi apache2.yaml

---
- name: Start Apache Web Server
  hosts: web
  become: yes
  tasks:
    - name: Ensure Apache service is running
      service:
        name: apache2
        state: started


- name: 플레이북의 이름을 지정합니다.
- hosts: 플레이북을 실행할 호스트 그룹 또는 호스트 이름을 지정합니다.
- become: yes: become 키워드를 사용하여 플레이북을 실행할 때 슈퍼유저(루트) 권한으로 실행합니다. 이는 데몬 또는 서비스를 시작하거나 중지할 때 필요한 권한을 얻기 위해 사용됩니다.
- tasks: 수행할 작업 목록을 나열합니다.
- name: 작업의 이름을 지정합니다.
- service 모듈: 서비스 관리 작업을 수행하는 모듈입니다.
- name: apache2: 서비스의 이름을 지정합니다. Ubuntu 에서 Apache 웹 서버는 apache2 로 알려져 있습니다.
- state: started: 서비스를 시작하도록 지정합니다. 이 작업은 Apache 웹 서버가 이미 실행 중인 경우에는 아무 작업도 수행하지 않습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini apache2.yaml

 

5) 사용자 생성 및 그룹 할당
이 예시는 원격 서버에 사용자를 생성하고 그룹에 할당하는 플레이북입니다. user 및 group 모듈을 사용합니다.

# vi useradd.yaml

---
- name: Create a user and assign to a group
  hosts: web
  tasks:
    - name: Create a group
      group:
        name: developers
        state: present

    - name: Create a user
      user:
        name: sysdocu
        groups: developers
        state: present

 

* 설명

- name: 플레이북의 이름을 지정합니다.
- hosts: 플레이북을 실행할 호스트 그룹 또는 호스트 이름을 지정합니다.
- tasks: 수행할 작업 목록을 나열합니다.
- group 및 user 모듈: 그룹 및 사용자 생성 및 할당 작업을 수행합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini useradd.yaml

 

6) 보안 패치 적용
서버에 보안 패치를 적용합니다.
# vi update.yaml

---
- name: Apply security patches
  hosts: all
  tasks:
    - name: Update package cache
      apt:
        update_cache: yes
      become: yes

    - name: Upgrade all packages
      apt:
        upgrade: safe
      become: yes

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini update.yaml

 

7) MySQL 설치 및 설정
MySQL 데이터베이스를 설치하고 설정합니다.

DB 생성, 계정 생성 및 DB 권한 부여까지 진행합니다.
# vi mysql.yaml

---
- name: Install MySQL and Configure Database
  hosts: db
  become: yes
  tasks:
    - name: Install MySQL Server
      apt:
        name: mysql-server
        state: present

    - name: Start MySQL Service
      service:
        name: mysql
        state: started

    - name: Install python3-pymysql
      apt:
        name: python3-pymysql
        state: present

    - name: Change MySQL root password
      mysql_user:
        login_user: root
        login_password: ''
        name: root
        password: 12345678
        host: localhost
        login_unix_socket: /var/run/mysqld/mysqld.sock

    - name: Create a MySQL Database
      mysql_db:
        login_user: root
        login_password: 12345678
        name: sysdocudb
        state: present

    - name: Create a MySQL User
      mysql_user:
        name: sysdocu
        password: 12345678
        priv: sysdocudb.*:ALL

    - name: Flush MySQL Privileges
      mysql_user:
        login_user: root
        login_password: 12345678
        name: sysdocu
        host: localhost
        priv: "*.*:ALL,GRANT"
        append_privs: yes

 

작업을 설명하면, 아래와 같이 순차 처리됩니다.

- MySQL 설치

- MySQL 시작

- python3-pymysql 설치 (Ansible 에서 MySQL 관리하기 위해 필요)

- root 패스워드 변경 (null -> 12345678)

- DB 생성

- DB 계정 생성

- 계정에 DB 권한 부여

* 작업별로 MySQL 쿼리 실행을 위해 root 계정정보를 입력해 주었습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini mysql.yaml

 

8) Docker 컨테이너 배포 및 관리

Docker 컨테이너를 배포하고 관리합니다.

플레이북에서 대상 호스트에 Docker 패키지와 docker-py 설치 작업 후 컨테이너를 구동하는 절차로 작성하면 되지만, 여기에서는 Docker 및 docker-py 가 대상 호스트에 설치되었다고 가정하고 컨테이너 구동 방법만 설명드립니다.

 

* 참고 : Docker 및 docker-py 설치 (Ubuntu 22.04)

(대상 호스트에서)

# apt -y install apt-transport-https ca-certificates curl gnupg lsb-release
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg |gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo   "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" |tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt -y update
# apt -y install docker-ce docker-ce-cli containerd.io

# apt -y install python3-pip

# pip3 install docker-py

 

플레이북을 작성합니다.

(Ansible 서버에서)

# vi docker.yaml

---
- name: Deploy Docker containers
  hosts: db
  tasks:
    - name: Pull Docker image
      docker_image:
        name: nginx:latest

    - name: Run a Docker container
      docker_container:
        name: my_nginx
        image: nginx:latest
        ports:
          - "80:80"

 

- name: 플레이북의 이름을 지정합니다. 이 이름은 플레이북을 식별하는 레이블입니다.
- hosts: 플레이북을 실행할 호스트 또는 호스트 그룹을 지정합니다. 이 예시에서는 "db" 호스트 그룹에 대한 작업을 수행합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- name: 각 작업의 이름을 지정합니다. 이것은 작업을 식별하는 레이블입니다.
- docker_image 모듈: 이 모듈은 Docker 이미지 관리 작업을 수행합니다. name 속성은 다운로드하려는 Docker 이미지의 이름을 지정합니다. 이 예시에서는 "nginx:latest" 이미지를 다운로드합니다.
- docker_container 모듈: 이 모듈은 Docker 컨테이너 관리 작업을 수행합니다. name 속성은 컨테이너의 이름을 지정하고, image 속성은 사용할 Docker 이미지를 지정합니다. ports 속성은 컨테이너와 호스트 간의 포트 매핑을 설정합니다. 이 예시에서는 "my_nginx"라는 이름의 컨테이너를 생성하고 "nginx:latest" 이미지를 사용하며, 호스트의 80번 포트와 컨테이너의 80번 포트를 연결합니다.

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini docker.yaml

 

반응형

댓글()