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

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

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

 

쓰레드 묶음으로 처리하기..

처리해야할 태스크가 100여개 있는데, 이것을 3개씩 처리하고 싶은 경우가 있습니다. 이럴때는 쓰레드 생성 함수를 루핑 돌리면서 처리해주면 됩니다.

아래 소스는 Practical threaded programming with Python 를 기반으로 작성되었습니다.

 

패키지내에 파일 보기

패키지를 설치하기전에 그 패키지에 어떤 파일들이 들어 있는지를 알고 싶을때가 있습니다. 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 는 잘 동작합니다.

한국에서 시스템 엔지니어로 산다는거.

한국에서 가장 큰 병폐가 무엇일까? 자주자주 그리고 오랫동안 생각해온 문제였고 사회생활을 비롯한 각종 활동에서도 이러한 물음에 대한 답을 찾기위한 약간의 실험같은 것을 했었다.

이에 대한 물음에 적절한 또 다른 물음은 ‘당신 곁에서 나약해보이고 없어보이는, 능력이던 재력이던간에, 사람이 있을 경우에 어떻게 대할 것인가?’ 라는 것이 있다. 한국에서 ‘없어보인다’ 라는 말은 굉장히 많은 의미를 담아낼 수 있는 말이다. 능력이 없을수도 있고 재력이 없을수도 있고 외모가 없을수도 있고 전체적으로 풍기는 이미지가 못미더울 수도 있는 가져다 붙이면 다 되는 말이라고나 할까.

내 직업은 시스템 엔지니어다. 아니, 정확하게 말하면 시스템 엔지니어도 아니고 그렇다고 개발자도 아니다. 굳이 말하자면 소프트웨어 엔지니어라에 더 근접한다. 그런데도 일단은 서버 시스템을 더 많이 다룬다. 뭔가를 설치하고 설치한 프로그램이 제대로 동작하는지를 모니터링하고 시스템을 튜닝하고 보안 업데이트를 하고 하는 일이 주다.

그런데, 지금 내가 하는 직업이 한국에서는 별로 좋은 직업이 아닌게 분명해지고 있다. 여기서 별로 좋은 직업이 아니다라는 말에 의미는 앞에서 말한 ‘없어보이는 직업’이라는 뜻과 같다.

IT 산업은 거대하다. 그 속에는 각종 직업군들이 존재한다. 프로그래머, 시스템 엔지니어, 네트워크 엔지니어등등 다양하다. 그런데, 시스템 엔지니어를 수년간하면서 느낀점은 제일 없어보이는 직업군이라는 거다.

잘 동작하던 서버 프로그램이 오류를내거나 응답반응을 하지 않을 경우에 제일 먼저 누구를 찾을까? 시스템에는 몇달간 변경사항이 없었지만 서버 프로그램에서 돌리는 소프트웨어에는(예를들면, Python, php, Java등등) 많은 변경이 있었다. 그런데도 문제가 생기면 시스템 엔지니어를 먼저 찾는다. 왜? 프로그래머는 자신이 변경한 코드에 대해서 발생되는 문제에 대해서 1차적 책임을 지지않는가?

시스템 엔지니어는 고달픈 직업이다. 예를들어, LAMP 시스템을 운영한다고 한다면 시스템 엔지니어는 리눅스만 알아서는 안된다. Apache, MySQL, PHP 에 대한 설정과 그러한 설정이 시스템에 어떠한 영향을 미치는지도 함께 알아야 한다. 더 나가서는 PHP, MySQL 개발 경력도 필요로한다.

실제로 시스템 엔지니어를 뽑는다는 구직조건들을보면 다음과 같은 것들을 자주 보게 된다.

SM – Java 개발경력 3년차, Tomcat, Spring, Hibernate 시스템 운영.

시스템엔지니어 – LAMP 시스템. PHP개발자 경험자 우대. L4 스위치 및 네트워크 운영.

그런데도 이러한 사람들의 경력 5년차의 경우에 국내 연봉이 얼마정도 일까? 잘나간다는, 다섯손가락에 꼽는 회사들을 빼고는 거의 대기업 신입초봉과 비슷한 정도다.

더욱 심각한 문제는 사공이 많은 것이다. 시스템을 구축할때에 이래라 저래라하는 인간들이 너무나 많다. IT 산업내 직업군중에서 자신의 소관도 아닌데도 타인에게 감놔라 배추놔라를 직업군이 있다면 그게바로 시스템엔지니어들이다.

이번에 시스템 구축할때 우리도 AWS 로하면 안되요?

AWS 로 하면 AutoScaling, Provisioning 도 되게 준비를 다해줬으면 좋겠습니다. 아, 거기다 자동배포도 되게 해주세요.

시스템엔지니어들이 언제부터가 개발자들을 고객으로 맞이했는지는 모르겠다. 저런걸 구축해주면 AWS 모니터링부터 AutoScaling, Provisioning 등에 유지보수등을 도맞아서 해줄건가? 거기다 안타갑게도 대부분의 국내시스템에서 AutoScaling, Provisioning 을 할만큼 예측불가능한 전체 시스템 스케일을 가진 경우는 거의 없다. 바꿔 말하면 대략적으로 몇대정도 시스템이 필요한지 다 예측가능한 시스템이다.

그런데도 어디서 주워들었는지 트랜드를 쫓아가고 싶어서인지 이것저것 간섭하는 이들이 적지 않다. 그런 간섭은 거의다 개발자들이 였다.

개발자들이 보기에 시스템엔지니어는 없어보이는 직업군이다. 자신들은 개발자들이기에 TCP 서버도 개발해보고 C도 개발해보고 더나가 C로 짜여진 리눅스 시스템을 시스템엔지니어들보다 더 잘 이해한다고 생각하고 그래서 개발하고는 거리가 먼 시스템엔지니어를 한단계 낮게 본다.

그래서 뭔가 시스템엔지니어가 시스템에 뭔가를 바꾼다라고 공지를하면 자신이 개발한 경험 TCP/IP 개발이나 시스템개발을 한 지식을 기반으로 ‘니들이 시스템 내부를 잘 모르나본데, 그거 바꾸는 이유는 알고 하는거냐?’ 식의 핀잔이나 ‘개발자가 갑이지 시스템엔지니어는 무슨… ‘ 식의 면박을 받기 쉽상이다. 개발자들은 그냥 시스템을 다루는 명령어 사전만 모를뿐이고 그러한 명령어 사전은 별 의미가 없다는 인식이 팽배하다.

자, 다시 글의 처음으로 돌아가보자. 한국 사회의 병폐가 무엇이라 보는가? IT산업내에 많은 직업군내에서 존재하는 서열. 개발자 갑, 시스템엔지니어 을, 네트워크 엔지니어 별동대. 이글을 읽는 개발자들은 ‘니만 경험한 세계’, ‘소수일뿐이다’ 따위의 생각은 ‘당신은 경험이 없다’는 걸 반증하는 것밖에 안된다. 자신은 고결한 경력을 쌓아서 주변에 그렇지 않았다가 아니라 그런한 문제를 피했다라는걸 말하는거밖에 안된다. 마치 사회문제에 무감각한것처럼..

한국 사회의 병폐는 ‘없어보이는자’ 위에 올라서서 이래라 저래라하는 사고체계에 있다. 한국인이 이해하려고 하지 않는 단어

Respect

개발자들은 시스템엔지니어를 Respect 합니까? 아니 더나가 각종 타 직업군들에 대해서 Respect 합니까?

리눅스 공유 메모리

리눅스 공유 메모리는 아주 특별하고 중요합니다. 튜닝하는데 있어서 매우 중요한 요소이기 때문입니다. PostgreSQL 를 세팅할때에도 반드시 해줘야 하는 것이기에 정확하게 무엇인지 짚고 넘어가고자 아는 선에 적습니다.

페이지(Page)

가장 먼저 이야기할 것이 바로 페이지(Page) 입니다. 리눅스 시스템은 메모리를 가상으로 만들어 관리합니다. 웃기게도 리눅스 시스템에서 동작하는 프로그램들은 자신들이 시스템의 모든 메모리를 사용할 수 있다, 아니 그보다 더 많은 메모리를 사용할 수 있다라고 착각을 합니다. 이는 리눅스 시스템이 메모리를 가상화해서 프로그램들에게 보여주기 때문입니다.

문제는 리눅스 시스템은 가상화된 메모리들을 페이지(Page)라는 단위로 쪼개서 관리합니다. 특정 크기를 정해서 페이지단위로 나뉘어 관리를 하는데 이렇게 해야지만이 가상화를 하기에 훨씬 쉽고 운영체제를 제작하는데 손이 덜 간다고 합니다.

그런데 이 페이지는 크기를 가지고 있으며 이를 확인하는 방법은 다음과 같습니다.

단위는 bytes 여서 정확하게 4kb 가 됩니다.

이게 무척이나 중요한 것이 PostgreSQL 데이터베이스 세스템에서 Shared_Buffer 값을 계산할때에 페이지 크기를 알아야 합니다.

공유 메모리(Shared Memory)

리눅스 시스템은 놀랍게도 공유메모리(Shared Memory)를 제공합니다. 이게 정말로 뚱딴지 같은 소리인데 왜냐하면 이 공유 메모리는 프로세스간에 서로 공유하기위해서 메모리이기 때문입니다.

프로세스는 자신만의 메모리를 필요로 합니다. 그것으로 끝입니다. 하나의 프로세스가 다른 프로세스의 메모리에 자료를 가져가면 그건 잘못된 것이고 절대로 그렇게 동작하지도 않습니다. 그런데 프로세스 사이에 자료를 공유하고 싶을때 어떻게 해야 할까요?

이럴때 바로 공유 메모리를 사용합니다. 공유 메모리의 특징은 다음과 같습니다.

  • 공유메모리는 최초로 공유 메모리를 만드는 프로세스에 의해서 만들어 집니다. 이렇게 만들어진 메모리는 커널이 관리해 줍니다.
  • 한번 만들어진 공유 메모리 공간은 직접 삭제를 하거나 리눅스 시스템이 재부팅을 하거나 해야지만 없어집니다. 모든 프로세스가 더 이상 공유 메모리를 사용하지 않는다고 자동 삭제되는 일은 결코 없습니다.

뭔가 대단히 있어보이는 듯한데, 한마디로 정의 하면

프로세스간에 데이터를 공유하고자 할때 사용하는 메모리로 커널에 의해서 관리 되어진다.

입니다. 참 쉽조잉~

그런데, 이 공유 메모리는 아주 많이 사용되어지기 때문에 이 공유메모리 양을 얼마로 해주냐가 리눅스 튜닝의 시작입니다. 실제로 커널 파라메터에 다음과 같은게 있습니다.

많이들 하는 튜닝입니다. 최대 공유 메모리를 얼마나 할 것인가 하는 겁니다.

공유 메모리는 최소(SHMMNI), 최대(SHMAX), 그리고 시스템을 통틀어 모든 공유 메모리 세그먼트의 총합(SHMALL) 로 구분이 되는데 이들의 최대 용량(제한 용량)은 다음과 같이 확인할 수 있습니다.

그런데, 여기서 주의해야 할 것이 있습니다. 커널은 이값을 지정할때에 shmmax 는 ‘bytes’ 단위이고 shmall 은 ‘pages’ 단위 입니다.

위에 보시면 커널에 할당된 shmall 값과 ‘ipcs -lm’ 해서 나온 값이 다릅니다. 이는 단위의 차이로 인한 것으로 커널의 shmall 값은 page 단위이기 때문에 다음과 같이 계산하면 ‘ipcs -lm’가 똑같아 집니다.

SHMMAX 값은 새로운 메모리 영역을 할당할때, 그러니까 shmget() 함수를 호출할때에  사용가능한 최대 메모리 양을 말합니다. 다시 강조하면 shmget()함수를 이용할때입니다. 이는 단일 프로세스가 공유메모리를 호출하기 위한 최대 값이라는 이야기 입니다.

SHMALL 은 시스템을 통틀어 모든 프로세스가 사용 가능한 공유메모리 양입니다.

이게 왜 중요해?

대부분 데이터베이스 시스템을 다룰때에 이 부분이 문제가 됩니다. ORACLE, PosgreSQL의 경우에 바로 이 공유 메모리 설정이 작으면 설치가 진행이 안된다거나 서버가 구동된다하더라도 오류 메시를 내보내고 오류를 내는 경우가 많습니다.

어떻게 설정해야 잘 하는 것일까? 혹은 적절한 값은 무엇인가는 어떤 시스템을 다루느냐에 따라서 달라집니다. PostgreSQL 의 경우에 Shared_buffers 값이 있는데, 이 값은 PostgreSQL에서 데이터를 캐쉬하는데 얼마의 RAM을 사용할 것인지를 지정합니다. PostgreSQL의 경우에 Subprocess 모델 기반으로 각 프로세스별 데이터를 공유하기위해서는 바로 공유메모리가 필요하고 Shared_buffers 는 결국 공유 메모리 입니다. 따라서 운영체제에서 PostgreSQL이 요구하는 Shared_buffers 메모리 값보다 적은 공유 메모리를 설정하면 PostgreSQL이 동작하지 않습니다.

PostgreSQL 의 경우에 Shared_buffers 메모리는 32GB 경우에 8GB 를 Shared_buffers 로 권장하고 있습니다. Shared_buffers 메모리는 공유메모리이고 단일 프로그램이 사용할 것이 때문에 SHMMAX 는 최소 8GB로 해야 합니다.

최대 공유메모리는 32GB-4GB 정도해서 28GB를 SHMALL로 지정해줍니다. 정리를하면

위와같이 지정할 수 있겠습니다.

공유 메모리 사용현황

공유메모리 사용현황은 ‘ipcs -a’ 명령어를 이용해서 확인할 수 있습니다.