작성일:

Ansible-101

Ansible Install

  • Centos 7
    • 기본적으로 Python 2.7 기반으로 설치 됨
    • 추후 pywinrm 패키지가 필요할때, python2-pip 패키지 추가 설치 필요
      sudo yum install ansible
      
  • 대안으로 pip 으로 설치 하는 방법 (user)
    pip install ansible # --user 
    

용어 정의

  • Inventory : 관리하는 원격 서버 목록
    • 지정하지 않으면 Default Path 의 hosts 파일을 참조
      • /etc/ansible/hosts
  • Module : Task 를 실행하는 방법 (모듈)
  • Playbook : Task 실행 프로세스 정의서
    • Yaml 파일로 작성
  • 멱등성(idempotence) : 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다.

Ansbile Config

[defaults]
host_key_checking = False

Inventory 구성

  • Public key 등록 사용 방법 : 키를 생성하고 public 키를 관리되는 서버에 등록 후 사용
# Key 생성 
ssh-keygen

# Public key 등록
ssh-copy-id [server-ip] 
# ansible host 파일 예제

192.168.1.5

[db]
192.168.1.10

[webservers]
192.168.1.100
192.168.1.110

# hosts 파일에 등록된 경우 
[apiserver]
apiserver1
apiserver2

# host명으로 등록
server1		ansible_host=192.168.1.50
server2		ansible_host=192.168.1.51

  • Host 지정 방법
    • all : 해당 Inventory의 모든 서버
    • webservers : webservers 라고 정의된 서버 목록
    • 192.168.1.100 : 192.168.1.100 서버

Ad-hook Execute

  • ansible 명령을 통한 inline 실행
  • 주요 인수
Usage: ansible <host-pattern> [options]
  -a MODULE_ARGS, --args=MODULE_ARGS   module arguments                                                                   
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
    set additional variables as key=value or YAML/JSON, if filename prepend with @  
  -f FORKS, --forks=FORKS 
      specify number of parallel processes to use (default=5)                                                                        
  -h, --help            show this help message and exit                                                     
  -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY                                           
      specify inventory host path or comma separated host                                
      list. --inventory-file is deprecated                                               
  -m MODULE_NAME, --module-name=MODULE_NAME                                                                 
      module name to execute (default=command)                                           
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable connection debugging)                                                              
  --version             show program's version number, config file location,                                
      configured module search path, module location,                                    
      executable location and exit                                                       
  -b, --become        run operations with become (does not imply password prompting)                                                                         

- Example

  • hostname 확인
# webservers 목록 실행 
# command 모듈, "hostname" 인수
ansible webservers -m command -a "hostname" 

# default module (생략가능) : -m command   
ansible webservers -a "hostname" 

# 모든 서버
ansible all -a "hostname" 
  • 기타 모듈 사용
# ping 모듈 
ansible webservers -m ping

# copy 모듈 : local → host 
ansible webservers -m copy -a "src=file.txt dest=/home/cdecl/web/"

# service 모듈 : kubelet 서비스를 시작 
ansible webservers -m service -a "name=kubelet state=started"

Playbook 사용

일련의 Task(작업)를 기술하여, 프로세스를 실행하는 방법

  • 간략한 설명
    • name : 작업을 설명하는 식별자 (주석, 생략가능)
      • 모듈 내에서의 name 은 다른 의미
    • gather_facts : (yes no ) Gathering Facts 작업 실행 및 생략
      • Facts : 작업 시작전 Host 의 Name, CPU, Memory 등을 수집하는 Setup 모듈
    • hosts : Inventory 내의 hosts 지정
    • tasks : 작업 목록들 (배열)
    • register : 작업을 해당 이름으로 등록, debug 항목에서 표준 출력을 받아오기 위해 사용
    • debug : debug 용 작업들 (msg, stdout 출력)
    • become : root 권한으로 실행
    • become_user : sudo 를 통해 실행할 계정
    • 변수값 평가 : “ {{ 변수 }} “
      • -e 파라미터를 통해 전달 가능

- Example

  • Ping 모듈 테스트
- name: ping test 
  hosts: webservers
  gather_facts: no
  tasks:
    - ping:
ansible-playbook ping.yml
  • Shell 모듈 : out 이란 이름으로 작업을 등록
- name: get hostname
  hosts: localhost
  tasks:
    - shell: "hostname"
      register: out  # out 이란 이름으로 작업을 등록 
    
    - debug: "var=out.stdout_lines"  # out 의 stdout 을 모두 출력 
> ansible-playbook hostname.yml

localhost | CHANGED | rc=0 >>
centos24

localhost | SUCCESS => {
    "out.stdout_lines": [
        "centos24"
    ]
}
  • Service 모듈
- name: nginx service start
  hosts: localhost
  # gather_facts: no
  tasks:
    - service: # nginx 서비스를 시작
        name: nginx
        state: started
#       - service: "name=nginx state=started"  #  inline 으로 표현 가능
      become: yes  # root 권한 실행
> # changed=1 : 상태 변화 있음 
> ansible-playbook nginx.yml

PLAY [nginx service start] 
TASK [service] ************changed: [localhost]
PLAY RECAP ****************localhost                  : ok=1    changed=1    unreachable=0    failed=0


> # changed=0 : 상태 변화 없음 → 이미 started 상태 
> ansible-playbook nginx.yml

PLAY [nginx service start] 
TASK [service] ************changed: [localhost]
PLAY RECAP ****************localhost                  : ok=1    changed=0    unreachable=0    failed=0
  • Loop (with_items) 및 변수 (vars) 활용
- name: test 
  hosts: localhost
  gather_facts: no
  vars:
    SERVER_IP: 10.20.10.20 
  tasks:
    
    - name: test
      shell: |
        echo docker run -d --name={{item.name}} -p {{item.port}}:80 \
          -e SERVER_IP={{SERVER_IP}}  
      with_items:
        - { name: "tomcat01", port: "8001" }
        - { name: "tomcat02", port: "8002" }
        - { name: "tomcat03", port: "8003" }
        - { name: "tomcat04", port: "8004" }
      register: out

    - debug: 
        msg: "{{ item.stdout_lines }}"
      with_items: "{{ out.results }}"


Tags 활용

- name: tags test
  hosts: localhost
  tasks:
    - shell : echo step 1
      register: out
      tags: 
        - step1
    - debug : var=out.stdout_lines
      tags: 
        - step1

    - shell : echo step 2
      register: out
      tags: 
        - step2
    - debug : var=out.stdout_lines
      tags: 
        - step2

    - shell : echo step 3
      register: out
      tags: 
        - step3
    - debug : var=out.stdout_lines
      tags: 
        - step3
# Setp2 tags 만 실행 
> ansible-playbook test.yml --tags "step2"

ok: [localhost] => {
    "out.stdout_lines": [
        "step 2"
    ]
}

Windows Host 사용

# host 설정 : Service Enable 
winrm qc 

# 인증 및 AllowUnencrypted 설정 
winrm set winrm/config/service/Auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}'
# winrm 을 사용하기 위한 python 모듈 설치 
pip install pywinrm   # --user 
  • Inventory 구성
[win]
192.168.28.25

[win:vars]
ansible_user=rundeck
ansible_password=<passowrd>
ansible_connection=winrm
ansible_port=5985  
# ansible_winrm_server_cert_validation=ignore
- name: ping test 
  hosts: win
  gather_facts: no
  tasks:
    - win_ping:
    
- name: Install git from a pre configured source (win_chocolatey_source)
  hosts: win
  tasks:
    - win_chocolatey:
        name: git

Ansible Facts

  • Facts : 원격서버(Node)로 부터 수집한 정보를 담고 있는 변수
# 원격서버 Facts 확인
> ansible hostname -m setup 

kubem | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.244.0.0",
            "10.244.0.1",
            "192.168.137.108",
            "172.17.0.1"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::e04c:baff:fe78:2e93",
            "fe80::b8f6:d7ff:fecc:4c91",
            "fe80::f8e5:7ff:fe0f:6b60",
            "fe80::48b8:90ff:fede:71cf",
            "fe80::8aa8:d266:54e5:1608",
            "fe80::2918:237b:3860:3272"
        ],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "11/26/2012",
        "ansible_bios_version": "Hyper-V UEFI Release v1.0",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-957.1.3.el7.x86_64",
            "LANG": "ko_KR.UTF-8",
            "crashkernel": "auto",
            "quiet": true,
            "rd.lvm.lv": "centos/swap",
            "rhgb": true,
            "ro": true,
            "root": "/dev/mapper/centos-root"
        },
...                                                       
  • ansible_distribution 필터링
    • OS 구분시 유효
> ansible win -m setup -a "filter=ansible_distribution*"

kube02 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "7",
        "ansible_distribution_release": "Core",
        "ansible_distribution_version": "7.6.1810"
    },
    "changed": false
}
kube01 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "7",
        "ansible_distribution_release": "Core",
        "ansible_distribution_version": "7.6.1810"
    },
    "changed": false
}
kubem | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution": "CentOS",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "7",
        "ansible_distribution_release": "Core",
        "ansible_distribution_version": "7.6.1810"
    },
    "changed": false
}
192.168.28.25 | SUCCESS => {
    "ansible_facts": {
        "ansible_architecture": "64비트",
        "ansible_bios_date": "11-10-2015",
        "ansible_bios_version": "P89",
        "ansible_date_time": {
			....
        },
        "ansible_distribution": "Microsoft Windows Server 2016 Standard",
        "ansible_distribution_major_version": "10",
        "ansible_distribution_version": "10.0.14393.0",

...

Ansible Facts

  • OS 구분에 따른 필터링
    • when 구문 사용

- name: nginx
  hosts: localhost
  tasks:
    - service:
        name: nginx
        state: started
      become: yes        
      when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6'

    - systemd:
        name: nginx
        enabled: yes
        state: started
      become: yes        
      when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'


참고

댓글남기기