Tagged: Linux

알고리즘 – 분수(Fraction) 문제

알고리즘 – 분수(Fraction) 문제는 컴퓨터 알고리즘을 시작하는데 좋은 예제입니다. 분수는 어릴적 산수시간에 배운 그게 맞습니다. 1/2, 1/3, 1/4 식 입니다.

분수에는도 사칙연산을 할 수 있습니다. 더하기(add), 빼기(subtract), 곱셈(multiply), 나눗셈(divide) 가 그것입니다. 이를 컴퓨터 프로그램 언어를 이용해서 만들어보는 겁니다.

참고: http://interactivepython.org/runestone/static/pythonds/Introduction/ObjectOrientedProgramminginPythonDefiningClasses.html#a-fraction-class

분수의 정의와 제약사항

분수는 다음과 같이 정의됩니다.

수학에서 분수(分數, fraction)는 a/b 이나  \frac {a} {b} 꼴로 표시한다. 이것은 a를 b로 나눈 값, 즉 a와 b의 를 뜻하며, 여기서 a는 분자b는 분모라고 한다. 이 때 분모 b에 0이 들어가는  \frac {a} {0}(a는 상수)라는 수는 정의될 수 없으므로 b0 이어야 한다.

From 위키페디아

중요한 것이 분모는 0 이여서는 안됩니다. 또 한가지 이 글에서 제약조건을 걸어야 하는데, 분자와 분모 모두 양수로만 이루어진 분수를 다룹니다. 또, 모두 정수여야 합니다. 이를 정리하면 다음과 같습니다.

  • 분모는 0 이여서는 안됩니다.
  • 분자, 분모는 모두 양의 정수(양수이며 정수)

분수의 덧셈

분수의 덧셈은 먼저 분모를 ‘통분’해야 합니다. 무슨말이냐 하면 덧셈을 하기 위한 두개의 분수들의 분모 크기를 같은 값으로 만드는 것(=분모를 통일하는것)입니다. 예를들어

1/2 + 1/3 이 있다면 분모를 통분하는데 서로서로 분모값을 분자,분모에 곱해주면 됩니다. (1*3)/(2*3) + (1*2)/(3*2) = 3/6 + 2/6 = 5/6

분모가 같아지니까 분자만 그대로 더해주면 됩니다.

분수의 뺄셈

분수의 뺄셈은 분수의 덧셈과 마찬가지로 분모를 통분해주고 분자까리 빼주면 됩니다.

분수의 곳셈

분자는 분자까리, 분모는 분모끼리 곳해주면 끝~

분수의 나눗셈

나누는 분수을 역으로 바꾸고 둘을 곱셈하면 된다.

2/5 나누기 1/3 = 2/5 * 3/1 = 6/5

여기까지가 분수에 관한 수학적 알고리즘입니다.

컴퓨터 알고리즘

컴퓨터 알고리즘은 컴퓨터를 이용해서 문제를 해결하는 방법입니다. 그럴려면 아무래도 프로그래밍을 해야하고 프로그래밍을 위해서는 프로그램 언어를 이용해야 합니다. Python, Java, PHP 등이 여기에 속합니다.

한가지 컴퓨터 알고리즘을 할때에는 선택한 언어의 특성을 이용하는 경우가 있습니다. 예를들어 Python 을 이용할 경우에 내장 메소드를 이용할 수 있는데, 이번 분수 알고리즘에서 이를 사용할 것입니다. 다른 언어로 구현할 경우에는 이러한 Python 의 내장 메소드 기능을 제공하지 않기 때문에 다르게 구현을 해야합니다.

이 말은 결국 컴퓨터 알고리즘을 구현하는데 사용하는 언어에 영향을 어느정도 받는다는 것입니다.

Python 의 특징(python3.4 기준)

Python 은 내장 메소드를 지원합니다. 이는 모든 데이터를 객체로 인식하고 레퍼런스하기 때문에 가능한 것입니다. 단순한 숫자조차도 다양한 메소드를 지원합니다.

위에 보시면 숫자에 대한 내장 메소드를 볼수 있습니다. 이 내장 메소드들은 특정한 연산을할때에 자동으로 작동합니다. 예를들어, ‘__add__’ 의 경우는 숫자를 더할때에 자동적으로 호출되어 작동합니다.

Python 에서 사칙연산에 관한 내장 메소드는 다음과 같습니다.

구현하기

Fraction 이라는 클래스를 만들고 내장 함수들을 조작함으로써 완성함으로써 완성됩니다.

먼저 두개의 숫자를 입력받는걸로 분수를 만듭니다.

그리고 덧셈 테스트를 해봅니다.

같은 클래스의 객체를 만들어서 덧셈을 해보면 저렇게 내장 메소드가 없다라고 나옵니다. 그러면 저 내장 메소드를 만들어주면 됩니다.

위와같이 덧셈 내장 메소드를 정의해주고 다음과 같이 테스트를 합니다.

잘 되네요. 뺄셈, 곱셈, 나눗셈은 앞에서 말한 방법대로 내장 메소드를 이용해서 구현하면 됩니다.

제약조건인 음수와 0에 대한 것을 예외로 처리하였습니다. 다음과 같이 실행 합니다.

마이너스(-) 표시가 마음에 안들긴하지만 일단 구현까지만하는 걸로..

ELK 구축하기 1 – Logstash

ELK 는 ElasticSearch, Logstash, Kibana 를 말하며 보통 이 시스템은 실시간 로그분석 시스템으로 불리웁니다. Logstash 는 로그를 실시간으로 전송하고 ElasticSearch 는 전송된 로그를 검색 인덱스를 만들어 보관하며 Kibana 는 ElasticSearch 의 분석한 자료를 시각화해줍니다.

이를 이용하면 시스템 자체 뿐만 아니라 각종 애플리케이션의 로그들을 분석하고 시각화된 통계자료를 자동으로 얻을 수 있습니다.

첫번째로 Logstash 를 설치해보도록 하겠습니다.

설치

Logstash 는 Java 7 이상이 필요합니다. Java 7 을 설치해야 합니다. 이것이 없으면 동작이 안됩니다.

Logstash 홈페이지에서 다운로드 받아 설치할 수 있습니다. tar.gz 도 있고 우분투, 레드햇 패키지도 있어 자신에게 필요한 것을 받아 설치하면 됩니다.

 

기본개념

Logstash 의 기본 개념을 잠깐 살펴보겠습니다.

마치 쉘(Shell)의 파이프라인(pipeline)처럼 동작합니다. 입력을 받아서 출력을 해주는 구조 입니다. 그리고 입력 받은 내용을 필터링을 하고 출력할 수도 있습니다.

Logstash 에서 Input, Filter, Output 이 핵심이며 다양한 Input, Filter, Output 에 대응하기 위해서 각각 플러그인을 가지고 있습니다. 예를들어 다양한 입력을 받아야 하는 경우에 운영자가 Input 자체를 구성할 수 있지만 누군가 만들어놓은 플러그인 설치하면 끝나게 됩니다.

basic_logstash_pipeline

결국 Logstash 를 운영은 수집하고자 하는 로그에 대해서 Input, Filter, Output 어떻게 만들고 구성할것인가가 핵심이 됩니다. 그래서 설정파일의 형식은 다음과 같습니다.

 

사용법

명령행으로 사용할 수 있습니다.

‘-e’ 옵션은 명령행에서 설정파일을 작성할 수 있도록 해줍니다. 설정 내용을 보면 input 부분에 ‘stdin{}’ 으로 표준입력을 받겠다는 것이고 output 에 ‘stdout{}’ 으로 표준출력으로 결과를 내보내겠다는 뜻입니다.

이제 아파치 로그 파일을 Logstash 설정파일을 만들어 분석해보도록 하겠습니다. 먼저 input 부분을 정의해 줘야 합니다. 예를들면 다음과 같습니다.

‘input{}’ 에는 어떤 형태의 입력을 받을 것인가를 정의하는데 이것을 플러그인(Plugin)이라고 합니다. 그래서 ‘input 플러그인이 무엇이냐?’하는 질문이 가능합니다. 여기서는 ‘file’ 이되며 보다 자세한 사항은 ‘Input plugins‘ 페이지를 참고하시면 됩니다. 그에 따른 세부사항을 설정하도록 되어 있습니다. 위 예제에서는 file 로부터 받을 것이기에 형태를 file 로 했고 세부사항으로 파일의 경로와 ‘start_position’ 을 정의했습니다. file 형태로 입력을 받을 경우에 기본값은 Unix 시스템의 ‘tail -f’ 와 같이 실시간으로 파일에 새롭게 써지는 로그들을 읽도록 되어 있는데 이를 바꾸고자 한다면 ‘start_position’을 이용하면 되고 위 예제에서는 파일의 처음부터 읽도록 바꾸었습니다.

다음으로 filter 을 정의해야 합니다. 아파치 로그를 파싱하기 위한 작업입니다. 역시나 filter plugin 들이 아주 많은데, 여기서는 기본으로 가지고 있는 grok 을 사용해서 다음과 같이 로그 파싱을 정의해줍니다.

아파치로그를 커스터마이징했다면 위의 예제와는 다르게 정의해야 합니다. 위 예제는 아파치로그가 “COMBINED” 로그로 설정되어 있어서 이 형태를 파싱하겠다 것입니다.

Output plugin 은 화면으로 출력을 하기위해 다음과 같이 stdout 을 사용합니다.

이것을 하나의 파일에 저장한 후에 다음과 같이 실행해 줍니다.

위와같이 원하는 결과가 화면에 나옵니다.

Python JSON Tool 을 이용한 Readable한 JSON 출력하기.

Python 을 설치하면 JSON Tool 이 포함됩니다. Python JSON Tool 을 이용한  Readable한 JSON 출력이 가능합니다. 즉 쉘 상에서 JSON 포맷을 보기 좋게 볼수 있습니다. 보통은 다음과 같이 출력되서 쉽게 알아보기 힘듭니다.

이를 보기 좋게 출력하는 방법은 다음과 같습니다.

 

패키지내에 파일 보기

패키지를 설치하기전에 그 패키지에 어떤 파일들이 들어 있는지를 알고 싶을때가 있습니다. Ubuntu, CentOS 에서 명령어로 모두 가능합니다.

Ubuntu 의 경우

Ubuntu 에서는 apt-file 명령어로 간단하게 가능합니다.

설치

설치는 다음과 같이 ‘apt-get’ 명령어로 간단하게 됩니다.

File 리스트 업데이트

파일 내역들을 업데이트를 다음과 같이 해줍니다.

패키지에 File 리스트 보기

다음과 같이 간단하게 살펴볼 수 있습니다.

CentOS 의 경우

CentOS 에는 repoquery  명령어로 가능합니다. 이는 yum-utils 를 설치하면 있습니다.

설치

yum 명령어로 yum-utils 설치 가능합니다.

파일 보기

파일 보기는 다음의 명령어로 확인 가능합니다.

 

리모트 스크립트 제작기

DevOps 가 대두되면서 지속적인 배포(Continuous Delivery) 가 핵심으로 떠오르면서 수만은 서버에 한꺼번에 명령어를 내리고 파일을 전송하고 설정파일을 관리하는 소프트웨어가 인기를 끌고 있다.

대표적으로 Chef, Puppet, Saltstack, Ansible 등을 들수 있는데 이들은 지속적인 배포 뿐만 아니라 시스템과 소프트웨어를 통합해 플랫폼으로서 수많은 서버들의 상태를 동일하게 유지시켜준다.

그런데 몇 해전만 해도 이런것들이 부족했던 시절이 있었는데, 이때 내가 다니던 직장에서 수천대의 서버를 관리해야하는 일이였다. 이러한 소프트웨어가 없던 시절에 나는 개인적으로 이와 비슷한 것을 만들어 사용했는데 그때 당시로 돌아가 어떤 생각으로 만들었었는지 개선했는지를 정리해보고자 한다.

쉘 스크립트

처음에 수십대 서버에 명령어를 보내야했다. 궁리를 한 끝에 생각난 것이 쉘 스크립트로 돌리자는 거였다. 리눅스를 조금 한 사람이면 expect 라는 명령어를 알 것이다. 이 명령어는 어떤 명령어를 날렸을 경우에 돌아오는 답변을 미리 기대해(expect)해서 그것을 파싱하고 자동으로 다시 답변을 해주는 명령어였다.

수백대에 명령어를 보내야 했었는데, 수백대의 서버이름은 파일로 저장해놓고 expect 쉘 스크립트를 작성하면 될 일이였다.

그런데 이게 생각만큼 쉽지 않았다. 먼저 쉘 스크립트를 지금도 잘 모르지만, 예외처리를 하기에 힘들었다. 로그인은 성공했지만 예기치 못하게 접속이 차단되거나 기대했던 프롬프트가 나오지 않아서 명령어가 실행되지 않는등 문제가 많았다.

그래도 그때 당시에는 좋았다. 오류가 나오기도 했지만 100대중 5대 내외여서 나름대로 좋았는데, 사람이 간사한게 처음에는 불편했던것을 감수했지만 시간이 지나자 감수했던 불편함을 어떻게든 없애고 싶은 생각이 들었다. 불편했던 것들은 다음과 같았다.

  • 기대하는 프롬프트가 다양하게 나타났다.
  • 예외처리를 하기가 힘들었다.
  • 정상적인 결과나 오류등을 파일로 저장하고 싶었다.
  • 동시에 여러서버들에 실행되길 원했다.

쉘 스크립트말고 다른 프로그래밍 언어를 사용하면 최소한 예외처리나 정상적결과나 오류등을 파일로 저장하는 것이 가능해질것 같았고 평소 사용하던 Python 프로그래밍을 사용해보기로 했다.

expect 프로그래밍 for python

Python은 아주 좋은 언어임에 틀림이 없었다. expect 프로그램을 지원하는 python 라이브러리가 존재했다. pexpect 모듈이 그것이였다.

pexpect 모듈과 Python 이 지원하는 쓰레드(thread) 그리고 로깅(logging) 기능을 조합하면 좋은 꽤나 쓸만한 프로그램이 나올것이 분명해 보였다.

15번째줄에 보면 기대되는 프롬프트를 적어준다. 위 예제에서는 간단하게 나왔지만 Python이 제공하는 정규표현식을 사용할 수도 있다. 위 예제를 기반으로 쓰레드를 붙이고 로깅을 붙이고 해서 여러서버에 동시에 명령어를 넣을 수 있게 되었다.

나름대로 만족하고 있었는데, 기대되는 프롬프트가 문제였다. 리눅스는 다양한 배포판을 사용하다보니 기대하는 프롬프트가 조금씩 달랐다. 거기다 SSH 접속할때에 가끔씩 인증키가 충돌이 나는 일도 있어서 기대하는 프롬프트를 리스트로 가지고 있어야 했다.

귀찮은게 문제였다. 어떻게 하면 저런것까지 신경 안쓰면서 명령어를 날리고 로깅을 할 수 있을까 하는 문제 말이지…

pxssh 모듈

pxssh 모듈은 귀찮이즘에 적어드는 시기에 찾은 신변기(?) 였다. 이 Python 모듈은 기대하는 프롬프트를 신경쓸 필요가 없었다. 최초로 접속하는 서버일지라도 알아서 HostKey 를 교환했고 프롬프트가 달라도 알아서 해주는 매우 좋은 녀석이였다.

pxssh 모듈은 위의 예제처럼 기대되는 프롬프트는 필요가 없다. 대신 한가지 특징이 있는데, pxssh 모듈은 결과값을 before, after 변수에 저장된다. 그래서 19번째 라인처럼 값을 불러오면 된다.

그런데, 한가지 문제가 있었다. 이번에는 파일을 전송하고 싶었던 것이다.

paramiko 모듈

이런저런 고민을 풀면서 일명 자동화 명령어 프로그램을 만드는 동안에 많은 검색을 하게되면서 많은 자료를 모울 수 있다. 그러던중에 paramiko python 모듈을 보게 됐다.

paramiko 는 ssh, sftp 프로토콜을 지원줘서 python 으로 ssh, sftp 프로그래밍이 가능하도록 만들주는 라이브러리였다. 올타쿠나!! 이거야!! 그래서 명령어 전송부터해서 파일 전송을 전부 이것으로 교체하기로하고 만들었지만 문제가 있었다.

paramiko 의 SSHClient 클래스를 지원하는데 이는 SSH를 이용해서 로그인을 할 수 있도록 한것인데, 문제는 pxssh 와 비교해보니 속도면에서 많이 느렸다. (물론 내가 잘못 짠 것일 수도 있다.) 그래서 paramiko 는 파일 전송을 하는데 사용하고 명령어를 쓸때는 pxssh 를 사용하도록 스크립트 두개를 사용하도록 했다.

대충 위와같이 프로그램을 짰다.

지금은 Python에서 Fabric 프로그램이라고 많이 사용하고 있다. fabfile.py 에 관련 내용을 작성하면 fab 명령어가 이 파일을 자동으로 인식해 내부에 작성된 메소드들을 실행해주는 방법이다. 파일 전송도 가능하다.

요즘은 Chef, Puppet, Saltstack 과 같은 것들을 사용하면 파일 배포및 명령어도 아주 쉽게 할수 있는 시대에 살지만 아주 간단하게 뭔가를 하고 싶을때에 종종 만들어 두었던 python 프로그램들을 사용하곤 한다.

Opensshd 7.0에서 바뀐점

OpenSSHD 7.0 에서 바뀐점이 있습니다. SSH 데몬이 인증을 하는 방법에는 다음과 같이 두가지가 있습니다.

  1. 패스워드 인증 – interactive authentication methods
  2. 인증키 방식

패스워드 인증 방법을 “interactive authentication methods” 라고 합니다. 그런데, OpenSSHD 7.0 에서는 root 로그인할때에는 더 이상 이 인증 방법을 지원하지 않습니다

CentOS 7 에서 Opensshd 7.0 이상 패키지를 설치를 해서 root로 로그인을 할려고 보니 패스워드 입력 프롬프트는 나옵니다. 하지만, 맞는 패스워드를 아무리 쳐도 로그인이 안되더군요. 그래서 뭔가 바뀌었나 싶어서 Changelog 를 살펴보니 다음과 같은 문구를 보게 되었습니다.

OpenSSHD 에 설정내용중에 “PermitRootLogin” 옵션이 있는데, 이전에는 이게 yes/no 를 입력하도록 되어있었지만 7.0 이상부터는 “without-password/prohibit-password” 로 변경되었고 “prohibit-password” 를 한다고 하더라도 모든 interactive authentication methods 를 차단(Ban)하고 인증키 방식을 지원한다고 되어 있습니다.

요약을 하면 root 사용자로 openssh 7.0 이상 서버에 로그인하기위해서는 인증키 방법을 이용해야 한다는 겁니다.

SSH 인증키 생성 방법.

인증키 생성은 다음과 같이 ssh-keygen 프로그램을 이용합니다.

이렇게하면 “/root/.ssh/id_rsa, /root/.ssh/id_rsa.pub” 두개의 파일이 생성이 됩니다. id_rsa 는 private key 이고 id_rsa.pub 는 public key 입니다. public key 는 sshd_config 설정파일에 기재된 이름으로 변경해줍니다.

id_rsa.pub 를 authroized_keys 파일로 바꿔 줍니다.  id_rsa 파일은 usb나 접속을 할려고하는 컴퓨터에 복사해 둡니다.

이제 다음과 같이 접속을 시도합니다.

 

ps, openssh-server 7.0 이상 패키지는 Fedora 배포판 23 버전에서 찾을 수 있습니다. Fedora 23 배포판은 7.1 버전 입니다.

SaltStack 에서 Jinja 사용시 유용한 팁

Salt 는 Jinja Template 을 지원해 Salt 파일 작성시에 프로그래밍이 가능하도록 되어 있습니다.  예를들어 배포판별로 아파치 웹 서버의 패키지 이름이 다른데, Jinja Template 를 이용하면 프로그래밍을 할 수 있습니다.

Salt 의 grains 을 이용해서 배포판을 가지고 오고 조건식(if statement)를 이용해서 패키지명을 명시해주고 있습니다.

하지만 이렇게하면 Salt 자체의 YAML 문법과 섞여서 읽기가 힘든 부분이 있습니다. 그래서 이를 다음과 같이 개선할 수 있습니다.

조건식을 앞으로 빼고 변수를 이용해서 패키지명을 저장해주고 이 변수를 Salt YAML 문법에 사용하는 것입니다. 앞에 버전보다는 Jinja 문법과 YAML 이 분리가 되어서 읽기가 매우 편해졌습니다.

또 다른 좀 더 나은 버전으로는 앞의 Jinja 문법을 다음과 같이 간소화할 수 있습니다.

출처: Salt Formulas

Vim 디렉토리 구조.

Vim 은 Unix/Linux 시스템에서 가장 있기는 편집기(Editor) 입니다. 터미널상에서 다양한 파일들을 편집할 수 있고 다양한 기능을 제공 합니다. 다양한 기능들은 플러그인(Plugin) 들로 제작되어 필요로하는 기능들만 사용할 수 있습니다. 이러한 플러그인들은 Vim 의 디렉토리에 넣기만하면 동작하도록 아주 간편하게 되어 있습니다.

이 문서는 다음의 문서를 직역해서 만들어졌습니다. 이글의 저작권도 원글에 있음을 밝힙니다.

기본 레이아웃(Basic Layout)

Vim 은 여러파일들로 분리된 플러그인들을 지원합니다.  “~/.vim” 디렉토리 아래에 새성할 수 있는 아주 많은 다른 디렉토리들은 많은 것을 의미합니다.

이제 아주 중요한 디렉토리들에 대해서 살펴보고 그들에 대한 스트레스를 날려버리자.

~/.vim/colors/

~/.vim/colors/ 안에 파일들은 컬러(Color) 스킴(Shemes)들을 다룹니다. 예를들어 (vim 실행상태에서 Command Mode 에서) “:color mycolors” 를 실행한다면 Vim 은 “~/.vim/colors/mycolors.vim” 파일을 찾을 것이고 그것을 실행할 겁니다. 이 파일은 컬러 스킴을 생성하는데 필요한 모든 Vimscript 명령어들을 포함해야 합니다.

여기서 컬러 스킴에 대해서 다루지 않을 것입니다. 만일 자신만의 컬러 스킴을 원한다면 이미 존재하는 컬러스킴을 복사하고 수정하면 됩니다. “:help” 는 여러분의 침구라는 걸 기억하세요(응?)

~/.vim/plugin/

“~/.vim/plugin/” 안에 파일들은 Vim 이 시작되는 매순간마다 각각 실행 됩니다. 이러한 파일들은  Vim 을 시작할때 마다 항상 로드되어질 원하는 코드를 포함한다는 것을 의미합니다.

~/.vim/ftdetect/

“~/.vim/ftdetect/” 안에 모든 파일들 역시 Vim이 시작될때마다 실행되어 집니다.

“ftdetect”는 “filetype detection”을 의미 합니다. 이 디렉토리안에 파일들은 탐지와 파일들의 파일타입이 지정하거나 아무것도 안하는 자동명령어들을 설정합니다. 이것은 하나 혹은 두라인 이상 길게 존재하지 않는다는 것을 의미합니다. (뭔소리??)

~/.vim/ftplugin/

“~/.vim/ftplugin/” 안에 파일들은 다릅니다.

The naming of these files matters! Vim 이 버퍼의 “filetype” 값으로 지정되면, “~/.vim/ftplugin/” 에서 일치하는 파일을 찾습니다. 예를들어, 만약 “set filetype=derp” 를 실행하면, Vim 은 “~/.vim/ftplugin/derp.vim” 을 찾을 것입니다. 그리고 만약 파일이 존재한다면 이것을 실행할 것입니다.

Vim 은 또한 “~/.vim/ftplugin/” 안에 디렉토리들을 지원 합니다. 예제에서 “set filetype=derp” 는  “~/.vim/ftplugin/derp/” 안에 모든 “*.vim” 파일들을 실행 시킵니다.  이것은 플러그인의 “ftplugin” 파일들을 로지컬 그룹으로 나눕니다.

이러한 파일들이 매번 버퍼의 filetype을 실행시키기 위해서는 반드시 buffer-local 옵션들을 지정해줘야 합니다. 만얀 전역적으로 옵션들을 지정했다면 모든 열린 버퍼들을 덮어쓰게 됩니다.

~/.vim/indent/

“~/.vim/indent/” 에 파일들은 “ftplugin” 파일과 매우 유사합니다. 그들은 그들의 이름을 기반으로 로드됩니다.

“indent” 파일들은 그들의 파일타입에 들여쓰기와 연관된 옵션들을 지정하고 이러한 옵션들은 buffer-local에 존재해야 합니다.

당연히, 단순하게 “ftplugin” 파일들에 이러한 코드를 집어넣을 수 있지만 Vim 사용자들이 당신이 무슨 일을 하는지 이해할수 있도록 이것을 분리시키는게 더 낫습니다. 이건단지 관습적인 것인데, 플러그인 제작자를 배려하도록 그것을 따르는게 좋습니다.

~/.vim/compiler/

“~/.vim/compiler/”에 파일들은 정확하게 indent 파일들처럼 동작합니다. 이것은 이름을 기반으로 현재 버퍼에서 compiler-related 옵션들을 지정합니다.

~/.vim/after/

“~/.vim/after/” 디렉토리는 약간의 꼼수같은 겁니다.  이 디렉토리에 파일들은 Vim 이 시작될때마다 로드되어 지지만, “~/.vim/plugin/” 에 파일이후에나 로드되어 집니다.

이것은 Vim의 내부 파일들을 오버라이드(override) 하도록 허용합니다.

~/.vim/autoload/

“~/.vim/autoload” 디렉토리는 굉장한 꼼수다. 들리기로는 실제보다 뭔가 더 복잡해 보입니다.

아주 간단하게 말하면, “autoload” 는 실제로 필요할때까지 플러그인 코드 로딩을 지연시키는 방법입니다.

~/.vim/doc/

마지막으로, “~/.vim/doc/” 디렉토리는 플러그인에 대한 문서를 위한 디렉토리 입니다.

salt-ssh, 에이전트 없이 SaltStack 사용하기

SaltStack 은 기본적으로 서버/클라이언트 구조를 가집니다. 서버는 중앙집중식으로 Salt-master 라 불리우고 각각의 관리대상이 되는 서버들에는 클라이언트로 Agent 가 설치되는데 이것을 Salt-minion 이라고 부릅니다. 이 둘이 통신을 주고받으면서 작동하게 되는 방식입니다.

하지만, 새로운 서버를 설치했을때에는 Agent 가 없기 때문에 SSH 로 원격 접속이 가능하다고 하더라도 Salt-minion 을 설치하기 전까지 수동으로 사람이 서버를 다루어야 하는 불편함이 존재합니다.

그래서 Saltstack 은 Salt-minion이 없이 SSH를 통해서 Salt 를 실행시킬 수 있도록 모듈을 제작했는데, 그것이 바로 Salt-ssh 입니다.

Environment

이 글을 예제는 전부 다음의 환경에서 작성되었습니다.

  • CentOS 7
  • 64bit
  • epel YUM repository installation

Salt-SSH 를 설치하기 위해서 epel YUM Repository 를 설치했습니다.

Install Salt-SSH

epel YUM repository 를 설치했다면 간단하게 Yum 명령어로 최신의 패키지를 설치할 수 있습니다.

의존성 패키지도 함께 설치가 됩니다.

또다른 설치 방법이 있는데, SaltSack 자체가 Python 으로 제작되었고 라이브러리(Library)이기 때문에 Python 의 패키지 설치 프로그램인 pip 를 이용해서 다음과 같이 설치가 가능합니다.

위와같이 설치했을 경우에 실행은 항상 python의 가상환경에서 실행을 해줘야 합니다.

Saltfile 작성

salt-ssh 는 master, minion 도 아닌 독자적인 패키지 이기 때문에 자체적인 글로벌한 환경세팅 파일을 가지는데 이것이 바로 Saltfile 입니다. Saltfile 는 salt-ssh 의 전체적인 동작방법과 설정디렉토리등을 정의하며, 이 파일이 존재하는 위치를 기준으로 상대적인 루트(Root)로 인식합니다.

한가지 말씀드리면, 이 파일은 절대적으로 필요하지는 않습니다. salt-ssh 를 실행할때마다 옵션으로 지정해줘도 됩니다.

roster 작성

이 파일은 접속하고자하는 서버의 정보를 기술한 파일입니다. minion_id, 호스트명(혹은 ip), 로그인을 위한 계정정보 등을 담고 있습니다. 대략 다음과 같습니다.

이 파일은 Saltfile 에서 정의한 config_dir 디렉토리에 있어야 합니다.

salt-ssh 는 어떤 시스템 계정에서든 가능합니다. 보통은 Salt 라는 일반 계정을 만들어서 하는 경우가 많은데, salt-ssh 역시 일반 계정으로 가능합니다. 이번 예제도 salt 라는 시스템계정을 만들어서 진행했고 지금까지 파일시스템 레이아웃은 다음과 같습니다.

master 파일 작성

salt-ssh 도 salt-master 와 같이 master 설정파일을 필요로 합니다. 이는 Saltfile 에서 정의해준 디렉토리인 etc/salt 디렉토리에 다음과 같이 만들어 줍니다.

salt-ssh 실행

다음과 같이 실행해 봅니다.

로깅을 위한 디렉토리를 만들어 줍니다. 주의할점은 salt 시스템 계정을 루트(root) 디렉토리로해서 만들어 줍니다.

디렉토리를 만들고 다시 실행을 하면, 뭔가 진행이 됩니다. 메시지를 자세히보면 ‘-i’ 옵션을 사용하라고 나옵니다. ‘-i’ 옵션을 이용해 다시 실행하면 다음과 같은 결과를 보여줍니다.

매우 잘 동작합니다.

salt-ssh 를 위한 SSH Key 배포

salt-ssh 는 기본적으로 ssh 의 rsa 비대칭키를 기반으로 인증을 합니다. 이는 config_dir 디렉토리 안에 pki 디렉토리에 들어 있습니다.

SSH 의 비대칭키를 이용하면 아이디/패스워드가 필요가 없습니다. salt-ssh 를 통해서 명령어를 실행시킬 권한을 가진 사용자, 대부분 root 나 sudo 권한을 가진 사용자 시스템 계정에 이키를 복사해두면 roster 에 아이디/패스워드를 적어둘 필요가 없습니다. 공개키만 배포하면되는데, 다음과 같이 합니다.

실제로 ‘192.168.96.20’ 서버에 root 계정에 .ssh 디렉토리를 살펴보면 ‘authorized_keys’ 파일이 생성된걸 볼수 있습니다.

이제 roster 에서 계정정보를 삭제하더라도 salt-ssh 는 잘 동작합니다.