2017년 5월 14일 일요일

Saltstack 이 뭔가요.

출처: http://bluese05.tistory.com/43 [ㅍㅍㅋㄷ]


Saltstack 이 뭔가요. 





 인프라의 규모가 커질 수록 서버 설치와 설정에 대한 부담이 늘어나기 마련이다. 특히 트래픽이 급격히 늘어나는 경우, 이에 빠르게 대처하여 서버를 구축하기 위해서는 자동화가 필수이다. Saltstack은 이런 대규모 인프라를 관리하기 위한 자동화 관리 시스템이다. 

 자동화 관리 툴로 유명한 Puppet 이나 Chef 도 있는데, Saltstack 은 이것들과 비교해 인지도가 약간 떨어지는게 사실이다. 아무래도 Puppet 이나 Chef 보다는 최근에 나온 것이기도 하고 기능도 많이 겹치기도 하기 때문. Puppet 과 Chef 와의 비교는 다음에 다룰 예정이다.
  



Saltstack의 장점


1. 일단 빠르다.  server 와 agent 간 zeromq 를 통해 통신하는데, agent 요청에 대해 비동기 병렬로 처리 하기 때문에 agent가 많아져도 수 초안에 처리가 가능하다. 실 경험을 바탕으로는 1만대 이상 agent 에 명령을 보내고 응답 받는데 2초가 채 걸리지 않았다. (물론 단일 작업 수행 시간 자체가 긴 경우는 논외)
   

2. 구조가 심플하다.  Server-agent 기반의 매우 단순한 구조이다. 서버의 경우 DB 조차 사용하지 않는다. (DB를 사용하고 싶은 경우 plug-in 구조로 DB를 사용할 수 있게 지원된다.) 보통 이런 시스템을 도입하게 되면 시스템 자체의 운영에 대해 부담감이 있기 마련이다. 하지만 구조가 단순하다면 이런 부담감도 크지 않아 도입하는데 무리가 없다. 


3. 풍부한 모듈 지원.  인프라 환경 구성을 위한 거의 대부분의 작업을 지원하는 내장 모듈이 존재한다. 그리고 이를 이용해 다수의 서버를 프로그래머블하게 제어하는게 가능하다. (= Infrastructure as a Code )





Saltstack Architecture


                         [ 단순한게 좋다. ]



1. Salt-Master

   Saltstack에서 Server 역할을 담당한다. Master는 등록된 Minion 에게 명령을 publishing 하고 그 결과를 취합하여 보여주는 역할이다.  1대의 single master가 minion 수천대까지 관리 가능하다. 


2. Salt-Minion

   Agent의 역할이며, 구성 자동화를 하기 위한 대상 서버에 설치하면 된다.  Master의 명령을 기다리고 있다가 명령이 오면 그에 맞춰 작업을 수행하게 된다. 
   만약, 서버에 minion을 설치하기 어려운 상황이라면 Ansible 처럼 SSH로 명령 push가 가능하게도 지원된다.


3. ZeroMQ

   Salt-master와 Salt-minion 간 통신에 ZeroMQ 라는 비동기 메시징 라이브러리를 사용한다.
   (ZeroMQ에 대해 궁금하다면 여기로 : http://kr.zeromq.org/ )
   따로 설치해야 하는 것은 아니며 Salt-master를 설치하면 zeroMQ도 함께 설치 된다. publish Port로 4505 / Return Port 로 4506 을 사용한다. (포트 수정 가능)


   Port 4505는 Publisher로서, 모든 salt-minion 들이 명령을 받기 위해 해당 포트를 listening 한다. slat-master는 이 포트를 통해 명령을 전달하며, 모든 minion은 비동기 형태(asynchronous) 로 동시에 명령을 받아 수행하게 된다. 

   Port 4506은 minion 들이 수행한 작업 결과를 받게 되는 역할로 사용된다. 그리고 결과 리턴 뿐 아니라 minion이 master에게 파일을 요청하거나 minion의 특정 데이터 값(Salt pillar) 을 요청하는 포트로도 사용된다.
  





Saltstack의 특징 



1. Python 기반

   Saltstack 자체가 Python 으로 개발되었으며, Saltstack에서 실행되는 모든 명령 실행 코드는 Python 기반의 Module / Function 으로 구현되어 있다. 만약 사용자가 원하는 custom module을 구현하고 싶다면 Python 으로 개발하면 된다. 근데 custom module 개발할 필요가 없을 정도로 내장 모듈이 많으며 강력하다. 


2. YAML / Jinja2 포맷의 설정 파일

  자동화할 작업들을 명세하는 sls 파일들은 YAML 포맷을 기본으로 한다. 또한 template 파일의 경우, 로직에 대한 처리는 Jinja2 template 을 사용한다. Jinja의 경우 기존에 Django나 Flask 같은 프레임워크에서도 많이 사용된 기술이기 때문에 어렵지 않게 사용이 가능하다.
  


3. ZeroMQ 기반의 메시징 처리

  위에서 설명했으니 스킵-



4. AES 암호화 통신

  salt-minion 이 master에 처음 등록될때 minion은 master에게 자신의 public key를 전달하게 된다. 그리고 master는 이 public key를 저장하고 해당 minion의 등록을 허락하는 절차를 거치게 된다. 이후 master와 minion은 ZeroMQ를 통해 통신할때 public key와 AES key를 이용해 암호화 되어 통신하게 된다.   





[ 참고 ]

  • https://saltstack.com/saltstack-architecture/
  • https://docs.saltstack.com/en/getstarted/system/index.html


출처: http://bluese05.tistory.com/41 [ㅍㅍㅋㄷ]



Saltstack : Grains 와 Pillar


Saltstack을 이용해 인프라 구성 자동화를 구현하려면 Grains 와 Pillar 의 개념을 잘 알아야 한다. 
이 두가지는 비슷하면서도 달라서 처음 사용하는 경우 헷갈리기 쉽다. 
Grains와 Pillar의 특징과 이용방법에 대해 간단히 알아보자. 






1. Grains

[출처: https://docs.saltstack.com ]

 Grains는 타겟 서버에 대한 시스템 정보들을 가리킨다.  
 이 정보에는 서버의 OS, kernel 정보에서 부터 CPU, MEM 같은 resource 정보들이 포함되어 있다.
 Grains 정보들은 salt-minion 데몬에 의해 자동으로 수집되거나 master에게 명령을 받았을때 수행하게 되고 
 취합 결과를 master 에게 전달하게 된다.

 아래는 minion이 설치된 서버에서 수집한 Grains 정보 이다.
 Grains 정보를 보려면 master에서 아래와 같이 입력하면 된다. 

root@~~# salt '*' grains.items 

saltstack.song.test:

    ----------

...(중략)

    cpu_model:

        Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz

    cpuarch:

        x86_64

    domain:

        song.test

    fqdn:

        saltstack.song.test

    fqdn_ip4:

        - 10.0.200.27

    fqdn_ip6:

    gpus:

        |_

          ----------

          model:

              SVGA II Adapter

          vendor:

              unknown

    host:

        saltstack

    hwaddr_interfaces:

        ----------

        ens160:

            XX:XX:XX:XX:XX:XX

        lo:

            00:00:00:00:00:00

    id:

        saltstack.song.test

    init:

        systemd

    ip_interfaces:

        ----------

        ens160:

            - 10.0.200.27

            - XX:XX:XX:XX:XX:XX

        lo:

            - 127.0.0.1

            - ::1

    kernel:

        Linux

    kernelrelease:

        3.10.0-327.4.4.el7.x86_64

    locale_info:

        ----------

        defaultencoding:

            UTF-8

        defaultlanguage:

            en_US

        detectedencoding:

            UTF-8

    localhost:

        proti-mp01-mor03

    lsb_distrib_id:

        CentOS Linux

    manufacturer:

        VMware, Inc.

    master:

        10.0.200.17

    mdadm:

    mem_total:

        1840

    nodename:

        saltstack

    num_cpus:

        1

    num_gpus:

        1

    os:

        CentOS

    os_family:

        RedHat

    osarch:

        x86_64

    oscodename:

        Core

    osfinger:

        CentOS Linux-7

    osfullname:

        CentOS Linux

    osmajorrelease:

        7

    osrelease:

        7.2.1511

    osrelease_info:

        - 7

        - 2

        - 1511

...(중략)

 위에서 볼 수 있듯이 Grains의 기본 포맷은 YAML 이다. 
 이 포맷은 --out 옵션으로 변경도 가능하다. 아래는 json 포맷으로 변경하여 출력하는 예이다. 

 root@~~# salt --out=json '*' grains.items 

 출력 결과를 보면, 
 Grains 정보에는 현재 OS 배포판, 커널 정보 부터 
 이더넷 인터페이스 이름과 IP, MAC 정보 와 같은 네트워크 관련 정보도 알 수 있다.
 그리고 현재 서버의 CPU, Memory같은 resource 정보들도 손쉽게 얻을 수 있다. 



 "그렇다면 Grains 는 어떻게 이용하면 되는가?" 


 이렇게 수집된 Grains 정보는 인프라 자동화를 구현하는데 유용하게 쓰일 수 있다.
 예를 들어보자. 

 만약 saltstack 으로 관리하려는 서버가 1000대가 있다고 가정해보자.
 이 서버의 일부는 CentOS 일수도 있고, Ubuntu 또는 Windows 일수 도 있다. 

 이러한 경우에 작업자가 CentOS 에만 작업을 하고 싶다면?
 또는 특정 커널 버전의 OS만 작업을 하고 싶은 경우도 있다. 
 또는 CPU 가 2core 인 서버만 작업을 하고 싶은 경우도 있을 수 있다. 

 즉, 작업 대상을 시스템 정보를 기준으로 구분짓고 싶을 경우 
 Grains는 굉장히 유용하게 사용이 가능하다. 

 예를들어, Grains를 이용해 OS가 CentOS인 서버의 hostname만 출력해보자.

root@~~# salt -G os:CentOS grains.item host

또는 kernel 버전이 3.10 인 서버의 IP만을 출력해보자.

root@~~# salt -G kernelrelease:3.10* grains.item ipv4

이렇게 Grains를 이용해 원하는 대상만 고를 수 있다.
또한, 사용자가 직접 Grains에 정보를 추가할 수도 있다. 

root@~~# salt 'web-01' grains.append roles webserver

web-01 이라는 서버의 grains 에 roles : webserver 라는 key:value 값을 추가하는 명령이다.
이렇게 사용자가 직접 grains 값을 입력하여 이용이 가능하다. 





2. Pillar


[출처: https://docs.saltstack.com ]


 Pillar 는 master 에서 global 하게 정의하는 변수이다.
 이 변수는 key value 형태로 사용자가 master에 파일로 작성한다. 
 그리고 minion은 이 pillar 파일을 받아 사용하게 된다. 

 즉, Pillar는 Grains와 정보 추출 방향이 정 반대 방향임을 알 수 있다. 

  • Grains : Minion이 수집하여 Master에게 전달 
  • Pillar : Master의 Pillar 파일 정보를 Minion에게 전달

 pillar 파일 위치는 master의 설정에 따라 다르다.
 master의 설정 파일은 /etc/salt/master 에 있다. 

root@~~# vim /etc/salt/master

... (중략)

# Salt Pillars allow for the building of global data that can be made selectively
# available to different minions based on minion grain filtering. The Salt
Pillar is laid out in the same fashion as the file server, with environments,
# a top file and sls files. However, pillar data does not need to be in the
# highstate format, and is generally just key/value pairs.
pillar_roots:
  base:
    - /srv/pillar

현재 pillar의 root path는 /srv/pillar 로 정의되어 있다. 
최초로 실행되는 pillar 파일은 /srv/pillar 디렉토리 하위에 init.sls 라는 이름으로 정의하면 된다. 


"보통 pillar 에 정의하는 변수는 어떤 것들이 있을까?"

보통의 경우 pillar 에는 시스템 정보 외에 주로 application을 위한 설정 정보들을 선언하여 사용한다. 
예를 들면, 

  • service URL
  • application의 설정 Path
  • 참조되는 IP, Port 정보
  • username
등등이 있다. 

아래는 mysql 설정에 대한 pillar 선언의 예이다. 
참고로 pillar 포맷 또한 YAML이 기본이다. 

mysql:
    master: mdb01
    keepalived:
        service_interface: ens160
        auth_pass: AYQBCB$@
        vips:
            - 10.0.0.101

    set_mysql: True
    root_password: XXXXXXX

    set_replication: True
    replication_user: repl
    replication_password: XXXXXXXX




Grains 와 Pillar의 조합


Saltstack에서 제공하는 Grains 와 Pillar 를 적절히 조합하면 인프라 자동화를 위한 다양한 케이스에 대해 대응이 가능하다. 

예를 들어, 
saltstack으로 관리하는 수천대의 서버중 
hostname이 mdb01 과 mdb02에 두 서버에 mysql 을 설치 자동화로 구현 한다고 가정해 보자. 

가장 첫번째로 해야할 일은 작업할 target 선정이다. 
간단한 방법으로 위에서 설명했던 Grains를 이용해 mdb01 과 mdb02에 role:db 로 저장한 후,
pillar에 mysql을 위한 설정 변수들을 선언해 자동화 코드를 구현하면 될 것이다. 



[참고]
  • https://docs.saltstack.com/en/getstarted/overview.html
  • https://docs.saltstack.com/en/getstarted/system/data.html
  • https://www.digitalocean.com/community/tutorials/an-introduction-to-saltstack-terminology-and-concepts


출처: http://bluese05.tistory.com/43 [ㅍㅍㅋㄷ]