728x90
반응형

Salt Demo Configuration

Salt Environment Configuration

  1. Install Virtual Box

  2. Install Salt-Vagarnt-Demo

    1. git clone https://github.com/UtahDave/salt-vagrant-demo

    2. cd salt-vagrant-demo

    3. vagrant plugin install vagrant-vbguest

    4. vagrant up

  3. Access Master

    1. vagarnt ssh master

    2. sudo su

    3. salt '*' test.ping

 

 

Salt Command Example

  1. Minion Hostname Test

    1. salt ‘*' cmd.run 'hostname’

  1. Minion Package Install

    1. salt '*' pkg.install cowsay

 

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Jinja File  (0) 2020.01.12
SaltStack Example  (2) 2020.01.12
SaltStack Best Practices  (2) 2020.01.12
SaltStack Command Option  (0) 2020.01.12
SaltStack  (1) 2019.12.17
728x90
반응형

Salt Jinja File

Jinja File

  • Python 웹 프레임워크인 Flask에 내장되어 있는 Template 엔진

  • 확장자는 xxx.jinja 형식을 가짐

  • Salt에서는 YAML보다 Jinja가 먼저 평가됨

  • State 파일에서 Jinja의 기본적인 사용법은 제어 구조를 사용하여 조건부 또는 중복 상태 요소를 래핑하는 것

  • 구성의 Template 파일로 이해하면 됨

 

Jinja Example

/srv/salt/dev/dev_files.sls

  • /tmp/test.conf라는 파일을 생성하고 user, group 권한은 pillar의 init.sls의 permssion을 참조

  • 파일 내용은 /dev/files/test.conf.jinja 템플릿을 사용

 

/srv/salt/dev/files/test.conf.jinja

  • grains.os_family의 값이 Debian이면 Ubuntu Linux를 RedHat이면 RedHat Linux를 name이라는 변수에 넣음

 

/srv/pillar/dev/init.sls

 

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Demo Configuration  (2) 2020.01.12
SaltStack Example  (2) 2020.01.12
SaltStack Best Practices  (2) 2020.01.12
SaltStack Command Option  (0) 2020.01.12
SaltStack  (1) 2019.12.17
728x90
반응형

Salt Example

Salt & Pillar

Salt와 Pillar의 관계

  • Salt가 시스템 구조를 정의하는 선언문이라면 Pillar는 Salt를 정의하는 선언문에 사용할 수 있는 변수와 같음

  • 예를 들어 Dev와 Live 환경을 가진 미니언이 있다.

    Dev 환경의 미니언에는 Python2 버전이 Live 환경의 미니언에는 Python3 버전이 설치되어야 할때 Pillar를 사용하지 않는다면 각 환경에 맞도록 Salt 파일이 하드코딩 되어야한다.

    만약 Pillar를 사용한다면 Pillar 파일에서 Grains Item을 설정하거나 다른 설정으로 미니언의 환경을 읽어와 Dev에는 Python2가 Live에는 Python3이 설치되도록 작성할 수 있다.

    이렇게 작성된 Pillar파일을 Salt 파일에서 참조하면 각 환경에 맞게 하드코딩할 필요 없이 Pillar에 설정된 값대로 Salt 파일은 Pillar의 값이 설정되게 된다. Pillar는 변수라고 이해하는 편이 좋을듯 하다.

  • 하드 코딩된 Salt파일은 YAML 형식이라 부르지만 Pillar를 참조하게 코딩된 Salt파일은 Jinja 파일이라 불린다.

  • Salt와 Pillar의 구조는 동일해야한다. 예를 들어 Salt/dev 디렉토리만 있고 Pillar/live 디렉토리가 있는 경우 Pillar의 live에 설정된 파일은 salt/dev에 적용되지 못한다.

    •  

    • base env에서 해당 sls를 찾지 못했다는 경고문 (구조가 다르기 때문에 생기는 문제)

    • salt/dev라면 pillar/dev가 되어야함

 

Salt & Pillar Example

  • Dev 환경에서 Minion 별 다른 패키지를 가져가는 경우

  • Pillar 파일 설정

    • pillar/dev/init.sls

      •  

      • init.sls 파일은 dev_pkg.sls 파일을 포함

    • pillar/dev/dev_pkg.sls

      • minion1인 경우 bro 패키지를 minion2인 경우 cgit 패키지를 설치

  • Salt 파일 설정

    • salt/dev/init.sls

      • init.sls 파일은 dev 디렉토리의 dev_pkg.sls 파일을 포함

    • salt/dev/dev_pkg.sls

      • dev_pkg.sls 파일은 pillar의 pkgs라는 Attribute를 참조하고 해당 Attribute안에 설정된 내용대로 정의

  • 실행 예제

    • Salt 명령 테스트

      • Pillar에 정의된 대로 minion1이면 python2 패키지를 minion2이면 python3 패키지를 설치

    • Salt 명령 적용

      • test=True하여 테스트 했던 결과와 실제 적용시 예상된 결과값이 출력

 

Salt Minion Roles

  • Grains의 id, host와 같은 Item으로 Minion을 분류할 수 있지만 Roles을 부여하여 관리할 수 있음

# salt minion2 grains.setval roles [live,demo]

  • minion2에 live와 demo라는 roles을 부여

위와 같이 부여된 Roles로 top.sls로 역할별로 Minion을 분류할 수 있다.

 

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Demo Configuration  (2) 2020.01.12
SaltStack Jinja File  (0) 2020.01.12
SaltStack Best Practices  (2) 2020.01.12
SaltStack Command Option  (0) 2020.01.12
SaltStack  (1) 2019.12.17
728x90
반응형

Salt Best Practices

/srv/pillar/dev/init.sls

  • Pillar는 Static Variable이 기재되는 것

  • Pillar는 Salt Minion들이 어떠한 설정 값을 유지하기 원하는지 선언하기 때문에 Dynamic Variable보다는 Static Variable이 적용 되는 것이 Best

 

 

/srv/salt/dev/dev_files.sls

  • 구성 파일로 해당 예제는 pillar에 선언된 대로 files/test.conf.jinja 파일을 정의하고 있다.

  • 여기서 확인해야할 점은 첫 줄의 dev/map.jinja 파일로부터 permission의 context를 import하는 것으로 아래에 확인해보면 user와 group의 변수 확인시 permission.user 형식으로 지정되어 있다.

  • pillar나 grains를 통해 값을 가져오는것이 아닌 Mapping된 map.jinja 파일에서 값을 가져오는 것이다.

 

 

/srv/salt/dev/map.jinja

  • state.sls 파일에 변수 값을 넣을 경우 Minion 환경에 따라 다른 값이 들어가야하는 경우가 많다.

  • 이런 경우 state.sls 파일에 모두 넣을 수 있지만 좋은 방법이 아니다.

  • state.sls 파일은 가독성이 좋도록 간단하게 작성하고 거기에 맵핑되는 변수들은 map.jinja 파일에 작성하는 것이 좋다. 물론 pillar에 넣어서 사용할 수도 있지만 pillar는 Dynamic Variable보다 Static Variable을 유지하는 것이 좋기 때문에 map.jinja 파일에 환경에 따른 Dynamic Variable을 지정하는 것이다.

 

  • map.jinja 파일을 보면 dev_files.sls 파일에 들어가는 {{ permission.user }} 와 같은 변수가 정의되어 있다.

  • permission은 grains.filter_by의 리턴값에 따라 설정이 되는 기본적으로는 default를 사용하도록 되어 있는데 이것은 리턴된 값이 정의된 내용에 없는 경우에 사용한다.

  • 리턴된 값이 정의된 내용에 있는 경우에는 state.sls 파일의 변수에 map.jinja의 내용들이 들어간다.

  • 여기서 주의해야할점은 가장 아래 쪽에 있는 merge=salt'pillar.get', base='default' 이다.

  • 가장 위의 pillar 파일을 보면 permission의 mode 값이 777로 설정되어 있고 map.jinja에서는 644로 지정되어 있다.

  • merge 인수의 경우 가장 pillar의 값을 가져와 우선 적용 시킨다. 적용시 아래와 같다.

  • map.jinja에 mode가 644로 적용되어 있어도 pillar의 값인 777이 우선 적용되었다.

 

 

/srv/salt/dev/init.sls

  • state.sls의 최상위 파일

 

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Demo Configuration  (2) 2020.01.12
SaltStack Jinja File  (0) 2020.01.12
SaltStack Example  (2) 2020.01.12
SaltStack Command Option  (0) 2020.01.12
SaltStack  (1) 2019.12.17
728x90
반응형

Salt Command Option

Target Options

  • -H / --hosts

    • Hosts기반으로 타겟 지정

  • -E / --pcre

    • pcre 정규 표현식을 사용하여 타겟 지정

    • Ex) salt -E 'minion[0-9]' test.ping

  • -L / --list

    • 쉼표 또는 공백으로 구분하여 서버 목록 기반 타겟 지정

    • Ex) salt -L 'minion1,minion2' test.ping

  • -G / --grain

    • Grain 값을 사용하여 타겟 지정

    • 구문은 Grain Key 다음 글로브 프레스 ( "g : Arch *" )

    • Ex) salt -G 'os:Ubuntu' test.ping

  • -P / --grain-pcre

    • Grain 값을 사용하여 타겟 지정

    • 구문은 Grain Key 다음 pcre 정규 표현식 "os : Arch. *"

  • -N / --nodegroup

    • 사전 정의된 노드 그룹 중 하나를 사용하여 타겟 지정

  • -R / --range

    • 범위 표현식을 사용하여 타겟 지정

    • 범위 표현식은 % cluster와 같음

  • -C / --compound

    • 여러 타겟을 지정

    • 대상은 공백으로 구분되며, 글로브 이외의 대상에는 특정 대상 인수 유형 : salt 'G @ os : RedHat 및 webser * 또는 E@database.*'와 일치하는 식별자가 앞에 옴

    • Ex) salt -C 'G@os:Ubuntu and minion* or S@192.168.50.*' test.ping

  • -I / --pillar

    • Pillar 값을 사용하여 타겟 지정

    • 구문은 Pillar Key 다음에 glob 표현식 ("role : production *")

  • -J / --pillar-pcre

    • Pillar 값을 사용하여 타겟 지정

    • 구문은 Pillar Key 다음에 pcre 정규식인 "role : prod. *"

  • -S / --ipcidr

    • 서브넷 (CIDR 표기법) 또는 IP 주소를 기준으로 일치

참조 URL : https://docs.saltstack.com/en/latest/topics/targeting/compound.html

 

 

Command Tip

1. state.apply와 state.highstate는 무슨차이일까?

  • state.apply

    • 명령 뒤에 인자값 (user, ssh 등) 이 붙으면 state.sls와 같이 특정 파일을 실행하는 형식으로 동작

    • 명령 뒤에 인자값이 없다면 state.highstate와 동일하게 동작

  • state.highstate

    • 인자값 여부와 상관없이 top.sls를 실행하는 동작

    • 인자값이 붙어도 top.sls를 실행하며 인자값은 변수 형식

1.1) Example - 1

  • 인자값 없이 state.apply & state.highstate 실행

  • state.apply

    •  

  • state.highstate

  • 인자값이 없는 경우 state.apply 와 state.highstate는 동일한 결과

1.2) Example - 2

  • 인자값 있는 상태로 state.apply & state.highstate 실행

  • state.apply

    • state.sls와 동일한 결과를 출력

  • state.highstate

    • state.apply와 동일한 state를 유지하는 Arg가 허용되지 않음

    • state.apply와 state.highstate는 top.sls를 사용하는 것에 있어서 동일하지만 인자 값 포함 유무에 따라 다른 결과를 출력

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Demo Configuration  (2) 2020.01.12
SaltStack Jinja File  (0) 2020.01.12
SaltStack Example  (2) 2020.01.12
SaltStack Best Practices  (2) 2020.01.12
SaltStack  (1) 2019.12.17
728x90
반응형

SaltStack

  • 대규모 인프라를 관리하기 위한 자동화 관리 시스템 (Puppet & Chef와 같은 System Management Tool)

  • Server (Master) - Agent (Minion) 간 ZeroMQ를 통해 통신하며 Server → Agent의 요청은 비동기 병렬 방식으로 처리되기 때문에 Agent의 갯수와 상관없이 짧은 시간 (수 초) 안에 처리 가능

  • Server는 별도의 DB를 사용하지 않으며 만약 DB를 사용하고 싶은 경우 Plug-In 구조로 DB를 사용할 수 있음

  • Python 기반의 Module / Function으로 구현됨

  • 설정 파일은 YAML 포맷을 기본으로 하며 Template 파일의 경우 Jinja2 Template를 사용

 

 

SaltStack 특징

  • Speed

    • Server와 Agent간 ZeroMQ를 통해 통신하고 Agent 요청에 대해 비동기 병렬로 처리하기 때문에 굉장히 빠름

  • Simple

    • Server - Agent의 구조로 매우 단순

    • Server의 경우 DB를 사용하지 않으며 별도의 Plug-In을 통해 DB 사용 가능

  • Many Module (Plug-Ins)

    • 인프라 환경 구성을 지원하는 대부분의 내장 모듈이 존재

  • Python

    • Salt Stack 자체가 Python 기반으로 개발되었으며 Python 기반의 Module / Function 으로 구현됨

    • Python이 실행되는 모든 곳에서 실행 가능 (Cloud, OS, Container)

    • OS, Cloud, Container와 같은 다른 환경에서도 동일하게 실행되며 이러한 Salt 크로스 플랫폼 관리 기능의 핵심은 정규화임

  • AES 암호화 통신

    • Minion이 Master에 처음 등록될 때 Minion은 Master에게 자신의 Public Key를 전달

    • Master는 이 Public Key를 저장하고 해당 Minion의 등록을 허가하는 절차를 거침

    • Master와 Minion은 ZeroMQ를 통해 통신할 때 PublicKey와 AES Key를 이용해 암호화 되어 통신

  • No FreeLoader

    • 각 특성을 가진 Minion에게 Master에서 별도의 명령 실행 가능

    • Minion은 Master에게 전달받은 명령을 확인해 자신의 특성과 일치하는지 판별 후 일치하면 실행

    • Minion에는 로컬에 저장해야하는 모든 명령이 이미 있으므로 Master에 명령을 실행할 수 있으며 그 결과는 Master에게 Return

  • Saling & Performance

    • Salt는 고성능 및 확장성을 위해 설계됨

    • ZeroMQ 또는 Raw TCP를 사용하여 Master ↔︎ Minion간 Data Pipeline을 구축하므로 성능이 뛰어남

    • Message Pack을 사용하여 Message (Master의 명령) 을 효율적으로 직렬화

    • Salt는 비동기 네트워킹 라이브러리로 Python Tornado를 사용하며 멀티 쓰레딩 및 동시성에 대한 최신 접근 방식을 사용하여 조정됨

  • Automation

    • Event 중심 인프라를 통해 초기 시스템 구성을 자동화 할 수 있을 뿐만 아니라 진행중인 관리를 확장, 복구 및 수행할 수 있도록 자동화 할 수 있음

    • 배포 및 유지 관리의 자동화

  • Programing

    • Salt의 원격 실행 기능은 CLI 명령이며 상태 시스템은 YAML을 사용하여 원하는 시스템 구성을 할 수 있음

    • Module을 사용해 IaC로 제어 가능

 

 

SaltStack Architecture

  • Salt Master

    • Server의 역할을 담당하며 등록된 Minion에게 명령을 Publishing하고 그 결과를 보여주는 역할을 수행

    • 구성 데이터 저장소, 원격 명령 실행, 다른 시스템의 상태를 확인하는 제어 센터로 작동

    • 1대의 Single Master가 수천 대의 Minion까지 관리 가능

    • Master가 없는 구성을 사용하여 인프라를 제어하는 것도 가능하지만 Master에서 제공하는 기능들을 사용할 수 없으므로 권장하지 않음

  • Salt Minion

    • Agent 역할을 담당하며 구성 자동화를 하기 위한 대상 서버에 설치

    • Master의 명령을 기다리고 있다가 명령이 오면 그에 맞춰 작업을 수행

    • 서버에 Agent를 설치하기 어렵다면 Ansible처럼 SSH로 명령 Push가 가능함 (AgentLess 형태)

    • Agent Less URL : https://docs.saltstack.com/en/getstarted/ssh/index.html

  • ZeroMQ

    • Slat Master ↔︎ Salt Minion 간 통신에 사용되는 비동기 메시징 라이브러리

    • 별도 설치 방식은 아니며 Slat Master를 설치하면 자동으로 함께 설치

    • Publish Port : 4505 / Return Port : 4506 (Port 수정 가능)

      • Publish Port 4505

        • Publisher로서 모든 Salt Minion들이 명령을 받기 위해 해당 포트를 Listening

        • Master는 Minion의 4505 Port로 명령을 전달하며 모든 Minion은 비동기로 동시에 명령을 받아 수행

      • Return Port 4506

        • Minion들이 수행한 작업 결과를 받게되는 역할로 사용

        • 결과 리턴뿐만 아니라 Minion이 Master에게 파일을 요청하거나 Minion의 특정 데이터 값 (Salt Pillar) 을 요청하는 Port로도 사용

        • 4506 Port에 대한 연결은 Master ↔︎ Minion 간의 1:1 관계 (비동기 아님)

 

Salt SubSystem

  • Salt SubSystem이란 어떠한 역할을 하는 System으로 예를 들어 Command Interface라는 역할을 하는 SubSystem을 구축할 때 일반적으로 포함되는 Plug-Ins는 Python API, REST API, Command Line으로 이렇게 모인 Plug-In들이 하나의 SubSystem을 구성

  • 아래는 기본 SubSystem

  •  

    • Authentication

      • 작업을 실행하기 전에 사용자에게 권한을 부여

    • File Server

      • 파일을 배포

    • Secure Data Store

      • 사용자 정의 변수 및 기타 데이터를 안전하게 사용할 수 있음

    • State Representation

      • 인프라 및 시스템 구성을 설명

    • Return Formatter

      • 작업 결과를 표준화 된 데이터 구조로 형식화

    • Result Cache

      • 작업 결과를 장기 저장소로 보냄

    • Remote Execution

      • 소프트웨어 설치, 파일 및 시스템 관리에 필요한 기타 작업을 수행하는 다양한 작업을 실행

    • Configuration

      • 원하는 상태와 일치하도록 대상 시스템을 구성

 

 

Salt SubSystem 구동 순서

  1. 명령 전달 (Master)

  2. 사용자 인증 (Master)

  3. 작업을 이벤트 버스에 배치하고 연결된 Minion에 전달 (Master)

  4. 작업 관리 구성 & 원격 작업 실행 (Master & Minion)

    1. State 파일 다운로드 (Master) & 명령 실행 (Minion)

    2. 보안 데이터를 검색하여 상태 파일에 삽입 (Master)

    3. 상태 파일이 파싱되고 컴파일됨 (Minion)

    4. 상태가 적용되고 상태 모듈이 실행 (Minion)

  5. 결과는 형식화되어 이벤트 버스에 배치됨 (Master)

  6. 결과는 Long-Term 저장소로 전송됨

  7. Reactors는 이벤트에 따라 트리거됨

  • 각 단계에서 SubSystem은 작업을 구성된 Plug-In으로 위임함

  • 각 단계에는 구성된 Plug-In에 따라 WorkFlow가 달라질 수 있음

  • Returner

    • Salt Returner는 Minion의 대한 Remote Execution 결과가 전송되는 위치를 지정하는데 사용

    • 기본적으로 Minion → Master로 데이터를 반환하는데 Retuner는 Master가 아닌 다른 목적지로 전송하도록 Routing 할 수 있음

    • 일반적으로 결과는 Returner와 Minion 명령을 시작한 프로세스에 지정된 대상으로 반환됨을 의미함

    • 대부분의 Returner는 Database System이나 Metric 또는 Logging 서비스에 전달함

    • Returner는 작업 캐시, 이벤트 데이터와 같은 Salt의 특정 데이터를 수집하는데 사용될 수 있음

  • Reactors

    • Salt Reactors System은 생성된 이벤트에 반응하여 동작을 트리거하는 매커니즘을 제공

    • Salt에서는 인프라 전체에서 발생하는 변경 (Remote Execution & Runner) 으로 인해 Minion 또는 Master Daemon이 ZeroMQ Message Bus에 Event를 생성하는데 Reactors System은 이 Message Bus를 감시하고 적절한 대응을 하기위해 구성된 Reactor와 Event를 비교함

    • Reactors System의 주요 목표는 변경이 발생한 상항을 자동으로 생성하기위한 시스템을 제공하는 것 (Event기반 Trigger 실행)

 

 

Salt 주의점

  • Salt Module 사용시 RedHat 계열 OS에 aptpkg Module을 사용하는 것처럼 맞지 않은 Module을 사용하면 Error Code 발생하니 환경에 맞는 Module을 사용해야함

 

 

Salt Security

Salt Minion Auth

  1. Minion은 처음 시작할 때 Network에서 이름이 Salt로 지정된 시스템을 검색함 (IP 또는 Hostname으로 변경 가능) → Vagarnt를 통해 구성을 쉽게 할 수 있음

  2. 시스템이 검색되면 Minion은 Network Handshake 과정 후 Public Key를 Master에게 전달

  3. 연결 후 Minion의 Public Key는 Master에 저장되며 salt-key 명령을 사용하여 Master에서 승인해야함 (해당 부분은 자동화된 매커니즘을 사용 가능 → Vagarnt 등)

  4. Master에서 Minion의 Public Key가 승인되지 않는다면 Salt가 ZeroMQ를 통한 Message를 보내도 Minion에서는 Public Key가 승인될때까지 명령을 실행하지 않음

  5. Minion의 Public Key가 승인되면 Master는 Public Master Key와 전달하는 Message의 암호화 및 해독을 하는데 사용되는 AES Key를 반환하여 Minion에게 전달하며 반환되어 전달받은 Key는 해당 Minion만 해독 가능

Salt ACL

  • 명령이 Minion에게 전달되기전 Salt는 ACL을 통해 명령 실행자의 권한이 있는지 확인

Salt Encryption

  • Master ↔︎ Minion 간의 통신은 AES Key를 사용하여 암호화 & 복호화 방식으로 전달되며 각 Minion 및 Session 마다 고유한 AES Key로 암호화됨 (Minion이 100개면 100개의 AES Key가 생성)

 

Salt Remote Execution

Salt 문법

  • Salt 기본 문법

    •  

    • Target

      • Taget이 '*'이면 모든 Minion에 전달

      • 각 Minion은 명령을 검사하고 대상과 비교하여 평가하며 명령을 실행할지 여부를 결정

      • 대상 시스템은 명령을 실행한 후 결과를 요청 서버로 리턴

    • Module.Function

      • 위의 예제에서는 Module은 test이고 Function은 rand_sleep

      • test Module의 rand_sleep이라는 Function을 실행

    • Arguments

      • 실행되는 Module.Function에 인자값을 부여

  • 각 명령은 별도의 Worker 스레드로 분리되어 Minion은 여러 작업을 한번에 처리할 수 있음

Salt Module & Function

  • Salt는 원격 실행과 구성 관리 기능을 구분해서 제공하는데 원격 실행 기능은 실행 모듈을 통해 제공됨

  • 이 Module은 Minion에 대한 작업을 수행하는 관련 Function들의 집합

  • Module

    • Module을 사용하면 시스템 (OS, Cloud, Container 등) 간의 차이점을 추상화할 수 있음

    • 실제로 데이터를 수집하는 매커니즘이 서로 다른 Linux나 BSD를 사용하는 Minion에게서도 비슷한 정보를 얻을 수 있음

    • Salt는 즉시 사용가능한 기능을 제공하기 위해서 적절한 Module을 선택하여 제공함

  • Function

    • Module내에 포함되어 있는 Function으로 정의된 기능을 수행하는 역할

    • 예를 들어 Command라는 Module내에는 ssh, pip 등과 같은 명령실행 Function이 포함되어 있음

Salt State System

  • Salt State System은 Remote Execution을 실행한 후 정상 수행되었는지 확인

  • State System에서 정상 수행 여부를 확인 후 실행이 되지 않았다면 Remote Execution을 호출하여 실행

  • Minion의 /src/salt/states 경로를 Salt State Tree의 Root로 사용

  • 단일 파일 형태 (/src/salt/states/mystate.sls) & 폴더 구성 (/srv/salt/states/mystate/init.sls) 로 구성 및 저장

  • salt:// 포맷은 State Tress의 파일을 제공하는 Salt File Server를 가리킴

  • /salt/states/users/init.sls | /salt/states/nginx/init.sls | /salt/state/php-fpm/init.sls | /salt/states/phptest/init.sls 형태로 작성

 

 

Salt Runners

Salt Runner

  • Runner SubSystem은 Salt Master에서 실행되는 Salt Module을 제공함

  • Runner는 salt-run 명령행 인터페이스를 사용하여 호출됨 (호출은 Master에서 실행하므로 대상에 포함되지 않음)

  • Runner는 작업 상태 표시, 실시간 이벤트 확인, Salt의 파일 서버 관리, Mine 데이터 확인, Minion에게 Wake-On을 보냄, Web Hook를 호출, 다른 HTTP 요청을 하는 등 다양한 수행을 할 수 있음

  • salt-run 명령에 인수를 전달하는 문법은 Salt Remote Execution에서 사용하는 문법과 동일

  • 단일성 명령 실행할 때 사용

 

Salt Orchestrate Runner

  • Orchestrate Runner는 Salt의 핵심 기능 중 하나인 명령을 실행하고 정의된 순서로 여러 Minion에 구성을 적용하는 기능을 제공하므로 자체 섹션을 가짐

  • 예를 들어 Orchestrate Runner를 사용하면 State System의 모든 기능을 사용하여 여러 시스템을 구성할 수 있음

  • salt-run은 단일성 명령이지만 여러 Minion에 명령 실행 가능

 

 

Salt Data

  • Master ↔︎ Minion & Minion ↔︎ Minion 간의 데이터 이동 관련된 내용

 

 

Salt Grains

  • 주요 Host System과 관련하여 Minion이 수집하고 유지하는 정보의 조각 (OS, Memory, Disk, Network Interface등과 같은 시스템 속성을 수집)

  • 일반적으로 Minion의 Agent Daemon에 의해 수집되고 요청시 Master에게 전달됨

  • Grains는 구성 변경 또는 명령에 대한 인수로 사용될 수 있음 (예를 들어 Grains를 사용하여 구성 파일 변경 또는 명령 인수로 특정 IP 주소를 가져올 수 있음)

  • Master는 Grains를 Minion에게 할당할 수 있는데 역할을 할당받은 Minion은 Grains를 사용하여 Master의 역할을 할 수 있음

 

Salt Pillar

  • Grains를 Master → Minion에 할당하는 것이 가능하지만 대부분의 구성 변수는 Pillar System을 통해 할당됨

  • Salt에서 Pillar는 Minion이 임의로 할당된 데이터를 검색하는데 사용할 수 있는 Key-Value 저장소를 나타냄

  • 이는 조직적 목적으로 중첩되거나 계층화 될 수 있는 사전 데이터 구조로서 기능을 함

  • Pillar는 값을 할당하기 위해 Grains보다 몇가지 중요한 이점을 제공하는데 가장 중요한 점은 Pillar Data는 할당된 Minion에서만 사용할 수 있다는 것임 (다른 Minion들은 내부에 저장된 값에 접근할 수 없음)

  • 따라서 노드 또는 노드의 하위집합에 대한 중요한 데이터를 저장하는데 이상적임 (비밀번호 또는 데이터베이스 연결 문자열은 대부분 Pillar 구성으로 제공됨)

  • Pillar Data는 종종 구성 데이터를 구성 템플릿에 주입하는 방법으로 구성관리 컨텍스트에서 활동됨

  • Salt는 구성 파일의 변수 부분을 적용할 노드에 특정한 항목으로 대체하기 위한 템플릿 형식을 제공함 (Grains가 Host Data를 참조할 때 종종 이 방법이 사용)

 

 

Salt Mine

  • Minion에게 정기적으로 실행되는 명령의 결과가 저장될 수 있는 마스터 서버의 영역 (Cron 작업의 결과 저장)

  • Mine의 목적은 Minion 머신에서 실행되는 임의 명령의 결과를 수집하는 것과 Grains 데이터에 대한 보완재로서 머신의 최신 정보를 제공하는 것

  • Mine은 가장 최근 결과만 저장함, 즉 기록 데이터에 Access 해야하는 경우 도움이 되지 않음

  • Minion은 Mine System을 통하여 상대방에 대한 데이터 쿼리를 할 수 있음

 

 

Salt Pyton

Salt Module

  • Salt의 각 SubSystem은 Python의 Module로 구성

  • Module은 Application (Mysql, Docker), 시스템 구성요소 (디스크, 파일) 를 관리하거나 외부 시스템 (gitfs) 과 상호작용하는 기능 그룹으로 생각할 수 있음

  • 모든 모듈은 Salt Source의 폴더에 있으며 모듈의 확장자는 .py 로 끝남

  • Module은 Salt Namespace 형식으로 SubSystem.Module로 표기되며 이 Namespace로 SubSystem Module의 유형을 쉽게 알 수 있음

  • Module에는 필요한 기능이 포함되는데 예를 들어 파일 실행 모듈 (salt.modules.file) 은 파일 관리가 중요하기 때문에 관련된 기능을 많이 가지고 있음, 또한 uwsgi 통계 서버 모듈 (salt.modules.uwsgi) 에는 하나만 있음

 

Salt Function

  • Function은 System 내에서 관리 및 구성을 하기 위해 호출할 수 있는 Module내의 특정 명령으로 생각할 수 있음

  • 예를 들어 salt.modules.pkg.install / salt.modules.network.interfaces / salt.modules.user.add 같음

 

Salt Argument

  • 명령행에서 Salt를 호출할 때 실행 인수는 추가 값으로 전달됨 (argument=value 형식)

  • 기본 값이 있는 인수는 선택적으로 전달할 수 있으며 필수 값은 공백으로 구분된 값으로 특정 순서로 전달됨

  • 예를 들어 user.add 함수의 경우 아래와 같음

    •  

  • 예제로 Fred라는 유저를 생성하고 기본 쉘을 지정할 경우

 

Salt Example

  • 여러 인수를 사용하여 전달하는 예 (인수는 arg 및 kwargs로 단축되며 아래는 1개의 arg와 3개의 kwargs를 전달)

    •  

  • 두 개의 Args와 Kwarg 전달

  • 몇몇 실행 모듈은 다음과 같은 리스트 전달을 허용함

  • 일부는 정의된 목록을 가져옴

 

Salt State Function Argument

  • State Function은 YAML 구문을 사용하여 상태 파일에서 호출됨

  • 아래는 Fred라는 사용자를 생성하고 기본 쉘을 변경하는 YAML 파일

    •  

  • 아래는 리스트로 패키지 설치

  • 정의된 목록 실행

 

Salt Syntax

 

Salt Configure Management

Salt Formulas

  • 특정 결과를 산출하기 위해 정렬된 상태 모듈 호출 집합

  • 구성관리 파일은 수식이 적용된 후 시스템이 어떻게 보이는지 나타내는 파일

  • 기본적으로 YAML 데이터 직렬화 형식으로 작성

 

Salt Template

  • Salt Formulas와 다른 파일들이 좀 더 유연한 상태로 쓰여지는 것을 허용

  • Template는 Formulas의 사용자 정의된 버전 또는 설정 파일을 구성하기 위해서 Minion에 대한 가능한 정보를 사용할 수 있음

 

 

반응형

'SaltStack' 카테고리의 다른 글

SaltStack Demo Configuration  (2) 2020.01.12
SaltStack Jinja File  (0) 2020.01.12
SaltStack Example  (2) 2020.01.12
SaltStack Best Practices  (2) 2020.01.12
SaltStack Command Option  (0) 2020.01.12
728x90
반응형

Kubernetes Ingress

 

Ingress는 서비스는 L4 Layer의 Service와 달리 L7 Layer의 서비스이다.

쿠버네티스의 Ingress는 HTTP(S) 기반의 URL Path LoadBalancing을 하는 서비스라고 보면 된다.

 

아래는 Ingress의 구성도이다.

 

 

Ingress는 URL 기반 로드밸런싱을 하며 구동되려면 뒷단에 Service가 있어야 한다. 

Ingress -> Pod는 불가능하며 Ingress -> Service -> Pod 형태로 구성이 되어야 한다.

 

인그레스는 리소스와 컨트롤러로 구성되는데 yaml로 정의하는 것은 리소스이며 실제 트래픽을 처리하도록 하는 것은 컨트롤러가 한다.

아래의 그림을 보자

 

 

클라이언트로부터 트래픽이 유입되면 인그레스 컨트롤러가 받아 내용을 확인하고 설정된 인그레스 리소스의 Rule대로 포드에게 트래픽을 전달한다.

 

위의 그림처럼 구성되는 이유는 Ingress 컨트롤러의 경우 어떤 Pod로 트래픽을 전달해야할지 알지 못한다. 단지 자기와 연동된 인그레스 리소스만 알고 있을뿐이다.

컨트롤러는 자신과 연동된 인그레스 리소스에게 들어온 트래픽에 대한 경로 정보를 요청하고 인그레스 리소스는 자신에게 정의된 Rule 대로 연동된 서비스에게 다시 경로 요청 후 서비스에 등록된 포드의 엔드포인트를 받게되면 컨트롤러가 전달받은 엔드포인트로 트래픽을 전달하는 방식이다.

 

Yaml로 정의하여 생성한 인그레스 리소스는 Rule을 정의하는 리소스일뿐 실제 트래픽을 전달하는 것은 컨트롤러가 한다는 것이 핵심이다.

 

온프레미스 기반에서는 직접 컨트롤러를 인그레스 리소스와 연동하여야한다는데 이 부분은 해보지 않아 예제로 만들지는 못하였다.

 

아래의 예제는 직접 생성해본 AWS 에서의 ALB 생성 YAML이다.

 

1. AWS ALB Controller 생성

 

- alb-ingress-controller.yaml

 

# Application Load Balancer (ALB) Ingress Controller Deployment Manifest.

# This manifest details sensible defaults for deploying an ALB Ingress Controller.

# GitHub: https://github.com/kubernetes-sigs/aws-alb-ingress-controller

apiVersion: apps/v1

kind: Deployment

metadata:

  labels:

    app.kubernetes.io/name: alb-ingress-controller

  name: alb-ingress-controller

  # Namespace the ALB Ingress Controller should run in. Does not impact which

  # namespaces it's able to resolve ingress resource for. For limiting ingress

  # namespace scope, see --watch-namespace.

  namespace: kube-system

spec:

  selector:

    matchLabels:

      app.kubernetes.io/name: alb-ingress-controller

  template:

    metadata:

      labels:

        app.kubernetes.io/name: alb-ingress-controller

    spec:

      containers:

        - name: alb-ingress-controller

          args:

            # Limit the namespace where this ALB Ingress Controller deployment will

            # resolve ingress resources. If left commented, all namespaces are used.

            # - --watch-namespace=your-k8s-namespace

 

            # Setting the ingress-class flag below ensures that only ingress resources with the

            # annotation kubernetes.io/ingress.class: "alb" are respected by the controller. You may

            # choose any class you'd like for this controller to respect.

            - --ingress-class=alb

 

            # REQUIRED

            # Name of your cluster. Used when naming resources created

            # by the ALB Ingress Controller, providing distinction between

            # clusters.

            - --cluster-name=eks-test

 

            # AWS VPC ID this ingress controller will use to create AWS resources.

            # If unspecified, it will be discovered from ec2metadata.

            - --aws-vpc-id=vpc-OOOOOO

 

            # AWS region this ingress controller will operate in.

            # If unspecified, it will be discovered from ec2metadata.

            # List of regions: http://docs.aws.amazon.com/general/latest/gr/rande.html#vpc_region

            - --aws-region=ap-northest-2

 

            # Enables logging on all outbound requests sent to the AWS API.

            # If logging is desired, set to true.

            # - ---aws-api-debug

            # Maximum number of times to retry the aws calls.

            # defaults to 10.

            - --aws-max-retries=10

          # env:

            # AWS key id for authenticating with the AWS API.

            # This is only here for examples. It's recommended you instead use

            # a project like kube2iam for granting access.

            #- name: AWS_ACCESS_KEY_ID

            #  value: KEYVALUE

 

            # AWS key secret for authenticating with the AWS API.

            # This is only here for examples. It's recommended you instead use

            # a project like kube2iam for granting access.

            #- name: AWS_SECRET_ACCESS_KEY

            #  value: SECRETVALUE

          # Repository location of the ALB Ingress Controller.

          image: docker.io/amazon/aws-alb-ingress-controller:v1.1.2

      serviceAccountName: alb-ingress-controller

 

 

2. AWS ALB Controller에 대한 Cluster Role 생성 및 바인딩 (Cluster에서 Controller에 대한 권한을 허용해야함)

 

- alb-ingress-rbac.yaml

 

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  labels:

    app.kubernetes.io/name: alb-ingress-controller

  name: alb-ingress-controller

rules:

  - apiGroups:

      - ""

      - extensions

    resources:

      - configmaps

      - endpoints

      - events

      - ingresses

      - ingresses/status

      - services

    verbs:

      - create

      - get

      - list

      - update

      - watch

      - patch

  - apiGroups:

      - ""

      - extensions

    resources:

      - nodes

      - pods

      - secrets

      - services

      - namespaces

    verbs:

      - get

      - list

      - watch

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  labels:

    app.kubernetes.io/name: alb-ingress-controller

  name: alb-ingress-controller

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: alb-ingress-controller

subjects:

  - kind: ServiceAccount

    name: alb-ingress-controller

    namespace: kube-system

---

apiVersion: v1

kind: ServiceAccount

metadata:

  labels:

    app.kubernetes.io/name: alb-ingress-controller

  name: alb-ingress-controller

  namespace: kube-system

...

 

 

3. ALB 생성

 

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: api-alb-ingress

  namespace: api

  labels:

    app: nodejs

  annotations:

    kubernetes.io/ingress.class: alb

    alb.ingress.kubernetes.io/scheme: internet-facing

    alb.ingress.kubernetes.io/target-type: ip

    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'

    #alb.ingress.kubernetes.io/security-groups: sg-OOOOOO

    alb.ingress.kubernetes.io/subnets: subnet-aaaaaa,subnet-bbbbbbb

    #alb.ingress.kubernetes.io/tags: "Name=alb-test"

    #alb.ingress.kubernetes.io/healthcheck-interval-seconds: '30'

    #alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '10'

    #alb.ingress.kubernetes.io/healthy-threshold-count: '3'

    #alb.ingress.kubernetes.io/unhealthy-threshold-count: '3'

    alb.ingress.kubernetes.io/healthcheck-path: '/'

    #alb.ingress.kubernetes.io/healthcheck-port : '80'

    #alb.ingress.kubernetes.io/healthcheck-protocol : HTTP

    alb.ingress.kubernetes.io/success-codes : '200'

 

spec:

  backend:

    serviceName: api-svc

    servicePort: 80

 

 

4. ALB 인그레스와 연동된 Service 생성

 

apiVersion: v1

kind: Service

metadata:

  name: api-svc

  namespace: api

  labels:

    app: nodejs

spec:

  type: NodePort

  selector:

    app: nodejs

  ports:

  - port: 80

    targetPort: 80

 

LoadBalancer는 Ingress가 하기 때문에 Service의 Type은 NodePort가 된다.

반응형

'Kubernetes' 카테고리의 다른 글

Kubernetes Service  (0) 2019.09.17
Kubernetes Monitoring - Version1  (0) 2019.09.17
Kubernetes HorizontalPodAutoscaler  (0) 2019.08.31
Kubernetes Pod DaemonSet  (0) 2019.08.30
Kubernetes Pod Replica  (0) 2019.08.30
728x90
반응형

Kubernetes Service

 

쿠버네티스에서의 로드밸런싱에는 Service와 Ingress가 있는데 간단하게 Service는 L4 로드밸런서, Ingress는 로드밸런서 이해하면 된다.

우선 Service에 대해 설명하겠다.

 

Service는 다른 포드의 요청이나 외부 클라이언트로부터 오는 HTTP 요청에 응답한다. 외부 클라이언트는 L4 로드밸런서를 외부로 노출시켜 트래픽을 받아 서비스에 속한 포드에 전달하는 것인데 다른 포드의 요청이라는 건 이해하기 애매할 수 있다. 이건 간편하게 내부 로드밸런서를 사용하는 경우로 이해해도 좋다. 물론 사용 사례일 뿐이니 각 환경마다 다르다.

 

외부 클라이언트 -> 외부노출 Service -> Webserver Pod -> 내부 Service -> WasServer Pod

 

 

이런식으로도 구성 가능하다.

 

일단 서비스를 사용하는 일반적으로 로드밸런서를 사용하는 이유와 비슷하지만 쿠버네티스 환경에서는 포드는 Static IP를 가지지 않고 노드 환경에 따라 삭제되고 재생성되는 일이 많으며 포드가 노드로 스케줄되기 전에 IP를 할당받으므로 클라이언트는 서버 포드의 IP를 알 수 가 없다. 이런 문제가 있기 때문에 Service라는 리소스가 필요한 이유이다.

 

쿠버네티스 서비스란 동일한 서비스 (webserver, api server와 같은) 를 제공하는 포드 그룹에 하나의 진입점을 위해 생성하는 리소스이다. 하나의 진입점이란 IDC 환경에서 L4 스위치를 사용할때 VIP를 사용하여 하단에 리얼 IP를 가진 서버를 묶듯이 이렇게 사용하는 VIP라고 이해하면 될것같다. 서비스가 생성되고 할당한 IP주소와 포트는 서비스가 삭제되기전까지 변하지 않는다.

 

위의 그림처럼 Service라는 하나의 진입점으로 들어온 트래픽은 하단의 포드 그룹에 로드밸런싱 된다.

 

Service의 기능중 sessionAffinity라는게 있는데 AWS ELB의 Sticky Session과 같은 기능이라고 보면 된다. ELB에서 Sticky Session을 지정하면 A클라이언트가 A인스턴스로 접속 후 다시 접속을 요청하면 B인스턴스가 아닌 A 인스턴스로 접속할 수 있게 세션을 열어주는 것인데 이것은  https://bcho.tistory.com/tag/sticky%20session 조대협님의 글을 읽어보길 추천한다.

 

 

sessionAffinity를 유지할 클라이언트 IP를 지정해야하는데 이유는 아래와 같다.

Sticky Session, 즉 sessionAffinity를 유지하려면 세션이 쿠키 기반의 옵션을 제공해야하는데 이는 HTTP 수준 (L7 Layer) 에서 동작을 해야한다. 

하지만 Service는 TCP/UDP 수준의 L4 Layer이다. 그렇기 때문에 패킷을 처리하고 페이로드 (전송되는 데이터) 에 대해서는 신경을 쓰지 않는다. 

그렇기때문에 IP를 지정해서 유지해줘야하는 것 (쿠키는 HTTP 프로토콜에서만 의미 있기 때문에 서비스는 쿠키를 처리할 수 없기에 세션이 쿠키 기반 옵션을 제공하지 않는 것) 이다.

 

이 외에 간단한 예제 몇개를 올려놓겠다.

 

- 다중 포트 노출

 

- 이름으로 포트 사용

 

Service 파일에서 포트에 name 속성을 지정하면 포드에서 포트를 적을 필요없이 http, https 등과 같이 사용할 수 있다.

 

아래는 AWS에서 Service를 생성하면 NLB로 생성되는 예제이다.

 

 

이대로 구성하면 바로 NLB가 생성된다. ALB의 경우는 이것보다는 좀 더 복잡하다. 추가되야할게 두가지 더 있다. 이건 Ingress 항목에서 설명하겠다.

 

서비스의 타입에는 ClusterIP, NodePort, LoadBalancer, External Name 이렇게 네 가지가 존재한다. LoadBalancer는 방금 위에서 설명했고 Nodeport에 대해 설명하겠다.

 

NodePort는 말 그대로 노드의 포트를 사용하는 것이다. 아래 그림을 확인해보자

 

 

우선 외부 클라이언트는 노드의 30123포트를 통해 서비스에 접근하고 서비스에서 포드에게 트래픽이 전달된다.

Service를 생성하면 노드의 포트를 랜덤으로 할당하는데 지정된 노드의 포트를 사용하고 싶으면 이렇게 사용하여도 된다.

 

 

 

여기서 연관된 리소스 중 하나인 엔드포인트에 대해 추가 설명하겠다. 서비스를 생성하고 kubectl describe svc OOO 명령을 실행하여 설명을 보면 Endpoint라는 필드가 존재한다. 

 

서비스는 포드에 직접 링크하지 않는다. 대신 이 엔드포인트라 불리는 리소스가 서비스와 포드 사이에 존재하며 이 서비스를 통해 들어오는 트래픽이 전달될 타겟을 지정한다.

즉 엔드포인트는 서비스에 의해 노출되는 IP주소와 포트의 목록이라 보면 된다.

 

 

출력 내용을 보면 포드의 IP와 포트가 엔드포인트로 지정되어 서비스에 등록되어 있다.

 

이 엔드포인트를 수동으로도 지정할 수 있는데 이런 경우 서비스가 연결을 포워딩할 IP와 포트를 직접 지정하는 경우에 사용된다.

아래는 수동으로 지정된 엔드포인트 매니페스트이다.

 

- 서비스 리소스

 

- 엔드포인트 리소스

 

위 방식은 수동으로 서비스와 엔드포인트를 지정한 방식이며 아래처럼 서비스에 ExternalName 형식으로 지정할 수 있다.

 

 

위처럼 엔드포인트를 지정하는 서비스는 클러스터 밖에 서비스에 접근하기 위해 사용된다.

 

여기서 클러스터 밖의 서비스란 AWS RDS와 같이 데이터베이스나 다른 클라우드 서비스를 의미한다. 일반적으로 대부분의 운영 서버들은 DB에 접근하기 때문에 ExternalName 템플릿은

많이 쓰일 것이다.

 

생성된 서비스를 확인해보면 아래와 같다.

 

 

여기서 하나 체크할 부분은 서비스인데도 IP가 없다. 왜 그럴까?

 

ExternalName 서비스는 기본적으로 DNS레벨에서 구현되며 작동한다. 그러므로 ExternalName 서비스로 연결하는 클라이언트는 서비스 프록시를 통하지 않고 직접 외부서비스로 연결한다.

이런 이유로 인해 ExternalName 서비스는 클러스터 IP를 얻지 못한다.

 

 

반응형

'Kubernetes' 카테고리의 다른 글

Kubernetes Ingress  (0) 2019.09.19
Kubernetes Monitoring - Version1  (0) 2019.09.17
Kubernetes HorizontalPodAutoscaler  (0) 2019.08.31
Kubernetes Pod DaemonSet  (0) 2019.08.30
Kubernetes Pod Replica  (0) 2019.08.30
728x90
반응형

Kubernetes Monitoring

 

어떤 시스템이든 가장 중요한 부분 중 하나가 모니터링 일것이다. 쿠버네티스 환경에서 모니터링 하는 방법을 알아본다.

설명할 내용은 기본 메트릭 서버, 프로메테우스이다.

 

우선 가장 기본적으로 알아야 할 것은 메트릭 (지표) 의 수집이다. 쿠버네티스 환경에서는 기본적으로 cAdvisor라는 메트릭 수집도구를 사용한다.

 

 

cAdvisor란 쿠버네티스에서 사용하는 기본적인 모니터링 에이전트로 모든 노드에 설치되서 노드에 대한 정보와 포드 (컨테이너) 에 대한 지표를 수집한다.

이렇게 수집된 내용은 Kubelet에게 전달되는데 이 후 전달된 내용은 모니터링 툴 (메트릭 서버, 프로메테우스) 에서 다시 수집해 간다.

cAdvisor의 경우 리소스 데이터만 수집한다. 이 리소스에는 CPU, Memory, Filesystem, Network Used와 같은 통계를 수집하는 것이다. 

 

리소스외에 다른 메트릭을 수집하고 싶다면 별도의 에이전트를 사용해야한다. 

이제 메트릭이 수집되는 과정을 확인해보면 아래 그림과 같다. 

 

 

cAdvisor + Metrics Server 부분은 쿠버네티스에서 사용하는 모니터링의 가장 기본적인 조합이다. 리소스만 수집하는 형태이며 조합이다.

 

데이터가 수집되는 동작 과정은 아래와 같다.

1. cAdvisor에서 노드의 정보와 포드의 지표를 수집

2. cAdvisor에서 수집한 내용을 Kubelet에게 전달

3. Metrics Server는 Kubelet에게서 수집된 정보를 가져감 

 

이런 수집된 데이터를 가지고 무엇을 할까?

 

아래의 그림을 보도록 하자. 이전 자료이기 때문에 Node X 부분에 Heapster라고 표현되어 있는데 이 부분이 메트릭 서버라고 생각하면 된다.

cAdvisor -> Kubelet -> Metrics Server 를 통해 수집된 데이터는 HPA (Pod AutoScaler) 에서 가져가고 이 데이터를 기반으로 포드를 늘려야할지 줄여야할 지 결정한다.

 

 

이제 메트릭을 생성할텐데 소스 코드는 github에서 다운받을 수 있으며 deploy 안에 있는 파일들을 하나로 합치거나

# kubectl apply -f deploy/

형태로 한번에 실행하여도 된다. (https://github.com/kubernetes-incubator/metrics-server/releases/latest)

 

메트릭 서버가 정상적으로 실행되는지 확인하는 명령은 아래와 같다. 메트릭 서버 또한 하나의 포드로 배포되며 시스템 포드 중 하나이다.

 

# kubectl get deployment metrics-server -n kube-system

 

HPA를 구성한 하고 get으로 HPA를 가져오면 

 

 

Target 부분에 지정한 리소스의 모니터링 값이 표시된다. 0%는 사용량이고 80%는 임계값이다.

 

이제 기본 메트릭서버를 만들어보았으니 프로메테우스를 생성해보겠다. 프로메테우스는 모니터링툴로 쿠버네티스 환경에서 많이 사용된다.

프로메테우스 또한 메트릭 서버와 마찬가지로 하나의 포드로 생성된다. 리소스만 수집하는 메트릭 서버와 달리 프로메테우스는 커스텀 메트릭 또한 수집할 수 있다.

 

 

 

프로메테우스를 생성하는 방법은 Helm을 사용하는 방법과 매니페스트를 사용하여 생성하는 방법인데 EKS 기반에서 프로메테우스를 실행하도록 할 것이다.

매니페스트 : https://github.com/coreos/prometheus-operator/blob/master/bundle.yaml -> kubectl apply -f bundle.yaml

Helm : helm install stable/prometheus \

--name prometheus \

--namespace prometheus \

--set alertmanager.persistentVolume.storageClass="gp2",server.persistentVolume.storageClass="gp2"

 

* Helm 설치

# Helm install

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh

chmod 700 get_helm.sh

./get_helm.sh

 

# tiller ServiceAccount Create and ClusterRoleBinding

kubectl -n kube-system create sa tiller

kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller

 

# tiller Install

helm init --service-account tiller --upgrade

 

프로메테우스 포드 구동 확인

 

 

프로메테우스를 설치하면 지표 수집 도구가 cAdvisor 뿐만 아니라 kube-state-metrics도 설치가 된다.

이제 로컬시스템에서 프로메테우스로 포트포워딩을 하여 접속 가능하게 해보자

 

# kubectl --namespace=prometheus port-forward deploy/prometheus-server 9090

 

웹 브라우저에서 localhost:9090으로 접속 하면 아래와 같이 실행된다.

 

 

이렇게 생성된 프로메테우스는 그라파나와 연결할 수 있다.

 

모니터링 부분은 아직 내용이 빈약하기 때문에 나중에 다시 정리를 해야겠다.

 

 

 

 

반응형

'Kubernetes' 카테고리의 다른 글

Kubernetes Ingress  (0) 2019.09.19
Kubernetes Service  (0) 2019.09.17
Kubernetes HorizontalPodAutoscaler  (0) 2019.08.31
Kubernetes Pod DaemonSet  (0) 2019.08.30
Kubernetes Pod Replica  (0) 2019.08.30
728x90
반응형

HorizontalPodAutoscaler

 

포드의 오토스케일링에 대해서 알아본다. 레플리카셋으로 구성된 포드는 원하는 숫자만큼 포드를 유지시켜주지만 오토스케일링을 할 수 있는 기능은 없다. 그렇기 때문에 포드를 오토스케일링하려면

별도의 포드를 구성해 오토스케일링을 해야한다. 이런 기능을 해주는 것이 HorizontalPodAutoscaler 이다.

 

오토스케일링하는 방법에는 스케일 업,다운 또는 스케일 인,아웃이 있는데 스케일 업,다운은 VPA (VerticalPodAutoscaler) 라는 기능을 사용하고 스케일 인, 아웃은 HPA (HorizontalPodAutoscaler) 를 사용한다.

지금 알아볼 것은 HPA 이다.

 

 

오토스케일링 프로세스

 

오토스케일링 프로세스는 세 단계로 나눌 수 있다.

1. 스케일된 리소스 객체가 관리하는 모든 포드의 메트릭을 가져옴

2. 지정된 목표 값에 메트릭을 가져오는 데 필요한 포드 수를 계산

3. 스케일된 리소스의 복제본 필드를 업데이트

 

 

노드 X 부분은 힙스터로 되어있는데 이제 힙스터는 사용하지 않으니 메트릭서버 또는 프로메테우스를 사용하면 된다. 

이렇게 가져온 데이터를 통해 지정된 목표값 (cpu, memory 등) 과 현재 포드 수를 계산해 포드를 늘려야할지 줄여야 할지 결정한다.

 

가져온 데이터를 계산하여 목표값보다 현재 사용중인 사용량이 많다면 HPA는 Deployment의 유지해야하는 복제수 숫자를 늘린다. 이렇게 Deployment 수정하면 Replicaset은 새로운 포드를 생성해야함을 인지하고 스케줄러에게 새로운 포드를 생성하라고 전달한다. 그러면 스케줄러는 새로운 포드를 생성할 노드를 결정하고 해당 노드의 Kubelet에게 포드를 생성하라고 요청한다. 그러면 Kubelet은 Deployment의 템플릿에 정의된 대로 포드를 생성한다. 여기까지가 포드 오토스케일링이 되는 과정이다.

 

 

HPA의 계산 매커니즘

 

 

우선 CPU 타켓 기준으로 설명을 하겠다.

현재 세개의 포드가 구동 중이고 오토스케일링을 목표 값은 CPU 50%이다. 50%가 넘으면 스케일 아웃이 되는 설정인 상태

 

HPA는 메트릭 서버에서 가져온 값을 계산하기 시작한다. 세 포드의 평균 / 목표값 을 계산하여 구동되어야할 Replicas를 결정하는데 여기서 3.6이 나왔다면 HPA는 소수점 반올림으로 4개를 실행해야한다고 결정 내린다. 그렇게 되면 스케일 아웃이되는데 아래에 Target QPS 부분도 확인해보자

 

위의 그림의 경우 오토스케일링 정책이 2개가 설정되어있는 경우이다. 목표값이 50%가 넘거나 QPS 지표가 목표값을 넘거나 하면 스케일 아웃을 하는 경우이다. 근데 그림을 보면 CPU 지표를 보면 스케일 아웃을 해야하는데 QPS는 현재 상태를 유지해도 되는 지표이다. 이런 경우 어떤 값을 따를까? 가장 높은 값을 목표 값으로 설정한다. 둘중 하나라도 스케일아웃이 필요하면 그 포드는 스케일 아웃된다.

 

이것만 알아두면 좋을것 같다. 어떤 목표값을 여러개 지정하더라도 그중 하나의 값이 스케일 아웃에 해당된다면 다른 값들은 무시되고 스케일 아웃이 진행된다.

 

스케일 아웃 계산법을 알아봤으니 스케일인에 대한 계산법도 알아본다.

목표한 값이 50이고 세개의 포드 값이 90이다. 각 포드당 CPU가 30%인경우

 

그렇게 되면 90/50 = 1.8이 된다. 필요한 포드의 수가 1.8개, 반올림하면 2개

 

즉 2개의 포드가 필요한 계산이 나오므로 HPA는 실행중인 포드의 수를 2개로 맞추기 위해 하나의 포드를 랜덤으로 삭제하게된다.

 

 

HPA 만들기

 

 

- cpu의 평균 값이 80%이상되면 스케일 아웃을 하는  HPA를 생성한 예제이다.

 

반응형

'Kubernetes' 카테고리의 다른 글

Kubernetes Ingress  (0) 2019.09.19
Kubernetes Service  (0) 2019.09.17
Kubernetes Monitoring - Version1  (0) 2019.09.17
Kubernetes Pod DaemonSet  (0) 2019.08.30
Kubernetes Pod Replica  (0) 2019.08.30

+ Recent posts