Ansible

freshness·2024년 7월 31일
post-thumbnail

애플리케이션을 원격 노드에 배포하고 반복적으로 서버를 배포하는데 사용되는 오픈 소스 도구

장/단점

장점

  • SSH 기반으로 원격 노드에 별도의 에이전트 설치가 필요 없다.(Agentless)
  • YAML 언어 사용으로 쉽게 사용 가능
  • 변수 기능을 사용해 같은 작업에 대해 다른 구성으로 쉽게 구성 가능
  • 다른 도구에 비해 간소화 된 코드 기반
  • 플레이북 구조가 간단하고 명확
  • 관리 대상의 종류를 따지지 않는다.

단점

  • 다른 프로그래밍 언어 기반의 도구보다 덜 강력
  • 변수 등록 시 별도의 절차가 요구되기 때문에 쉬운 작업을 복잡하게 만들 수 있다.
  • 플레이 내 변수 값을 확인하기 어려움
  • 때때로 성능 속도 저하 발생
  • 입력, 출력, 구성 파일의 형식 간 일관성이 없음

용어

  • 제어 노드
    • Ansible이 설치된 모든 호스트
  • 관리 노드(관리 호스트, 원격 노드)
    • SSH가 설치되고 서비스가 동작해야 제어 노드가 접근해 관리 가능
    • Python 2.6 이상의 버전이 설치 요구
  • 인벤토리
    • 호스트가 속한 그룹을 정의
    • 여러 관리 노드를 그룹으로 조직화 가능
    • 관리 할 대상의 정보가 모여있는 곳으로 호스트이름 또는 IP 주소를 사용해 그룹을 정의한다.
  • 플러그인
    • Ansible의 핵심 기능을 강화하는 코드 조각
  • 모듈
    • Ansible은 Python 기반으로 실행되며 모듈은 Ansible을 실행하는 코드 단위
    • 기능 별로 모듈 존재
    • 제어 노드에 있는 모듈이 관리 노드에 복사되어 관리 노드에서 실행
  • 작업
    • 모듈의 집합
  • Ad-hoc 명령
    • 여러 시스템에서 빠른 작업을 수행하도록 설계된 한줄 짜리 임시 명령
    • Ad-hoc 명령 = 셸 명령 / 플레이북 = 셸 스크립트
  • 플레이
    • 특정 관리 노드를 대상으로 순서가 지정된 작업 목록
  • 플레이북
    • 하나 이상의 플레이를 가진 YAML 파일
    • ansible-playbook 명령을 이용해 플레이북 실행 가능
  • 역할
    • 알려진 파일/디렉토리 구조를 기반으로 관련 변수, 파일, 작업 등 아티팩트 모음
  • 컬렉션
    • 플레이북 및 역할, 모듈, 플러그인을 퐇마하는 Ansible 콘텐츠 배포 형식
  • 연결 플러그인
    • 제어 노드가 관리 노드에 원격으로 연결할 때 사용하는 방법
    • SSH가 기본이며 localhost, paramiko 등이 존재

Ansible 설치

  1. Ansible 설치
    1. 운영체제 배포판의 버전 문제가 있을 수 있기 때문에 pip 설치 권장
    2. python은 존재하지만 pip가 설치되지 않은 경우
      1. curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
      2. python3 get-pip.py 실행
    3. pip install ansible
      1. ansible-core 로 설치할 경우 작업 시 추가 설치할 경우가 생길 수 있음

Ansible 실습

  1. 컨트롤 노드와 관리 노드 SSH 접속 설정
    1. 컨트롤 노드에 ansible 설치
    2. ssh-keygen을 이용해 ssh 키 생성
    3. ssh-copy-id 로 host에 ssh 키 복사
      1. ssh-copy-id vagrant@host[N]
    4. 구분이 편하도록 hostname 설정
    5. 필요 시 /etc/sudoers.d 에서 관리자 권한 사용을 부여

인벤토리 구성

  1. /etc/ansible/hosts : 기본 인벤토리 파일
  2. -i 옵션을 사용해 다른 인벤토리 파일 지정 가능
  3. pip 로 설치한 경우 해당 디렉토리가 없을 수 있음
  4. ansible-inventory --list : 인벤토리 설정 확인
  5. 정적 inventory 파일 작성 예시
    • inventory는 INI 방식, Yaml 방식 2가지로 작성 가능
  • 가장 쉽게 등록하는 방법 중 하나는 DNS 또는 IP만 적어놓는 것(INI 방식)
    ctrl-node
    host1
    host2
    host3
    host4
    192.168.56.100
    192.168.56.101
    192.168.56.102
    192.168.56.103
    192.168.56.104
  • 그룹별로 등록할 때(INI 방식)
    192.168.56.101 # 그룹이 없는 경우 대괄호 의 그룹 세팅 위로 설정
    
    [webservers]
    host1
    host2
    
    [databaseserver]
    host3
    host4
    
    192.168.56.100 # 대괄호 아래 정보는 대괄호 그룹에 포함
  • 인벤토리 수동 등록
    • ansible --list-hosts all -i {$PATH}
  • 인벤토리 등록 리스트 조회
    • ansible --list-hosts all -i inv02 : 전체 호스트 확인(그룹 표현X)
      • ansible —list-hosts $(group OR host) -i $(INV_PATH) : 현재 인벤토리 파일에 특정 호스트가 있는지 확인
    • ansible-inventory --list -i inv02 : 전체 등록 호스트 확인(그룹 표현 O)

구성 파일 세팅

  • Ansible의 작동 방식을 구성하는 파일
  • 기본 위치 : /etc/ansible/ansible.cfg
    • ansible —version 으로 확인 시 config file = None 일 경우 특정 폴더를 기준으로 삼아 해당 디렉토리에 구성 파일을 등록하고 사용(이 때 ansible 명령어도 해당 디렉토리에서 실행)
  • 우선 순위 : 현재 위치 > ~ > /etc
  • 작성 예시
    # 실제 입력 시 주석 제거
    [defaults]
    inventory = inventory # 인벤토리 정보를 가진 파일명
    remote_user = vagrant # 관리 노드에서 사용할 유저명
    ask_pass = false # 원격 접속 시 password 요구 여부
    host_key_checking = false
    
    [privilige_escalation]
    become = true # 접속자와 다르게 become_user로 작업
    become_method = sudo
    become_user = root # 접속 유저
    become_ask_pass = false # sudo 사용 시 password 요구 여부
  • ansible-config view : 현재 적용된 구성 파일 내용 확인
  • ansible-config dumf : 현재 적용된 모든 구성 정보 확인
  • ansible-config list : 설정 가능한 모든 설정 항목

모듈 및 플러그인 확인

  1. ansible-doc -l : ansible의 모든 모듈 및 플러그인 목록 확인
  2. ansible-doc $(module) : 특정 모듈의 매뉴얼 확인

Ad-hoc 사용 방법

  1. 하나 이상의 관리 노드에 단일 작업을 실행하는 임시 명령
  2. 거의 반복하지 않는 간단한 작업에 주로 사용
  3. 명령 형태 : ansible [pattern] -m [module】 -a "[module options】"
    1. 패턴 : 검색 또는 실행할 호스트( ex: all, host1, host1, host2)
    2. -m : 모듈 이름
    3. -a : 모듈의 옵션/argument
    4. 예시
      1. ansible all -m ping : 인벤토리 내 등록된 모든 노드에 ping 사용
      2. ansible group01 -a "/sbin/reboot" -u vagrant -b -k
        1. -a : argument
        2. -b : =become
        3. -K : 관리자 권한 요청
        4. -u : 작업 실행할 유저

플레이북

  1. yaml 형식 사용
    1. 들여쓰기는 공백 2칸으로 지정(탭은 구문 오류 발생)

    2. 시작은 —- 끝은 … 으로 표기가 권장되나 최근 생략하는 추세

    3. 여러 줄 값을 사용 시 | 나 > 기호를 사용한다

      include_newlines: |
      							exactly as you see
      							will appear these three
      							lines of poetry
      							
      fold_nowlines: > 
      							this is really a
      							single line of text
      							despite appearances
  2. 플레이북 실행 순서
    1. 호스트 패턴과 일치하는 모든 시스템에 작업을 순서대로 실행
    2. 각 작업은 지정된 모듈 옵션을 사용해 모듈 실행
    3. 하나의 작업이 마무리되면 다음 작업으로 이동
    4. 특정 호스트에서 작업 실패 시 해당 호스트는 작업이 남아있어도 제외 후 실행
  3. 플레이북 실행
    1. ansible-playbook playbook.yaml : 실행
    2. ansible-playbook playbook.yaml --syntax-check : 플레이북 문법 체크
    3. ansible-playbook playbook.yaml -C : 플레이북 간이 체크 (작업 X)
    4. ansible-playbook playbook.yaml -C -diff --limit host1 : 차이점 모드
      1. —limit : 특정 호스트로 제한해 많은 양의 출력이 나타나지 않도록 조정
  4. 플레이북 예제
    1. file + copy 모듈

      ---
      - name: test file modules
        hosts: host1
        tasks:
          - name: file create
            file:
              path: /tmp/fileA
              state: touch
      
          - name: file copy
            copy:
              src: /tmp/fileA
              dest: /tmp/fileB
              remote_src: true # remote_src가 true인 경우 대상 hosts의 경로에서 src를 찾는다.
      
          - name: file remove
            file:
              path: /tmp/fileA
              state: absent
      
          - name: file link create
            file: 
              src: /tmp/fileB
              dest: /tmp/fileC
              state: link
      
          - name: directory create
            file:
              path: /tmp/test_dir
              state: directory
      ...
    2. user 모듈

      ---
      - name: user test
        hosts: host1
        tasks:
          - name: default user create
            user:
              name: ansible-user01
              state: present
      
          - name: uid and shell user create
            user:
              name: ansible-user02
              state: present
              uid: 2000
              shell: /bin/sh
      
          - name: group create
            group:
              name: ansible-group
              gid: 3000
              
          - name: primary group change
            user:
              name: ansible-user01
              group: ansible-group
      
          - name: secondary group change
            user:
              name: ansible-user02
              groups: ansible-group
    3. cron 모듈

      ---
      - name: test cron
        hosts: host1
        tasks:
          - name: cron job add
            cron:
              name: test cron
              weekday: "2"
              minute: "0"
              hour: "12"
              user: "root"
              job: "ls -l /tmp"
              cron_file: test_cron
      ...
    4. parted 모듈

      ---
      - name: parted test
        hosts: host1
        tasks:
          - name: partitioning
            parted:
              # part_start 생략 시 fdisk 기본값과 같은 값이 입력
              device: /dev/sdb
              number: 1
              part_end: 1GiB
              state: present
              fs_type: ext4
      ...
      
    5. nmcli 모듈

      1. IP 변경 시 연결이 끊기게 되며 이 때 Ctrl+C를 통해 인터럽트를 걸고 나와도 IP가 변경된 호스트로의 ansible 연결은 진행이 되지 않는다. ansible 관련 프로세스 중 일반적이지 않은 프로세스를 강제 종료 시킨 후 다시 ansible을 통해 확인하면 정상적으로 ansible을 사용할 수 있다.
      - name : nmcli test
        hosts: host1
        tasks: 
          - name: Change IP
            nmcli:
              type: ethernet
              conn_name: static
              ip4: 192.168.56.200/24
              state: present
              gw4: 192.168.56.255
              dns4: 8.8.8.8
              ifname: eth1
              method4: manual
      
          - name: Change dns priority /etc/hosts
            lineinfile:
              path: /etc/hosts
              line: "8.8.8.8 dns"
              state: present
      
    6. nfs 연결

      1. nfs 는 별도 모듈이 없는 것 같아 제어노드를 서버, 관리 노드 중 하나를 클라이언트로 지정해 설정
      2. 제어 노드에서의 nfs 서버 사전 설정 필요
      3. NFS-CLIENT
      - name: nfs-test
        hosts: host1
        tasks:
          - name: Install nfs-utils package
            dnf:
              name: nfs-utils
              state: latest
      
          - name: nfs enable & start
            become: true
            command: 
              cmd: systemctl enable --now nfs-server
      
          - name: mount setting
            become: true
            lineinfile: 
              path: /etc/fstab
              line: "192.168.56.100:/home/vagrant/test /home/vagrant/nfs_test nfs defaults 0 1"
              state: present
      
          - name: final mount
            become: true
            command: mount -a
      

변수

  • 변수 이름에는 문자, 숫자, 밑줄만 포함
  • 이미 예약된 플레이북, Python 키워드는 사용 불가
  • 숫자로 시작할 수 없음

변수 정의

  1. 변수를 정의할 수 있는 위치는 아래와 같다.

    1. 인벤토리
    2. 플레이북
    3. 외부 참조 파일
    4. 역할
    5. 명령의 -e 옵션
  2. 기본 변수

    1. variable: value 처럼 yaml 파일 형태의 Key:value로 지정
    # playbook.yaml
    - name: This play is webserver config
      hosts: host2
      vars:
        pkg_name: httpd
        content_file: index.html
        fw_rule: http
        fw_st: enabled
      tasks:
        - name: "{{ pkg_name }} package install"
          dnf:
            name: "{{ pkg_name }}"
            state: latest
  3. 목록 변수

    1. yaml의 목록형태로 정의, list형태로 사용 가능
    # playbook.yaml
    - name: test variables
      hosts: localhost
      vars:
        pkg_name: httpd
        region:
          - northeast
          - southeast
          - midwest
        foo:
          field1: one
          field2: two
      tasks:
          debug:
            msg: "{{ region }}"
        - name: list variable one print
          debug:
            msg: "{{ region[0] }}"
    
  4. 사전 변수

    1. 그룹 위에 기본 변수 형태로 저장해 dictionary 형태로 사용 가능
    # playbook.yaml
    - name: test variables
      hosts: localhost
      vars:
        pkg_name: httpd
        region:
          - northeast
          - southeast
          - midwest
        foo:
          field1: one
          field2: two
      tasks:
        - name: dictionary variable
          debug:
            msg: "{{ foo }}"
        - name: dictionary variable
          debug:
            msg: "{{ foo['field1'] }}"
  5. 등록 변수

    1. 실행한 모듈의 반환 값을 저장
    # playbook.yaml
    - name: register test
      hosts: host1
      tasks:
        - name: create user
          user:
            name: register_user01
            state: present
          register: debug_result
        - name: print register uid only
          debug: 
            msg: "{{ debug_result['uid'] }}"
  6. 호스트 변수

    1. 인벤토리의 호스트 별로 변수를 저장 시 사용, 같은 변수를 호스트 마다 다른 동작을 하게 할 때 편리
    2. Key: Value 형태가 아닌 Key=Value 형태로 선언
    # inventory.ini
    ctrl-node # var01=value01
    
    host1 user_name=user01 user_st=absent
    host2 user_name=user02 user_st=present
    host3 user_name=user03 user_st=present
    host4 
    
    [web]
    host[1:2] 
    
    [db]
    host[3:4]
  7. 그룹 변수 : 인벤토리의 그룹별로 변수를 저장

    ctrl-node # var01=value01
    
    host1 
    host2 
    host3 
    host4 
    
    [web]
    host[1:2] 
    
    [web:vars]
    var01=value02
    
    [db:vars]
    var01=value03
    
    [db]
    host[3:4]
  8. 플레이북에 변수 파일 포함

    1. ansible 사용 디렉토리에서 vars/external_vars.yaml 파일을 생성(폴더, 파일이름 변경 가능)

    2. 생성된 변수 파일을 플레이북에 기재

      # /var/external_var.yaml
      somevar: somevalue
      
      # playbook.yaml
      - name: other vars file
        hosts: localhost
        vars_files:
          - var/external_var.yaml
        tasks:  
          - debug:
              msg: "{{ somevar }}"
  9. 커맨드 런타임

    1. ansible-playbook 사용 시 -e(extra-vars)에 변수를 정의

      ansible-playbok playbook.yaml -e "version=1.0.0 other_var=foo"
      ansible-playbok playbook.yaml -e '{"version":"1.0.0", "other_var"="foo"}'
      ansible-playbok playbook.yaml -e "@/var/external_var.yaml"
  10. 프롬프트를 통한 변수 입력

    1. 변수 지정을 직접 하지 않고 입력받아 처리하는 변수 입력 방법
    - name: User Create with password_prompt
      hosts: host1
      vars_prompt:
        - name: username
          prompt: Enter username
          private: false
          default: admin
    
        - name: hashed_password
          prompt: Enter Password
          private: true
          encrypt: sha512_crypt
          confirm: true
          salt_size: 16
      tasks:  
        - name: Create user
          user: 
            name: "{{ username }}"
            password: "{{ hashed_password }}"

필터

변수에 기본값 제공 혹은 형식 변환하며 | 를이용해 필터 지정

  1. 기본값

    - name: test filter
      hosts: host1
      tasks:
        - debug:
            msg: "{{ var01 | hash('sha256') }}"

팩트

ansible_ 로 시작하는 변수로 이루어진 운영체제, IP 주소, NIC 정보, 디스크 장치 등의 관리 노드와 관련된 정보를 가진 변수

  • 모든 관리 노드의 팩트 변수 확인 → ansible all -m setup
  • 팩트 수집 비활성화
  • playbook에 팩트 수집을 비활성화 하면 setup 모듈을 이용한 팩트 변수 수집을 넘겨 바로 다음 작업을 진행할 수 있다.(default는 팩트 수집 활성화)
  • 팩트 모음을 debug 모듈로 확인해봤을 때 대상인 host의 팩트 정보만을 가져오는 것을 확인
    • 특정 host의 hostname을 조건으로 작업 시 loop를 사용하면 안되고(=하나의 값) 단일 팩트로 조건 지정을 하면 host 작업 시 해당 host가 가진 fact로 변경된다.

    • name: fact test
      hosts: all
      gather_facts: false
      tasks:
      - name: print ifname
      debug:
      msg: "{{ ansible_eth1['ipv4']['address'] }}"
      - name: custom fact print
      debug:
      msg: "{{ ansible_local }}"

  • 사용자 정의 팩트
    • 각 호스트별 사용자가 직접 정적 팩트 변수를 선언 가능
    • 관리 노드는 보통 ansible을 설치하지 않기 때문에 수동으로 지정 위치에 .fact 확장자로 팩트 파일을 생성한다.
    • 제어 노드에서 ansible_local 변수를 출력하면 해당 호스트의 사용자 정의 팩트로 선언한 변수를 확인할 수 있다.
      # /etc/ansible/facts.d/reference.fact
      [general]
      foo=1
      bar=2

템플릿

Python의 웹 템플릿 엔진인 Jinja2 를 사용할 수 있기 때문에 jinja 문법으로 파일을 작성하고 ansible로 작업을 한다면 반복적인 작업을 훨씬 편하게 사용할 수 있다.

{{  ansible_managed | comment }}
{# /etc/hosts line #}
{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}

반복문

변수로 지정된 리스트, 딕셔너리처럼 반복되는 요소를 이용해 for문을 사용하는 것처럼 ansible-playbook에 반영이 가능하다

  • loop의 요소는 파이썬의 for문처럼 직접 지정하는게 아닌 item 으로 고정된다.
  • 사용 예
    - name: test loop
      hosts: host1
      vars:
        user_list: [ "testuser5", "testuser6" ]
      tasks:
          - name: add user item_list
    	      user:
    	        name: "{{ item }}"
    	        state: present
    	        groups: wheel
    	      loop: "{{ user_list }}"
    	      
          - name: add several users dict
    	      user:
    	        name: "{{ item.name }}"
    	        groups: "{{ item.groups }}"
    	        state: present
    	      loop: 
    	        - {name: "testuser7", groups: 'wheel' }
    	        - {name: "testuser8", groups: 'vagrant' }

조건문

변수 값을 이용해 작업의 상태를 변경할 수 있는 기능

  • 평소 변수를 사용하는 것과 다르게 조건문에서는 변수명에 {{ }} 이중 중괄호를 사용하지 않는다.
  • $(변수) is $(비교값) → 해당 변수가 비교값과 동일한지 확인
  • ==, >, ≤, gt, ge, lt 처럼 기존에 사용하던 다양한 연산자를 사용할 수 있다.
  • 사용 예(조건문 + 반복문)
    - name: control fact
      hosts: all
      vars:
        user_list: ["user01", "user02", "user03"]
      tasks: 
        - user:
            name: "{{ item }}"
            state: absent
          when:  ansible_facts['hostname'] == "host2"
          loop: "{{ user_list }}"

Handler

작업 실행 후 시스템의 변경이 있을 때 별도의 작업을 호출 후 실행

  • DB의 트리거와 비슷한 역할
  • tasks와 같은 레벨
  • 주로 특정 서비스의 구성 파일이 변경된 경우 서비스를 재시작
  • 작업(=play)에 변경(=Changed)이 존재하며 알림(Notify) 가 있을 때만 실행
  • 핸들러의 이름 = 알림의 이름인 경우에만 알림이 핸들러로 전송
  • 작업과 핸들러 실행 순서
    • 작업 → 알림 전송 → 핸들러 실행

    • 핸들러는 알림의 순서가 아닌 yaml 파일의 순서대로 진행

    • 둘 이상의 핸들러 작업의 이름이 같은 경우 알림은 마지막 핸들러 작업을 실행

    • name: Verify apache installation
      hosts: host1
      vars:
      http_port: 443
      max_clients: 200
      tasks:
      - name: Ensure apache is at the latest version
      dnf:
      name: httpd
      state: latest

      - name: Write the apache config file
        lineinfile:
          line: Listen {{ http_port }}
          regexp: ^Listen 80
          path: /etc/httpd/conf/httpd.conf
        notify:
          - Restart apache

      handlers:
      - name: Restart apache
      service:
      name: httpd
      state: restarted

Delegate(위임)

delegate를 사용하면 플레이 또는 일부 작업을 제어 노드나 다른 관리 노드에서 실행 할 수 있도록 해준다.

  • include, add_host, debug는 위임이 불가하며 제어 노드에서만 동작한다.
  • 작업(=play) 단위로 지정하며 delegate_to 키워드를 통해 호스트를 지정
  • 제어노드에 작업을 위임 시 detegate_to: localhost 대신 local_action: 키워드를 사용
    - name: test delegate
      hosts: host1
      tasks:
        - name: create file
          file: 
            name: /tmp/test_delegate
            state: touch
          delegate_to: host2

Block

  • 작업(=play)에 하나 이상의 작업을 논리적 그룹화
    • 2개의 작업에 같은 조건문이 필요한 경우 하나의 블록으로 묶고 조건문을 하나만 주는 것
    • 블록에 구성된 키워드는 블록 내 모든 작업에 공통 적용
  • 블록 단위의 예외 처리
    • Rescue(=실패 처리)

      • 블록 작업 중 하나라도 실패가 존재하면 rescue 구문이 실행
      • 파이썬의 except와 유사
    • always(=무조건 실행)
      - 작업의 실패, 성공과 관계없이 무조건 실행되는 구문
      - 파이썬의 finally와 유사

    • name: test block
      hosts: all
      tasks:
      - name: package and service block
      block:
      - name: package install
      dnf:
      name: nfs-utils
      state: latest

          - name: service start
            service:
              name: nfs-server
              state: started
              enabled: true
              
        when: ansible_hostname == "host1"
        
        rescue: 
          - debug:
             msg: This is rescue 
        always:
          - debug:
              msg: This is always

태그

많은 작업을 가진 플레이북에서 작업이나 블록 별로 태그를 부여해 플레이북 실행 시 태그를 기준으로 작업에 대한 진행을 조절할 수 있다.

ansible-playbook --tags all $(playbook) : 모든 작업 실행(=default)

ansible-playbook --tags [tag1, tag2] $(playbook) : 특정 태그만 실행

ansible-playbook --skip-tags [tag1, tag2] $(playbook) : 특정 태그 작업 건너뛰기

ansible-playbook --tagged $(playbook): 태그가 설정된 작업만 실행

ansible-playbook --untagged $(playbook) : 태그가 없는 작업만 실행

ansible-playbook --list-tags : 사용 가능한 태그 목록 확인

ansible-playbook --list-tasks : --tags--skip-tags 옵션과 함께 사용 시 관련 작업 목록 확인

  • 특수 태그
    • always, never 2개의 태그 이름이 예약되어 있어 해당 태그 이름은 사용 금지
    • always : --skip-tags 명령으로 명시되는 경우를 제외하고 항상 실행
    • never : --tags never 명령으로 명시적으로 태그를 실행하는 경우를 제외하고 항상 실행되지 않음

작업 오류 처리

  • ignore_errors - Play 레벨
    • 플레이북 진행 중 일부 플레이가 오류가 나면 이후 플레이 진행을 멈추는데 이때 오류나는 부분을 멈추지 않고 진행 시킬 수 있도록 해주는 옵션(T,F)
    • 리턴 코드가 0이 아닌 경우에 동작
    • 변수 오류, 연결 실패, 실행 문제, 구문 오류는 리턴 코드가 0이 나오지 않기 때문에 작업 오류처리로 실행 할 수 없다.
  • ignore_unreachable - Play 레벨
    • 관리 노드에 연결할 수 없을 때 연결 실패를 무시하고 실패하는 경우 사용(T,F)
  • force_handlers - playbook 레벨
    • 핸들러는 플레이북의 플레이들이 모두 동작 후 호출을 확인 후 동작하기 때문에 중간에 플레이가 에러 때문에 실행되지 않는다면 핸들러도 동작하지 않는다.
    • force_handlers를 true 로 입력하면 play 오류와 관계없이 핸들러를 실행할 수 있다.(T,F)
    • 순서를 무시하는 작업이 아니며 play 오류로 인한 작업이 중단 되기 전의 핸들러 호출 작업이 있는 경우만 유효
  • failed_when - play 레벨
    • 작업이 성공/실패 여부를 강제적으로 결정해 이후 작업을 진행한다. (T,F)
    • True인 경우 작업이 실패, False는 작업 성공
    • 여러 조건을 리스트 형태로 입력 시 and 조건을 만족 시켜야 하며 or 조건으로 변경하려면 리스트 형태가 아닌 조건문 사이를 or를 사용해야 한다.
  • changed_when - play 레벨
    • failed와 비슷한 형태로 change를 제어
  • any_errors_fatal- playbook 레벨
    • 특정 작업 실패 시 모든 플레이를 중단 시킬 수 있다.(T,F)
  • max_fail_percentage - playbook 레벨
    • 실패율을 입력하고 전체 플레이에 비례해 작업 실패율이 지정한 실패율에 도달할 경우 플레이가 중단된다.

전략 및 롤링 업데이트

Ansible은 기본적으로 5개의 포크(Fork)를 사용해 하나의 작업을 동시에 5개의 호스트에서 실행

ansible-playbook linear.yaml -f 2 : -f는 포크의 개수(=동시처리 수) 를 조절 가능

Serial 과 Fork

serial : 한번에 작업을 처리할 호스트의 수

fork : 플레이를 실행 할 때 한 호스트당 한번에 처리할 작업의 수

Linear 전략

  • Ansible의 전략의 Default로 설정
  • 작업 실행 시 serial(기본값: all)에 정의된 대로 호스트를 배치
  • 하나의 작업은 fork의 한계까지 동시 실행
  • 플레이를 실행해야하는 모든 호스트가 작업을 완료하면 다음 플레이 실행

자유 전략

  • 특정 호스트가 특정 작업에 대해 시간이 오래 걸리거나 멈춘 경우 다른 호스트가 완료될 때까지 기다리지 않는다.

호스트핀 전략

  • 자유 전략과 거의 동일하나, 다음 플레이가 있는 경우 해당 플레이의 모든 호스트의 작업이 완료될 때 까지 기다린다

디버깅 전략

  • 디버그(debug) 전략은 선형 전략을 사용하고, 대학형 디버깅 세션에 의해 제어.

작업 실행 제한

throttle : play 레벨, 블록 레벨

  • 의도적으로 작업 실행에 제한을 둘 때 사용
  • 작업 fork나 serial 보다 작아야 한다.

비동기

Ansible은 작업을 기본적으로 동기식으로 수행한다.

  • 동기식 작업 시 여러 호스트에 대해 play를 수행 시 작업이 지연될 경우 ssh 연결에 대한 타임아웃이 발생 할 수 있음.

비동기 Ad-hoc 명령

  • -B or --background : 비동기 실행 작업의 타임아웃 시간 설정
  • -P or --pool : 비동기 작업을 실행 시 작업 사이의 시간 간격(=default 15초)
  • ansible host1 -B 600 -P 0 -a "sleep 1M" : 실행 작업의 타임아웃 10분, 풀링 없음
  • ansible host1 -m async_status -a jid=$(jobid Number)

아티팩트 재사용

객체지향 프로그래밍처럼 ansible에서도 만들어둔 변수, 작업, 플레이북, 역할 파일을 참조해 작업을 작성할 수 있으며, 이를 통해 ansible 플레이북의 유지보수의 용이성과 재사용성을 높일 수 있다.

변수 재사용

  • vars_files 키워드, include_vars 모듈을 이용해 외부 변수 파일 참조
  • Ansible은 현재 ansible 실행 디렉토리의 group_vars/, host_vars/ 디렉토리의 yaml 형식의 변수 파일을 가져올 수 있으며 이 때 별도의 플레이북 키워드나 모듈을 사용하지 않아도 변수를 읽어들일 수 있다.

작업 재사용

  • include 모듈
    • include - 플레이 전체 or 일부 작업 참조
    • include_role - 역할 참조
    • include_tasks - 작업 참조
    • include_vars - 변수 파일 참조
  • import 모듈
    • import_playbook - 플레이북 전체 참조
    • import_role - 역할 참조
    • import_tasks - 작업 참조
  • include, import 비교
항목includeimport
재사용 형식동적정적
처리 시점모듈 실행 시플레이북 파싱 시 전처리
작업 옵션작업 자체를 포함하는 경우만모든 가져오기 모듈 적용 가능
반복문 호출OX
태그 및 작업 목록 확인XO
핸들러 호출파일 내 작업 이름 호출 X파일 내 작업 이름 호출 O
작업 시작XO
플레이북 전체 가져오기XO
변수 파일 가져오기OX

역할 재사용

역할 - 표준화된 디렉토리 및 파일 구조를 기반으로 변수,작업, 핸들러, 템플릿 등을 구조화

  • ansible-galaxy init role $(role) : 롤 기반의 표준화된 디렉토리 및 파일 구조를 생성
  • 역할 참조 순서
    1. 플레이북 파일이 있는 경로의 roles 디렉토리
    2. 홈 디렉토리의 ~/.ansible/roles 디렉토리
    3. /usr/share/ansible/roles 디렉토리
    4. /etc/ansible/roles 디렉토리
  • 플레이북의 역할 참조 순서
    • pre_tasks 의 작업
    • pre_tasks 의 핸들러
    • role의 작업
    • tasks의 작업
    • roles 및 tasks의 핸들러
    • post_tasks 의 작업
    • post_tasks 의 핸들러
  • ansible-galaxy : 다른 사용자 및 커뮤니티에서 개발한 역할, 컬렉션, 플레이북 번들을 찾고 다운로드 및 공유할 수 있는 무료 서버
    • ansible-galaxy role search <ROLE> : 역할 검색 시 태그, 플랫폼, 작성자로 검색
      • ansible-galaxy role search elasticsearch --author <SOMEONE> : 역할과 작성자로 검색
      • --platform : 플랫폼
      • --author : 작성자
      • --galaxy-tags : 태그
    • ansible-galaxy role info <ansible galaxy user>.role_name : 특정 유저의 역할 정보 확인
    • ansible-galaxy role install <ansible galaxy user>.role_name : 역할 설치
    • ansible-galaxy role remove <ansible galaxy user>.role_name : 설치된 역할 제거

암호화

Ansible Vault는 플레이북 또는 변수 파일을 암호화 하거나 변수 값을 암호화하여 민감한 콘렌츠를 보호 할 수 있다

  • 암호화 가능 대상 : ansible.cfg 뺀 모든 파일
  • ansible-vault --vault-password-file <source>
    • 패스워드 파일을 이용해 사용 할 단일 볼트 패스워드
  • Vault ID 및 멀티 볼트 패스워드
    • Vault ID 를 통해 별도의 대상에 볼트 패스워드를 지원한다.(=파일 별로 볼트 패스워드 지정 가능)
    • ansible-vault, ansible-playbook 사용 시 —vault-id 옵션을 사용 가능
    • vault-id 형식
      • --vault-id label@source
        • label = vault에 대한 구분값(=금고 이름)
        • source = 레이블에 비밀번호를 입력하기 위한 소스
          • 파일명
          • 프롬프트(=prompt) - 대화형으로 패스워드를 입력
          • 스크립트 파일명
    • ansible-vault encrypt --vault-id <label>@<source> <filename>
      • 이미 만들어진 파일을 암호화
    • ansible-vault decrypt --vault-id <label>@<source> <filename>
      • 이미 만들어진 파일을 복호화
    • ansible-vault create --vault-id <label>@<source> <filename>
      • 파일을 직접 생성하고 내용을 작성 후 암호화
    • 일부 콘텐츠 암호화
      • ansible-vault encrypt_string --vault-id <label>@prompt 'abcd'
        • 위 명령어 실행 시 abcd가 암호화된 형태로 출력된다.
        • 출력된 내용을 변수의 값으로 붙여넣기한다.
        • ansible-playbook --vault-id <label>@prompt playbook.yml 을 입력 후 패스워드를 입력하면 암호화된 변수의 값이 복호화 되어 화면에 출력된다.
    • Argument
      • view - 보기
      • rekey - 암호화 패스워드 재지정
      • edit - 수정

0개의 댓글