2015년 6월 27일 토요일

Sleepy layla



제가 키우는 강아지 입니다.

캐벌리어 킹 찰스 스페니얼 이라는 종으로, 한국에는 잘 없다더군요.

이름은 라일라(layla)에요!

2015년 6월 18일 목요일

infrastructure as code를 Vagrant, VirtualBox, Chef-Solo, Berkshelf를 통해 맛보기

사실 지난번에 Opsworks에 대해서 포스팅은 했지만 저는 infrastructure as code의 전문가가 아닙니다. 포스팅 후 새로운 일이 생겨서 하는 김에 infrastructure as code를 의식해서 일을 진행해보자..해서 진행하게 되었고 알게 된 것들을 공유하고자 합니다. #1이라고 붙였는데 #2를 쓰게 될지 어떨지는 잘 모르겠네요 ㅎ 일단 이번 포스팅에서는 chef코드를 통해서 서버를 구축하는데 까지 써보려고 합니다.

  1. 왜 이런 짓을 하는가
  2. VirtualBox Install
  3. Vagrant Install
  4. Chef Install
  5. 만들자!

1. 왜 이런 짓을 하는가

팀에 다섯명이 개발을 한다. 그런데 개발 환경은 다 다르다. 어떤 때는 깔려 있는 패키지의 버전이 다르고, 어떤 때는 아예 패키지가 없기도 하다. 물론, 개발 환경 구축에 대한 문서는 공유되어 있다. 허나 maintenance를 안하는 동안 이미 유명무실해졌다. 그냥 옆 사람한테 물어보는게 빠르므로. 그래서 개발 환경 구축 따위 그냥 하는거다. 언제까지? 돌아갈때 까지. 
그리고 두 명이 나가고 한 명의 어리버리한 개발자가 새로 들어왔다. 새로 들어온 개발자에게 이미 유명무실해진 구축 문서를 보여주면서 그대로 하라고 한다. 될리가 있나. 왼쪽 사람에게 물어 본다. 계속 물어 본다. 슬슬 짜증낼 것 같으면 오른쪽 사람에게 물어본다. 그렇게, 하루가 간다. 
드디어 개발 중인 어플이 돌아가기 시작했다. 허나 이게 완벽하게 돌아가는지 어떤지는, 아무도 모른다.

이런 풍경은 내가 개발자로 살던 지난 몇년동안 거의 모든 프로젝트에서 벌어졌다. 개발 환경 만드는건, 진짜.. 열라 짜증난다. 진짜 짜증난다. 그래서 infrastructure as code에 흥미를 가지게 되었고, 나같은 이들이 조금이라도 있을꺼란 생각에 글을 남기게 되었다.

(사실, 위와 같은 일이 아직까지도 끊이지 않고 벌어지는 이유는 개발자 본인들의 책임이 크다. 새로운 것을 받아들이려 하기 보단 그냥 하던 대로 하는 걸 하고 싶어 한다. 이러 이렇게 하면 더 나아질 수 있어요! 하면, 귀찮아, 배워야 해, 지금 이대로 해도 어차피 되긴 되잖아, 등등의 말이 돌아오는 일이 많다. 최첨단이라는 이미지가 있는 개발자들은 의외로 보수적이다.)

대충 이런 느낌입니다..(10분간 그렸음)

2. VirtualBox Install

내가 맥을 쓰니 맥 위주로 설명을 하겠다. 윈도우를 쓴 기간이 훨씬 길었는데, 이미 윈도우는 다 잊었다!! 윈도우를 쓰던 시절, 가상머신을 설치하는 건 필수였다. 리눅스 커맨드를 쓰려면 어쩔 수 없었다. 하지만 맥에서는 아니다. 안깔아도 쓸 수 있다. 그래서 나도 안 깔고 썼는데.....
그리고 나의 맥은 개판이 되었다............
brew 커맨드와 npm, gem 커맨드로 이것 저것 그때마다 깔아댔더니 패키지 간의 종속관계며 버전이며 뒤죽박죽이 되었다. 이 상태로 새로운 프로젝트를 만들어 진행하다가 새로운 서버에 릴리스를 해야할 시점이 되면, 나는 고민해야 한다. 내 개발환경의 어느 부분만큼 서버에서 재현해야 할 것인가....
하지만 이제 이런 고민을 할 필요는 없다. code로 인프라를 정의해놓으면 100번이든 만번이든 똑같은 서버를 만들 수가 있다. 고로, 개발 환경도 code로 정의된 인프라에서 만들면 된다! 
그 첫번째 단계가, 가상환경을 만드는 것이다.
서론이 길었는데,
여기 가서 다운 받자. dmg클릭해서 다음다음다음..
커맨드는 나중에 소개. 

3. Vagrant Install

Vagrant는 가상환경 그 자체의 설정을 도와주는 툴이다. 가상환경의 메모리는 얼마를 줄 것인가, ip는 뭘로 할 것인가, os는 어떤 것으로 할 것인가, 등등의 설정을 할 수 있다. 
여기 가서 다운 받자. dmg클릭해서 다음다음다음..

Vagrant는 Vagrantfile이라는 설정 파일에 기술함으로써 서버 설정을 할 수가 있는데, 그 서버를 [2]에서 설치한 virtualbox에 하게 된다. 그런데, 플러그인을 사용하면 AWS의 EC2를 컨트롤할 수도 있다. 무슨 말인고 하니, 맥에다가 VirtualBox깔아서 가상서버를 만들 필요도 없이 EC2의 서버를 가상머신처럼 쓸 수 있다는 소리다.. 이것 말고도 수많은 플러그인이 있는데, 사실 나는 안써봐서 잘 모른다. 나는 그냥 전도만 하겠음.. 신앙심을 키우시는건 본인들의 몫



4. Chef Install

여기서 디벨롭 킷을 다운로드하는 방법도 있는데, 나는 아직 필요성을 못 느꼈으므로 gem으로 인스톨.

 $ gem i chef --no-ri --no-rdoc

Chef를 인스톨하면 knife라는 커맨드를 사용할 수 있게 된다. knife는 chef레포지토리를 조작하는 커맨드이다. 다음으로 knife를 인스톨하자

$ knife configure
이걸 실행하면 ~/.chef/knife.rb에 설정파일이 저장된다. 이것저것 물어보는데 언제나 처럼 모두 디폴트로! 그 다음 knife-solo를 실행한다.
$ gem i knife-solo --no-ri --no-rdoc

소개가 늦었는데, chef에는 chef-server와 chef-solo가 있다.
  • Chef-server: 설정값을 서버에 저장하여, chef-client는 그 설장값을 참조
  • Chef-solo: 설정값을 파일에 저장. 그 파일을 Git으로 관리가 가능. 
위의 기능으로 봤을때, 일반 개발자라면 Chef-solo가 훨씬 쓰기가 편하다. 그 chef-solo를 실행해 주는게 knife-solo가 되겠다.
자, 그럼 준비가 끝났나? 아직 남았다. 잊어선 안된다
Don't repeat yourself
서버에 프로그램을 설치하는 건 정형화되어 있다. 그렇다면? 그렇다. 다른 사람이 만들어놓은걸 가져다 쓰면 된다. Rails에서의 Gemfile 같은...
그것을 가능하게 해주는 것이 Berkshelf이다. 깔자.
$ gem i berkshelf --no-ri --no-rdoc

자. 이제 준비가 끝났다. 만들어 보자!

5. 만들자!

1. Chef레포지토리 만들기

% knife solo init chef-repo
Creating kitchen...
Creating knife.rb in kitchen...
Creating cupboards...
Setting up Berkshelf...

이걸 실행하면
% tree chef-repo
chef-repo
├── Berksfile  #Berkshelf설정파일. rails에서의 Gemfile
├── cookbooks #Berksfile에 설정한cookbook들이 다운로드 되는 디렉토리
├── data_bags #모름
├── environments #잘모름
├── nodes #모름
├── roles #모름
└── site-cookbooks #유저가 직접 작성하는 cookbook
이런 것들이 생긴다. 언제나 처럼, 모두 다 알려고 하지 말자.

2.  Berksfile 설정/실행

% cd chef-repo
% vi Berksfile

하면 site :opscode라고 한줄이 써 있는데, 버전3에서 부터 문법이 바뀌었으므로 지우고 아래와 같은 줄을 추가하자
source 'https://api.berkshelf.com'

cookbook 'nginx'
cookbook 'git'

그런후, rails의 bundle install과 같은 커맨드인 아래의 커맨드를 실행하자. 버전3부터는 bundler로 인스톨도 가능하다고 써있었는데 나는 안해봤다.

% berks vendor cookbooks
Resolving cookbook dependencies...
Fetching cookbook index from https://api.berkshelf.com...
Using build-essential (2.2.3)
Using dmg (2.2.2)
Using chef_handler (1.1.9)
Using git (4.2.2)
Using yum-epel (0.6.0)
Using yum (3.6.1)
Using windows (1.37.0)
.......
이것으로 cookbooks디렉토리에 다운로드 되었다.

3. vagrant 설정

이제 가상서버를 만들자.

% vagrant init
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
% vi Vagrantfile
위의 커맨드로, vagrant 설정파일인 Vagrantfile이라는 파일이 생긴다. 이 파일을 에디터로 열어서, 기본적인 값만 설정해보자.

Vagrant.configure(2) do |config|
    config.vm.box = "ubuntu"
    config.vm.box_url = "http://files.vagrantup.com/precise64.box"
    config.vm.synced_folder "../", "/share"
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.provision :chef_solo do |chef|
    chef.json = {
    }
    chef.run_list = [
      'recipe[nginx]',
      "recipe[git]"
    ]
    end
end

대충 설정값을 보면 감이 올 거라 생각하는데, 이중에서  config.vm.box_url 는 http://www.vagrantbox.es/ 를 참고해서 각자 원하는 os값을 넣도록 하자.


4. 실행

자 이제, 제대로 되었는지 어떤지 실행을 할 시간이다.
우선 서버를 켜고
% vagrant up --provision
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: chef-repo_default_1434619019668_69242
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
...

ssh접속을 해보자
% vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
...
git이 다운로드 되었는지 확인이 되면
vagrant@precise64:~$ git
usage: git [--version] [--exec-path[=]] [--html-path] [--man-path] [--info-path]
           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
           [--git-dir=] [--work-tree=] [--namespace=]
           [-c name=value] [--help]
            []

일단 내가 생각한 흐름대로 진행되었다는 뜻이 된다.
이상! 다음에는 recipe를 통한 서버의 세세한 설정에 대해서 쓰겠습니다! 언제가 될진 모르겠지만....


2015년 6월 8일 월요일

메르카토르 도법에서 위도와 pixel과의 관계

이전에, 메르카토르 도법으로 만들어진 지도를 화면에 표시해 스크롤 하는 프로젝트를 한 적이 있었는데, 경도, 즉 좌우 스크롤은 문제없었으나 위도, 즉 상하 스크롤이 제대로 되지 않았다.
원인은 메르카토르 도법의 특성에 있었다. 사실, 당시 나는 메르카토르 도법이 뭔지도 모르고, 당연히 내가 쓰던 지도가 메르카토르 지도인지 조차 모르고 있었다. 찾아보니, 적도에서 멀어지면 멀어질 수록 지도상의 상하길이가 길어진다는 것을 알았다.

메르카토르 도법 참조

이게 왜 문제가 됐는고..하니..
화면에 표시된 픽셀 하나당 위도, 혹은 경도의 값을 정해서 스크롤된 픽셀만큼 위도와 경도를 재계산해서 지도의 중심값을 계산했는데, 경도의 경우는 픽셀당 경도가 고정값이라 제대로 됐지만, 위도의 경우는 고정값이 아니라서 제대로 되지 않은 것이었다.....

그래서 이것저것 찾아본 결과.. (하루 종일 찾은 것 같다..) 아래와 같은 식으로 해결 할 수 있었다.

double latitudeToPixelY(double latitude) {
    double sinLatitude = Math.sin(latitude * (Math.PI / 180));
    return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
        * 지도의 전체픽셀수);
  }
double pixelYToLatitude(double pixelY, byte zoom) {
    double y = 0.5 - (pixelY / (지도의 전체픽셀수));
    return 90 - 360 * Math.atan(Math.exp(-y * (2 * Math.PI))) / Math.PI;
  }

누군가에게 도움이 되었으면!

2015년 6월 3일 수요일

DevOps를 위한 AWS Opsworks에 대해서.

일단 제가 가진 이력을 잠깐 설명을 해야 하는데, 저는 일본에서 8년정도 소프트웨어 관련 일을 했습니다. 개발도 하고, 입으로 사기치는 컨설턴트 같은 일도 하고, 다시 개발도 하고.... 일본만의 특수한 경우인지는 모르겠지만, 서버관련 직종(인프라)과 소프트웨어 개발 관련 직중이 명확하게 나뉘어져 있는데 저는 소프트웨어 개발 관련이라, 서버는 거의 다루어 본적이 없습니다.(이상 자기 소개끝)
그런 제가 최근에 서비스를 하나 개발했습니다. 일반적인 Ruby On Rails로 만든 서비스입니다. 아무런 생각없이 서버는 AWS로 해야지.. 했었는데 웬걸, 막상하려니 대체 어디부터 손을 대야 할지 난감했었어요. 우선,
EC2 인스턴스를 만들어서 인스턴스안에 서버 깔고, 레일즈 깔고, 깃 깔고, 깔고 깔고, 연결하고...

이건 당연히 나보다 머리 좋은 사람들이 뭔가를 해놓았을 것이다...
라는 귀차니즘에서 오는 추측으로 찾던 중 제 일을 도와주던 동료로 부터 Opsworks에 대해서 듣게 되었고 바로 이거다 라는 생각에 바로 구축하게 되었습니다. 그 경험을 공유했으면 합니다.

1. DevOps

소프트웨어 회사가 어느정도 규모가 있으면, 개발팀, 그리고 운용팀으로 나뉘어 집니다. 저 역시 그런 환경에 있었던지라 운용은 그냥 따분한 일..정도로만 생각하고 있었습니다. 그런데 이게 1인개발 혹은 소규모개발이 되면 바로 내 일이 되게 되는데....
  1. 개발
  2. 소스 푸쉬
  3. 서버 접속
  4. 소스 다운로드
  5. 빌드
  6. 올리기
  7. 제대로 동작하는지 확인하기
  8. 다시 개발
  9. 제대로 동작하는줄 알았는데 뭔가 이상이 있음이 발견됨
  10. 그걸 고침
Welcome to the chaos
하루에 디플로이를 몇번씩이나 해야 하는 상황이 되면 너무 불편하고 무엇보다 서비스의 품질을 보장할 수가 없게 됩니다. 이 상황을 탈피하기 위한 개발 방법으로 제안된 것이 DevOps입니다. 대충 설명드렸는데 조금 다를지도 모르니 검색해 보심을 추천합니다;;

2. AWS에서의 DevOps

DevOps가 뭔지는 알았다. 자 그럼 이제 방법을 보여주시오.. 가 되겠는데, 여러가지 방법이 있다고 합니다.(아주 명쾌한 대답이네요.) 클라우드 컴퓨팅의 선두주자인 AWS에서도 몇가지 방법을 제공하고 있습니다.
  • Elastic Beanstalk
    • Deploy
    • provision
    • monitor
    • Simple
  • Opsworks
    • Elastic Beanstalk와 기능은 같으나 Chef를 통해서 좀 더 세밀한 설정이 가능
  • CodeDeploy
    • Only Deploy
  • CluodFormation
    • Only provision(연계만 해줌,,)
흠, 이중에서 저는 Opsworks를 선택해서 구축했습니다. 고로 다른 것들은 잘 모릅니다...

3. Opsworks의 특징

  • 하나의 단위를 Stack이라고 한다
  • Stack안에 Layer라는 기능 단위가 존재한다. (레이어의 예: ELB, App Server, RDB)
  • EC2 Instance를 늘리거나 줄일 수 있다.
  • GitHub의 레포지토리로부터 Deploy를 할 수 있다.
  • RollBack기능이 있다..
  • 각 레이어간의 연결은 콘솔에서 설정이 가능하다. 예를들어 RDB와App의 연결은 콘솔에서 하므로, 소스를 손댈 필요가 없다. 같은 방법으로 Redis와의 연결도 Chef custom recipe를 통해 가능하다.
이 것 이외에도 기능이 있지만, 제가 써 본 기능은 이것들 입니다.

4. Opsworks의 실제

Opsworks그 자체에 대해서는 검색하면 여러가지 정보가 나오니, 설정하는 방법이라든지, 시작하는 법이라든지 하는 방법은 생략하도록 하겠습니다. 실제로 제가 어떻게 쓰는지를 설명함으로써 이걸 가지고 무얼 할 수 있는지 대충 감을 잡으셨으면 하네요.
  • 개발환경, Production환경을 따로 Stack을 만든다.
  • 개발환경은 Github repository의 master branch를 참조하고, Production환경은 production branch를 참조한다.
  • master로 소스를 개발해 개발환경으로 디플로이한 다음 문제가 없으면 production브랜치에 머지 해서 Production환경을 업데이트 한다.
  • 서버 설정
    • 서버 설정에 있어 기본적인건 Opsworks에서 제공해준다. 예를 들어 nginx와 유니콘의 인스톨이라든지, Rails그 자체의 인스톨이라든지,
    • 그 외의 설정은 Custom Recipe 를 통해서 할 수 있다. Recipe는 Chef 문법에 맞춰서 기술한다. 저도 여기에 빠삭한건 아닙니다. 필요한 설정을 검색해서 붙여 쓰는 정도 입니다.
      • 예를 들어, BasicAuth, 서버의 시간대 설정 등등..
    • infrastructure as code 라는 개념인데, 이것으로 인해서 서버가 항상 깨끗한 상태로 유지된다. 이게 뭔 소린가 하면, 서버에 이것저것 인스톨하고 버전도 제각각이고 한 상태가 되면 서버가 박살나거나 해서 재구축이 필요하게 되었을때 "박살나기 전 상황과 똑같은" 상태로 만드는 게 애매하게 되는데, 이것을 미연에 방지하고, 서버를 늘릴때도 손쉽게 똑같은 서버를 늘릴 수가 있다.
  • 디플로이
    • AWS콘솔 상에서 디플로이 버튼을 클릭함으로써 디플로이를 할 수 있다. 좀 더 스마트한 방법은 아래에서 소개.
SSH로 서버에 들어갈 필요조차 없습니다 여러분!

5. 조금 더 스마트한 방법

아래 같은 시나리오를 생각했다.
  1. Github에 푸쉬
  2. 테스트 코드 실행
  3. 테스트 코드가 OK면 디플로이 실행
  4. 실행 결과를 통지
이걸 가능하게 해주는 서비스가 있는데, werker라는 서비스다. 이 서비스는 GithubRepository(branch)에 푸쉬가 오면 기술된 동작을 실행하고(Rspec등등) 문제가 없으면 Opsworks에 Kick을 해줌으로 해서 위의 시나리오대로 동작을 시켜준다. 실행 결과는 Slack의 Incoming WebHooks로 받을 수 있다.

좀 더 자세하게 쓰면 좋았겠지만, 요즘 세상은 Theory만 알면 검색하면 다 나오는 세상이니 생략했습니다.(사실 좀 귀찮은 것도 있었지만요;;) 대신에 질문 주시면 성심성의껏 대답해 드리겠습니다. 그럼 좋은 하루 되세요.