44/120

Ansible

용어

제어노드

Control Node, Controller, Ansible Engine
앤서블이 설치되는 시스템

  • 컨트롤러
    조건: Uinx 계열만 가능
    윈도우 시스템이 제어노드가 될 수 없음 -> 왜? 앤서블은 ssh사용 기본적으로 통신방식, 윈도우는 ssh를 사용하지 않음
    파이썬이 설치되어 있어야 함 (앤서블이 파이썬으로 만들어져 있어서)

관리노드

Managed Node, Target Node/Host ...

BM, VM, Instance, Network Device
조건 : 윈도우, 리눅스 상관 없음

  • SSH가 가능한 모든 시스템
  • Python 설치(모든 시스템이 설치 되어있음 except for Windows)
  • Windows : WinRM(Windows Remote Management) 앤서블의 확장프로그램

인벤토리

관리 노드의 목록을 가지고 있는 파일(?)
~.ini


정적 인벤토리 : 관리 노드의 목록 파일
동적 인벤토리 : 클라우드, CMDB에서 관리 노드 목록 가져옴
도커, 컨테이너 생명주기가 짧을 수 없음 -> 정적으로 관리 쉽지 않음, 목록을 텍스트로만 관리하는게 쉽지 않음

플러그인

사용하면 ssh 아니여도 시스템관리 가능
Ansible 기능 확장

모듈

Ansible 작업 실행 할 수 있는 기본 단위
Python Code로 만들어져 있음

Ad-hoc(임시라는 뜻)

Ansible 임시 실행
하나의 모듈을 실행 가능

테스크(Task)

하나의 모듈을 실행 -> 하나의 테스크(작업)

플레이

하나 이상의 테스크의 모음

플레이북

하나 이상의 플레이 모음(파일 .yaml)
이 파일안에 여러개의 플레이가 있을 수 있음
하나의 플레이에는 여러 개의 테스크

인벤토리

https://docs.ansible.com/
https://docs.ansible.com/ansible_community.html
여기 용어가 많음
인벤토리 문서

default location : /etc/ansible/hosts

[vagrant@controller ~]$ cd /etc/ansible/
[vagrant@controller ansible]$ ls
ansible.cfg  hosts  roles

다른 인벤토리 사용하기 위해선 -i <path>로 잡아줘야 함

hosts안에는 처음에는 전부 주석

앤서블을 사용하기 위한 전략
회사에 다루는 사람 혼자라면 상관x -> 근데 여러명 앤서블로 자동화

  • 컨트롤러 여러개로 따로따로 관리를 할 것인가
  • 관리할 노드 여러개 쭉 있고, 앤서블 컨트롤러 한 대만 두고 여러명의 사람이 SSH 접속을 통해 한대의 컨트롤러로 사용을 할 것인가

후자의 경우 인벤토리 파일을 사용하는게 유리

  • etc 디렉토리는 시스템 전체에 관련된 설정 : 누가 접속하더라도 똑같은 설정
  • home디렉토리에 설정 : 사용자별로 설정 적용

etc 필요할때도 있지만 사용해선 안되는 경우가 있음
---> 기본 인벤토리 파일은 사용하지 않는 것을 선호함

홈 디렉토리 존재의의 이유 : 루트를 제외하면 다른사람 홈디렉토리의 접근 불가 -> 개별공간

기본 위치에 있는 인벤토리 파일이 아닌 경우 : -i 옵션 사용

인벤토리 파일 만드는 법

인벤토리 만드는 포맷

  1. ini : 일반적으로 선호, 훨씬 더 간단, 포멧은 일반적으로 ini로 생성
  2. yaml : playbook 생성 시,

변수 설정

변수를 설정할때 = equal 을 사용
대괄호는 설정들을 분류하기 위해 만듬 [] = Section

key=value

[Section]
key=value
key # value 없이 key만 있는 경우

yaml은 들여쓰기와 띄어쓰기가 굉장히 중요-> 굉장히 귀찮음 -> 일반적으로 ini
playbook 생성시 대체할 것이 없음

FQDN : 호스트와 도메인을 함께 명시하여 전체 경로를 모두 표기하는 것

예제

mail.example.com # manage node

# 그룹
[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

ansible 명령 시, 관리노드명 말고 그룹명 지정도 가능

  • [ ] : 인벤토리 그룹

원칙 : 하나의 노드는 하나의 그룹에만 속해야 한다->X ==> 하나의 노드가 여러 개의 그룹에 속할 수 있음 -> 노드와 그룹은 1:1은 아니다

all: # 그룹
  hosts: # 지시어 (그룹이 없는 관리노드)
    mail.example.com:
  children:
    webservers: ## 그룹
      hosts:
        foo.example.com:
        bar.example.com:
    dbservers:
      hosts: # 호스트 목록
        one.example.com:
        two.example.com:
        three.example.com:

그룹이 그룹을 가질 수 있는다 : 네스티드 그룹, 중첩 그룹
children all 그룹에서 가질수 있는 그룹
--> 사실 귀찮음 쓰지말자.. ini 최고!

Default Gruops

정의하지 않아도 존재하는 그룹

  • all : 인벤토리 파일의 있는 모든 호스트 노드
  • ungrouped : 그룹이 없는 잘 쓰이지 않을 수 있음

주의
인벤토리 생성 원칙
간결하게...

복잡하게 만들면 모든 오류의 주된 원인은 사람, 인벤토리 파일을 만드는 것도 사람
그룹이 그룹을 가지고.. 그룹밑에 호스트가 지정할대 잘못된 그룹 지정하면 오류-> 설정되면 안되는 시스템에 설정이 된다거나 설정이 되어야할 시스템에 안되는 경우
실제로 IaC에서 많은 경우가 발생

예시로 넷플릭스 모든 시스템 관리 IaC임
서비스 안되던 시간 IaC 변수 설정 잘못해서 라우팅 테이블 세팅이 안되어서 생긴 오류들

그룹 만들때(그룹에 호스트를 분류할 때)

  • What - An application, stack or microservice (for example, database servers, web servers, and so on).
  • Where - A datacenter or region, to talk to local DNS, storage, and so on (for example, east, west).
  • When - The development stage, to avoid testing on production resources (for example, prod, test).
    개발한 코드를 실제 바로 올리는게 아니라, 개발 서버 스테이지 서버 프로덕션 서버에 올리는 경우도 있음

가장 많은 형태는 application단위로 구분

Adding Rages of hosts

호소트의 범위 레인지를 지정할때

연속적인 이름을 가지고 있는 경우
inventory.ini

[webservers]
www[01:50].example.com
192.168.100.[10:19]
[webservers]
www[01:50:2].example.com

01에서 50까지 2씩 증가

Q.범위를 지정했는데 호스트가 아직 없어도 에러는 안뜨나요?
A. 전부 다 있어야함 -> 전부 ssh 접속을 시도 -> 동적으로 사용하는게 좋음

변수를 설정
변수를 쭉 나열 가능

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

인벤토리 변수

[atlanta]
host1 
host2

[atlanta:vars] # 그룹에 vars 그룹에 변수를 지정하는
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

vars 안쓰면

host1 ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

일일이 다해야함

중첩그룹

[atlanta]
host1
host2

[raleigh] # 레드햇의 본사
host2
host3

[southeast:children] 
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

children 없으면 host 있으면 그룹명이 들어와야함

usa그룹도 하위에 children 그룹을 가지고 있음
칠드런 있으면 무조건 그룹

사실 위코드는 오류, 정의가 안 되어 있기 때문에

나중에 변수들은 특수한 용도들을 가지고 있는 변수

Connecting to hosts: behavioral inventory parameters

인벤토리 파일 구조를 볼 수 있음

인벤토리 파일 확인

생성한 인벤토리 파일 계층 확인

ansible-inventory -i <INVENTORY_FILE> --graph
[vagrant@controller ~]$ ansible-inventory -i b.ini --graph
@all:
  |--@ungrouped:
  |--@usa:
  |  |--@southeast:
  |  |  |--@atlanta:
  |  |  |  |--host1
  |  |  |  |--host2
  |  |  |--@raleigh:
  |  |  |  |--host2
  |  |  |  |--host3

--list 하면 json파일 형식으로

_meta내용은 변수

Json 형식 및 호스트/그룹 변수

ansible-inventory -i <INVENTORY_FILE> --list
 [vagrant@controller ~]$ ansible-inventory -i b.ini --list
{
    "_meta": {
        "hostvars": {
            "host1": {
                "escape_pods": 2,
                "halon_system_timeout": 30,
                "self_destruct_countdown": 60,
                "some_server": "foo.southeast.example.com"
            },
            "host2": {
                "escape_pods": 2,
                "halon_system_timeout": 30,
                "self_destruct_countdown": 60,
                "some_server": "foo.southeast.example.com"
            },
            "host3": {
                "escape_pods": 2,
                "halon_system_timeout": 30,
                "self_destruct_countdown": 60,
                "some_server": "foo.southeast.example.com"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "usa"
        ]
    },
    "atlanta": {
        "hosts": [
            "host1",
            "host2"
        ]
    },
    "raleigh": {
        "hosts": [
            "host2",
            "host3"
        ]
    },
    "southeast": {
        "children": [
            "atlanta",
            "raleigh"
        ]
    },
    "usa": {
        "children": [
            "southeast"
        ]
    }
}

호스트에 설정된 변수 확인

ansible-inventory -i <INVENTORY_FILE> --host <HOST>
{}

[vagrant@controller ~]$ ansible-inventory -i b.ini --host host1
{
    "escape_pods": 2,
    "halon_system_timeout": 30,
    "self_destruct_countdown": 60,
    "some_server": "foo.southeast.example.com"
}

빈칸은 호스트의 있는 변수 목록이 나오는 공간

호스트의 목록을 확인하는 명령어(호스트 매칭 확인)

ansible <HOST_PATTERN> -i <INVENTORY_FILE> --list-hosts
[vagrant@controller ~]$ ansible host1 -i b.ini --list-hosts
  hosts (1):
    host1
[vagrant@controller ~]$ ansible atlanta -i b.ini --list-hosts
  hosts (2):
    host1
    host2

구성파일

앤서블을 어떻게 작동시킬 수 있는지 설정파일
https://docs.ansible.com/ansible/latest/reference_appendices/config.html
미리 설정하면 매번 반복적인 옵션을 지정하지 않아도 됨

설정파일 위치

  1. ANSIBLE_CONFIG (environment variable if set)
  2. ansible.cfg (in the current directory)
  3. ~/.ansible.cfg (in the home directory)
  4. /etc/ansible/ansible.cfg 기본 설정 파일
    1번이 우선순위 제일 높음

똑같은 설정파일이 있다고 할 때,
-u ec2-user 미리 계정을 설정 해둘 수 있음 3,4 에도 할 수있고 근데 3,4 ,에 내용이 다를 때 3번이 우선순위가 더 높음. 같은 설정에 대해 어디가 우선순위가 높은지

  • 1번은 잘 쓰지 않음, 환경변수 설정파일의 위치를 지정

디렉토리와 관계없이 지정되어 있으면 지정 됨
[vagrant@controller ~]$ touch /tmp/a.cfg
[vagrant@controller ~]$ export ANSIBLE_CONFIG=/tmp/a.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
  config file = /tmp/a.cfg
[vagrant@controller ~]$ unset ANSIBLE_CONFIG # 환경변수 해제
  • 2번 현재디렉토리의 설정파일 ansible.cfg 현재 작업하고 있는 디렉토리의 위치
    vagrant파일이랑 비슷함 아니 똑같음 playbook 파일이 여러개 있을 수 있음
    파일을 각각 다른 디렉토리에 보관 각 서버 설정파일이 다를 수 있음
    별개의 디렉토리의 설정파일 보관
[vagrant@controller ~]$ mkdir a b
[vagrant@controller ~]$ touch a/ansible.cfg
[vagrant@controller ~]$ touch b/ansible.cfg
[vagrant@controller ~]$ cd a
[vagrant@controller a]$ ansible --version
ansible 2.9.27
  config file = /home/vagrant/a/ansible.cfg
[vagrant@controller a]$ cd ../b
[vagrant@controller b]$ ansible --version
ansible 2.9.27
  config file = /home/vagrant/b/ansible.cfg
  • 3번은 홈디렉토리 해당되는 사용자가 받는 설정
[vagrant@controller ~]$ pwd
/home/vagrant
[vagrant@controller ~]$ touch .ansible.cfg
[vagrant@controller ~]$ cat .ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
  config file = /home/vagrant/.ansible.cfg
[vagrant@controller ~]$ rm ~/.ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
# 홈디렉토리는 .ansible.cfg 이 차이를 명확하게 알아야함(사용자를 따라다니는 설정)  
[vagrant@controller ~]$ pwd
/home/vagrant
[vagrant@controller ~]$ touch ansible.cfg
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
  config file = /home/vagrant/ansible.cfg
[vagrant@controller ~]$ cd /tmp
[vagrant@controller tmp]$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  • 4번은 전역적인 설정 어떤 사용자든 받게되는
[vagrant@controller ~]$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg # 현재 적용되는 설정파일
  

1번과 4번은 전역적인 관점
3번은 해당되는 사용자에게만 부여되는 설정
4번은 해당되는 디렉토리에 접근한, 해당되는 디렉토리에 작업에 대해서만

내가 자주쓰는 설정 3번, 해당되는 작업에 특화되는 설정은 2번에 나머지는 잘 쓰지 않음

홈디렉토리에 있는건 사용자를 따라다님

section

cfg지만 ini 파일처럼 section이 존재

[vagrant@controller ~]$ egrep '^\[' /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]

디폴트가 어디에 설정되어 있는지
ini 형식으로 할때 디폴트 섹션의 인벤토리라는 키를 사용한다

[vagrant@controller ~]$ vi .ansible.cfg
[defaults]
inventory=./inventory.ini

[vagrant@controller ~]$ ansible all --list-hosts
  hosts (2):
    *.11
    *.12

다음과 같이 설정시 -i 옵션을 통한 인벤토리 파일을 지정할 필요가 없음

/etc/ansible/ansible.cfg보면 주석같지만 사실 디폴트 값

관리노드 접속

앤서블의 전제
OpenSSH : SSH

SSH 접속

  • 패스워드 인증
  • 키 쌍 인증

권한 상승(Privilege Escalation)

패키지 설치, 서비스 스타트, enable 관리자 권한이 필요함

루트사용자는 최소한으로 사용해야함 리눅스 시스템의 최소한의 보안
루트사용자는 시스템의 모든 권한을 가지고 있음
루트로 바로 접속하는 경우도 접속할 수 조차도 없음

sudo vi /etc/ssh/sshd_config

ssh 서버의 설정파일
이 파일은 관리자 권한만 가능 읽기 권한이 없기 때문에
설정 중에 38 라인 PermitRootLogin 기본 값은 No 루트로의 SSH 접근이 해제 되어있음
모든 클라우드 똑같음 -> 위험하기 때문에
루트 바로접속은 위험성이 있음

권한 상승 도구

  • su(X) 가능하면 절대로 사용해서는 안됨 어차피 지금 사용도 안됨
    a에서 root로 변경할때 비밀번호를 물어봄 root의 패스워드를 물어봄-> 사람이 많으면 루트의 패스워드 계정을 공유해야함 -> 보안에서는 책임추적성이란 것이 있음 -> 누가 했는지 나중에 알 수가 없음
    루트 패스워드 안하면 기능적으로 불가능
  • sudo
    패스워드는 자신의 패스워드를 사용
    su보다 sudo가 안 좋은가? 그렇지 않음
    sudo는 sudo를 사용할 수 있는 사용자를 지정

sudo를 사용할 수 있는 유저를 관리하는 파일

/etc/sudoers 파일

%wheel ALL=(ALL)   ALL

vagrant *.100=(root) /usr/bin/ls

%wheel : wheel 그룹
ALL : 모든 시스템에서
(ALL) : 모든 사용자로
마지막 ALL : 모든 명령어

/etc/sudoers.d/vagrant

%vagrant ALL=(ALL) NOPASSWD: ALL

NOPASSWD sudo 할때 패스워드 묻지 않음 (passwordless sudo)
패스워드 없는 계정 인증할때도 사용-> 패스워드가 없으면 인증을 할 수 없기 때문

ansible* 접속 관련 옵션

SSH 접속 옵션

  • -u REMOTE_USER SSH 접속 계정 지정 옵션(기본 : 현재 사용자)
    문제가 되는 경우 서로 같은 사용자가 아닌 경우
  • -k, --ask-pass : 기본값은 Fasle, Ture 시 패스워드를 물어보기
[vagrant@controller ~]$ ansible *.11 -i inventory.ini --list-hosts -k
SSH password:

옵션을 사용하지 않으면 -> SSH 키 인증

ansible의 기본 인증 방법: SSH 키 인증

권한 상승 옵션

  • -b, --become : 권한 상승
    옵션을 사용하지 않으면 --> 권한상승 하지 않음
  • --become-method <sudo|su>
    sudo: 기본값
    su
  • --become-user : 어떤사용자로
    root : 기본값
  • -K, --ask-become-pass : sudo 패스워드 묻기
    옵션 사용하지 않으먼 --> passwordless sudo

https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html
커맨드 모듈 인덱스

free_form : 파라미터, 자유 양식

[vagrant@controller ~]$ ansible *.11 -i inventory.ini -m command -a id
*.11 | CHANGED | rc=0 >>
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[vagrant@controller ~]$ ansible *.11 -i inventory.ini -m command -a id -b
*.11 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

설정 파일

ansible.cfg 편집

[defaults]
remote_user=<SSH_USER>
ask_pass=<True|False>
host_key_checking=<Ture|False> # defaults는 True
# 클라가 서버에 최초로 접속할 때, 지문 물어봄 -> ansible에선 known_hosts에 있는 지 확인 yes/no 묻지 않음 -> known_hosts에 없으면 접속을 안함 
# 원래는 안물어 봤는데 지금은 물어봄
# 그룹을 지정하면 호스트가 100개면 전부 yes 쳐야함
# False면 무조건 yes한다

[privilege_escalation]
become=<True|False>
become_ask_pass=<True|False>
become_method=<sudo|su>
become_user=<SUDO_USER>
  • ask_pass의 기본값 false
  • host_key_cheking의 기본값 true
  • become 기본값 false
  • become_ask_pass 기본값 false
  • become_method 의 기본값 sudo

ansible-config 명령

ansible-config 설정파일 검증

  • 설정가능한 모든 항목 표시, 문서랑 똑같음
ansible-config list
  • 모든 설정의 기본 값 및 변경 값 표시
ansible-config dump

현재 설정된 항목 모두 확인
초록색 이상 없지만 변경도 없음
노란색은 변경 되었을때
빨간색은 실행이 안되었을때, 문제가 있을때

  • 현재 참조하고 있는 설정파일의 내용 확인
ansible-config view

모듈

모듈 목록 확인

https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html

ansible-doc -l

모듈 확인 가능
인터넷 연결안되어있어도 모듈의 목록을 확인 하할 수 있음
포맷 - 모듈 이름 : 간단한 설명

모듈 상세 정보

ansible-doc <MODULE_NAME>

모듈명으로 쓰면 모듈에 대한 상세정보 확인 가능

옵션 = 파라미터

ad_hoc 명령

ansible <HOST_PATTERN> -m <MODULE> -a <PARAMETER> 

패턴지정
관리노드 설정시 호스트 명들에 패턴을 지정할 수 있음

[vagrant@controller ~]$ cat inventory.ini
*.11
*.12

[web]
weba
webb

[db]
weba
dba
dbb

[vagrant@controller ~]$ ansible web:db --list-hosts # 합집합과 같음
  hosts (4):
    weba
    webb
    dba
    dbb

[vagrant@controller ~]$ ansible 'web:!db' --list-hosts
  hosts (1):
    webb


[vagrant@controller ~]$ ansible 'web:&db' --list-hosts # 교집합과 같음
  hosts (1):
    weba

패턴 사용하지 말기 --> 문제 발생 소지가 있음
목록 형태는 상관없음 멀티그룹까지 ok !, & nono 단순하게 하기

교집합 위험성이 너무 큼 -> 차라리 그룹을 만들어서 abc를 하기

Wordpress 구성에 필요한 작업

  • 패키지 설치: yum
  • 서비스 제어: service
  • 텍스트 수정: lineinfile, blockinfile, replace
    vi cheatsheet
    required 빨간색 무조건 지정해야하는 파라미터
  • 압축 : archive. unarchive
  • 방화벽 : firewalld (레드햇 계열) 데비안은 사용하지 않음, ufw 데비안, iptables
  • 파일 복사 : copy, fetch 관리노드에서 컨트롤 노드로 파일을 복사
  • 파일 다운로드 : get_url
  • 데이터베이스 : mysql_db (mariadb), mysql_user 사용자 만들고 권한 부여
  • 인증서생성 : openssl_certificate
  • 파일 관리 : file

윈도우 모듈도 있음
윈도우는 윈도우용으로 사용해야 함

좋은 웹페이지 즐겨찾기