Docker machine에 대하여

Mac에서 도커를 쓸려면 docker-machine 이라는 녀석을 무조건 써야되는데,
그냥 도커를 돌릴 수 있는 가상머신이라고 생각하니 마음이 편해졌다.
더 알고 싶으면, 밑에 글도 읽어보자.

아래 그림에서 Docker가 돌아가는 Linux VM이 docker-machine이라는 것이드아~

docker-machine
[gfm]
### Docker machine

– 도커 호스트가 설치된 VM이라고 생각하면 됨.
– VM이므로 개발PC, 클라우드, 데이터센터등 아무데나 설치가능
– 클라우드 서비스의 경우는 해당 클라우드의 서비스에 특성에 맞춰주는 driver가 존재함.
– 로컬에 설치하는 경우는 virtualbox, vmware를 지원함.
– 보통 Dooker toolbox로 설치하면 들어있음
– 명령어는 docker-machine 임
– 실제로 docker-machine을 만들고 start를 하면 mac에서는 virtualbox의 VM이 시작됨.

### Docker machine 생성하기
“`
$ docker-machine create –driver virtualbox dev
“`
create 명령으로 생성하는데, driver는 virtualbox가 기본값이고, aws, azure, digital ocean등등이 있다. 왜 이름이 드라이버인지는 아직 모르겠다.

“`
Running pre-create checks…
Creating machine…
(dev) Copying /Users/wapj/.docker/machine/cache/boot2docker.iso to /Users/wapj/.docker/machine/machines/dev/boot2docker.iso…
(dev) Creating VirtualBox VM…
(dev) Creating SSH key…
(dev) Starting the VM…
(dev) Waiting for an IP…
Waiting for machine to be running, this may take a few minutes…
Machine is running, waiting for SSH to be available…
Detecting operating system of created instance…
Detecting the provisioner…
Provisioning with boot2docker…
Copying certs to the local machine directory…
Copying certs to the remote machine…
Setting Docker configuration on the remote daemon…
Checking connection to Docker…
Docker is up and running!
To see how to connect Docker to this machine, run: docker-machine env dev
“`

실행결과를 살펴보면,

– boot2docker.iso를 카피한다음에 VM을 만들고
– ssh키를 만들고
– VM을 기동시키고, 네트웤이 올라오는걸 기다린다.
– 올라오면 boot2docker를 프로비저닝하고
– 인증키를 local -> remote 로 복사하고
– remote(여기서는 VM)에 있는 Docker daemon에 필요한 도커 설정을한다.
– 그뒤에 도커에 잘 접속되는지 체크한다.

docker-machine에 접속하기위한 정보를 보기위해서는

“`
$ docker-machine env dev
“`

를 실행하면 되고, 그 결과는 아래와 같다.

“`
export DOCKER_TLS_VERIFY=”1″
export DOCKER_HOST=”tcp://192.168.99.101:2376″
export DOCKER_CERT_PATH=”/Users/wapj/.docker/machine/machines/dev”
export DOCKER_MACHINE_NAME=”dev”
# Run this command to configure your shell:
# eval $(docker-machine env dev)
“`

도커 호스트의 ip와 포트 인증서의 위치, 도커 머신의 이름등이 나온다.

생성한 도커 머신을 확인하기
“`
$ docker-machine ls
“`

위의 명령어로 확인 하면 된다.

그리고 도커 머신과 정보를 주고받으려면 (이걸 공홈에서는 대화한다고 표현) 해당 도커머신에 대한 환경설정을 해야한다.

“`
$ eval “$(docker-machine env dev)”
$ docker ps
“`

해당 설정을 하지 않으면 도커 머신에 접속할 수 없다는 에러가 뜨게 된다.
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

### 도커 머신에 이미지 실행하기

생성된 도커 머신에 이미지를 다운받고 실행해보자.

“`
$ docker run busybox echo hello world
Unable to find image ‘busybox:latest’ locally
latest: Pulling from library/busybox
583635769552: Pull complete
b175bcb79023: Pull complete
Digest: sha256:c1bc9b4bffe665bf014a305cc6cf3bca0e6effeb69d681d7a208ce741dad58e0
Status: Downloaded newer image for busybox:latest
hello world
“`

로컬에는 해당 이미지가 없기 때문에 docker hub에서 받아오게 (pull)되고, 해당 이미지를 실행한다.
도커머신의 ip를 알기 위해서는 아래와 같은 명령을 실행하면 되는데,
요즘 세상에는 머신의 아이피가 바뀌는건 부지기수로 있는 일이니 머신 이름으로 아이피를 받아오는 방법을 잘 알아놓는 것이 좋을 것이다.

“`
$docker-machine ip dev
192.168.99.101
“`

그럼 이제 nginx이미지를 받아서 실행해보고 잘되는지 확인해보자.
“`
$ docker run -d -p 8000:80 nginx
“`

위의 이미지를 실행하면 nginx를 다운받게 되고, -p 옵션으로 도커 호스트의 8000번 포트로 들어가게 되면, 컨테이너의 80번 포트로 포워딩을 해주게된다.

curl로 확인해보자

“`
$ curl `docker-machine ip dev`:8000



Welcome to nginx!


Welcome to nginx!

If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.

For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.

Thank you for using nginx.



“`

도커 머신은 말그대로 VM이므로 여러개 생성이 가능하다.

아래의 기본적인 명령어는 일단 숙지를 하고 다니자.

“`
$ docker-machine create –driver virtualbox [이름]
$ docker-machine ls #리스트 보기
$ docker-machine stop [이름] # 정지시키기
$ docker-machine start [이름] # 시작하기
$ docker-machine rm [이름] # 삭제하기
“`
[/gfm]

도커 아키텍쳐

서버의 소스를 배포하려고 하는 중인데, 내가 알고 있는 방식은 파일을 동기화 시키는 방식이었다. docker를 사용하면, 여러개의 파일을 동기화 안하고 그냥 이미지로 구워서 할 수 있는 것 같아서, 소스 배포할 때 편할것 같은 느낌이 들었기 때문에 조사해보기로 했다. 아무래도 잘 모르는 기술을 잘 파악하기 위해서는 아키텍쳐를 알면 좋기 때문에 시간을 내서 아래의 페이지를 요약 번역 해보았다.

https://docs.docker.com/engine/introduction/understanding-docker/

마음대로 번역한거라 혹시 틀린내용이 있을 수 있는데,  잘못된 것을 발견하게 되면 바로 수정하겠음.

Why docker?

공홈에 보면 주저리주저리 많은데 내가 이해한 바는 아래 3가지이다.

  • 어플리케이션의 빠른 배포
    • 리눅스이기만 하다면 서버환경에 의존성이 없음
    • 우분투에서 센트OS환경의 이미지를 돌릴 수 있음. 당연히 반대로도 가능
  • 배포와 스케일아웃을 쉽게 해줌
  • 머신의 성능을 최대치 까지 뽑아낼 수 있음. (고밀도 -> 고성능)

도커의 아키텍쳐는 어째 되나?

도커는 클라이언트-서버 아키텍쳐를 사용한다.
클라이언트와 서버는 호스트 머신에 설치된 Docker daemon으로 빌드와 실행, 배포등을 할 수 있도록 통신한다.

docker architecture

 

도커 데몬

도커 데몬은 호스트 머신에서 실행되고, 유저는 Docker client를 통해서 데몬과 상호작용한다.

도커 클라이언트

도커 데몬에 명령을 내릴 수 있도록 만든 도커의 주된 유저 인터페이스이다.

도커 인사이드

내부를 이해하려면 다음의 3가지 Docker Images, Docker registries, Docker containers 를 알아야한다.

Docker images

도커 이미지는 읽기전용 템플릿이다. 예를들면, 우분투에 아파치 웹서버를 설치한 것을 하나의 이미지라고 볼 수 있다.
도커 이미지는 도커 컨테이너를 만드는데 사용되고, 도커는 새로운 이미지를 빌드할 수 있는 심플한 방법을 제공한다. 혹은 다른 사람이 만든것을 다운받을 수도 있다. 이미지는 도커의 빌드 컴포넌트이다.

Docker registries

도커 레지스트리는 이미지들을 보관하는 곳이다. 이미지를 업로드/다운로드 할 수 있는 공개 저장소와 사설 저장소가 있다. 공개 저장소는 Docker hub에서 제공되고 있다.
도커 레지스트리는 도커의 배포 컴포넌트이다.

Docker containers

도커 컨테이너는 디렉토리와 비슷하다. 도커 컨테이너는 어플리케이션을 실행하기 위한 모든것을 가지고 있다. 각각의 컨테이너는 하나의 도커 이미지로 만들어 진다.
도커 컨테이너는 실행될수 있고, 시작 시킬 수 있고, 중지 시킬 수 있고, 이동 시킬 수 있고, 삭제 할 수 있다. 각각의 컨테이너는 고립되어 있어며 안전한 어플리케이션 플랫폼이다.
도커 컨테이너는 도커의 실행 컴포넌트이다.

그래서 도커는 어떻게 동작하나?

  1. 어플리케이션을 담기 위해 도커이미지를 빌드 할 수 있다.
  2. 도커 이미지로 부터 어플리케이션을 실행하기 위한 도커 컨테이너를 만들수 있다.
  3. 도커 이미지는 공개/사설 저장소에 공유할 수 있다.

도커 이미지는 어떻게 동작하나?

도커 이미지는 읽기전용 템플릿이고, 이것으로 부터 도커 컨테이너들을 작동시키는 것은 위에서 알게되었다.
각각의 이미지는 연속된 레이어들로 구성되어 있다. 도커는 union file systems를 사용해서 레이어들을 하나의 이미지로 합친다.
Union file systems는 분리되어 있는 여러 파일시스템을 투명하게 덮어서 하나의 파일 시스템 형태로 만들어준다.
여러개의 레이어가 있다는 것은 도커가 가벼운 이유 중 하나이다.
예를 들어서 어플리케이션을 새로운 버전으로 변경하기 위해 도커의 이미지를 다시 빌드한다고 해보자.
그런경우에 이미지 전체를 새로 빌드하는 것이 아니라, 새로 추가된 부분 또는 업데이트 된 부분만 변경하면 된다.
그리고 배포할 경우에도 변경된 부분만 배포하면 되기 때문에 도커 이미지는 더 빠르고 더 심플하다.
모든 이미지는 우분투나 페도라 같은 베이스 이미지로 부터 시작된다. 그리고 베이스 이미지는 보통 Docker hub에서 가져오게된다.
도커 이미지는 베이스 이미지에서 인스트럭션 셋을 작성하여 만들어지게 되는데, 각각의 인스트럭션은 이미지의 새로운 레이어를 생성하게 된다.
인스트럭션은 다음과 같은 액션들을 포함한다.

  • Run 커맨드
  • 파일또는 디렉토리의 추가
  • 환경변수 설정
  • 이미지에서 컨테이너를 런칭할때 어떤 프로세스가 실행되는지

도커 레지스트리는 어떻게 동작하나?

도커 레지스트리는 도커 이미지들을 위한 스토어이다. Docker hub 같은 퍼블릭 레지스트리를 사용하거나, 자체구축을 해서 사용해도 된다.
도커클라이언트로 업로드한 이미지들을 검색할 수 있고, 땡겨 받을 수도 있다.
Docker hub에도 사설 스토리지 서비스를 해주는데, 1개는 무료이지만 그 이상은 비용이 든다. 자세한건 https://hub.docker.com/plans 링크 참고

컨테이너는 어떻게 동작하나?

컨테이너는 운영체제, 유저가 추가한 파일들 그리고 메타데이터로 구성되어 있다. 이미 봤지만, 각각의 컨테이너는 이미지로 부터 빌드된다.
이미지는 컨테이너가 올라가려면, 어떤 프로세스를 실행해야하는지 그에 따른 이런 저런 설정파일을 컨테이너에 알려준다.
컨테이너가 이미지로 부터 실행이 되어서 올라갈 때에, 이미지의 최상단에 읽기-쓰기가 되는 레이어를 더하게 된다.

당신이 컨테이너를 실행할때 무슨일이 일어나나?

docker 바이너리를 사용하건 API를 사용하건 Docker 클라이언트는 Docker 데몬에게 컨테이너를 실행시키라고 요청을 보낸다.

$ docker run -i -t ubuntu /bin/bash

위의 커맨드를 한번 쪼개보자.
docker 커맨드로 도커 바이너리를 실행시키고, 새로운 컨테이너를 올리기위해 run 서브커맨드를 사용한다. 도커 클라이언트가 도커 데몬에게 요청을 보내기위한 최소한의 내용은 다음과 같다.

  • 컨테이너로 빌드할 도커 이미지가 무엇인가, 여기서는 ubuntu 베이스 이미지이다.
  • 컨테이너가 올라간 후 실행하고 싶은 커맨드는 무엇인가, 여기서는 /bin/bash 라는 명령어를 사용한다.

그러면 위의 명령어가 실행되면 어떤 일이 일어날까?

  • ubuntu 이미지를 밀어올린다.(Pull)
  • 새로운 컨테이너를 만든다.
  • 읽기-쓰기레이어에 파일 시스템을 할당하고 마운트한다.
  • 네트웍과 브릿지 인터페이스를 할당한다
  • 아이피를 세팅한다.
  • 당신이 지정한 프로세스를 실행한다.
  • 어플리케이션의 로그를 캡쳐한다.

도커를 지탱하는 기술(Underlying technology)

도커는 Go 언어를 사용하여 작성되었고, 몇가지 커널의 기능을 사용했다.

Namespaces

도커는 namespaces라는 워크스페이스(우리가 컨테이너라고 부르는) 격리화 기술의 이점을 차용했다. 컨테이너를 실행하게 되면, 도커는 해당컨테이너를 위한 namespaces의 셋을 생성한다.
Namespaces는 레이어의 격리를 제공한다 : 각각의 컨테이너는 그들 자신의 namespace를 가지게 되고 외부로는 접속할 수 없다.
리눅스에서 도커가 사용하는 몇가지 namespaces는 아래와 같다.

  • pid namespace : 프로세스 격리에 사용
  • net namespace : 네트워크인터페이스 관리에 사용
  • ipc namespace : IPC리소스 접근에 대한 관리에 사용 (IPC : InterProcess Communication)
  • mnt namespace : 마운트포인트의 관리에 사용
  • uts namespace : 커널격리와 버전 인식에 사용 (UTS : Unix Timesharing System)

Control groups

도커는 cgroup 또는 control groups라는 리눅스의 또다른 기술을 사용한다.
컨트롤 그룹은 도커가 CPU, 메모리, 디스크 같은 하드웨어리소스를 쉐어 할 수 있게 제어한다.

Union file systems

Union file systems또는 UnionFS라고도 하는 파일시스템은 레이어를 생성하는데 사용되고, 매우 가볍고 빠르다. 도커는 컨테이너를 위한 빌딩 블록을 제공하는데에 union file systems를 사용한다. 도커는 AUFS, btrfs, vfs, DeviceMapper 같은 Union file systems를 사용할 수 있다.

Container format

도커는 이러한 컴포넌트들을 조합하여 감싸는데 이걸 컨테이너 포맷이라고 한다. 디폴트 컨테이너 포맷은 libcontainer라고 부른다.
또한 도커는 LXC라는 전통적인 리눅스 컨테이너도 지원한다.
추후에는 BSD Jails또는 Solaris Zones를 통합해서 다른 컨테이너 포맷도 지원할 예정이다.

[알고리즘] 소수 구하기

요즘 코딩 감각이 좀 둔해진 것 같아서, 다시 프로젝트 오일러 정주행중인데, 예전에 처음 풀었을 때에는 그냥 뺑뺑이 돌려서 소수를 구했었다.

이번에는 두번째 하는거라서 자료를 조금 찾아보기도 하고, 나름 생각해서 이렇게 하면 빠르겠다
싶은 것도 만들어보기도 하였다…

결과적으로는 수학을 이용한 것이 제일 빨랐다..

첫번째 메서드 실행결과

elapsed time : 0:03:00.578463
method1 DONE!

두번째 메서드 실행결과

elapsed time : 0:00:00.272193
method2 DONE!

세번째 메서드 실행결과

elapsed time :  0:00:00.305218
method3 DONE!

아래는 작성해본 코드이다.

[gfm]
“`
from datetime import datetime

def timer(method):
def timed(*args, **kwargs):
start = datetime.now()
result = method(*args, **kwargs)
end = datetime.now()

print (“elapsed time : “, end – start)
return result

return timed

### 정의대로 만든거
def isPrime(x):
if x == 1:
return False
else:
for num in list(range(2,x)):
if x % num == 0:
return False
return True

### 약간의 수학을 이용
### x 가 a와 b의 곱으로 이루어진다면 a와 b의 최대값은 x**0.5 보다 작거나 같아야 한다. 는 원리를 이용
def isPrime2(x):
if x == 2 or x == 3: return True
if x%2 == 0 or x < 2 : return False for i in range(3, int(x**0.5) + 1, 2): if x%i == 0: return False return True ### 인터넷에서 본거 def isPrime3(n): if n < 2: return False if n % 2 == 0: return n == 2 k = 3 while k * k <= n: if n % k == 0: return False k += 2 return True @timer def execute1(size=1000): prime_list = [] for x in list(range(2, size)): if isPrime(x): prime_list.append(x) print("method1 DONE!") print(prime_list) @timer def execute2(size=1000): prime_list = [] for x in list(range(2, size)): if isPrime2(x): prime_list.append(x) print("method2 DONE!") print(prime_list) @timer def execute3(size=1000): prime_list = [] for x in list(range(2, size)): if isPrime3(x): prime_list.append(x) print("method3 DONE!") print(prime_list) if __name__ == '__main__': num = 100000 execute1(num) execute2(num) execute3(num) pass ``` [/gfm]

파이썬 실행환경 설정하기 with pyenv

[markdown]
virtualenv를 사용하는 법을 올렸었는데, pyenv라는 녀석을 추천해주셔서 실제로 설치해보고 경험해보려고 정리해보았다.

####아래의 링크들을 참고하여 작성했음을 밝혀드립니다.
[pyenv](https://github.com/yyuu/pyenv)
[pyenv-virtualenv](https://github.com/yyuu/pyenv-virtualenv)
[pyenv-installer](https://github.com/yyuu/pyenv-installer)
[pyenv + virtualenv + autoenv 를 통한 Python 개발 환경 구축하기](https://blog.ansuchan.com/how-to-set-python-dev-env/)

### pyenv 설치하기 ( mac OSX )

#### 의존성 패키지 설치

[일반적인 빌드 문제들](https://github.com/yyuu/pyenv/wiki/Common-build-problems)에 나와있는데, mac OSX에 미리 설치해야하는 의존성 패키지가 있으니 한번 확인해보도록 하자.

#### 설치 스크립트
“`python
brew update
brew install pyenv
“`

### pyenv 설치하기 ( ubuntu )

#### 의존성 패키지 설치
우분투에서 미리 설치해두어야하는 패키지들은 아래와 같다.

“`
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm
“`

#### 설치 하기 (pyenv installer로 설치함)
“`
sudo apt-get install git
curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
“`

pyenv installer 라는 녀석으로 설치하는 게 위의 스크립트 인데, 아래의 플러그인들도 같이 설치된다.

pyenv-doctor, pyenv-pip-rehash, pyenv-update, pyenv-virtualenv, pyenv-which-ext

설치후에 아래의 스크립트를 .profile에 추가해서 pyenv를 패스에 추가해줘야한다.

“`
export PATH=”$HOME/.pyenv/bin:$PATH”
eval “$(pyenv init -)”
eval “$(pyenv virtualenv-init -)”
“`

### pyenv로 파이썬 설치하기

“`
pyenv install 2.7.8
pyenv install 3.4.3
“`

설치가 가능한 파이썬 바이너리는 아래의 커맨드로 확인가능하다

“`
pyenv install –list
“`

### pyenv로 virtualenv 관리하기

pyenv로 파이썬을 설치하면 `.pyenv/versions` 디렉토리 밑에 버젼별로 2.7.x, 3.4.x등의 디렉토리가 생긴다. 버전번호가 아니라 virtualenv 플러그인을 사용하면 버젼을 지정하고 거기에 이름을 넣어서 관리가 가능하다. pyenv installer로 설치를 하면 자동으로 pyenv-virtualenv 플러그인이 설치되므로 추가로 설치는 하지 않아도 된다.

솔직히 virtualenv 플러그인은 왜 필요한지 처음에는 의아했는데, 생각해보니 2가지 정도가 있었다.

1. 같은 파이썬 버젼이지만, 패키지를 다르게 설치하고 싶은경우.
2. virtualenv를 활성화하면 쉘의 앞머리에 가상환경 명이 나와서 편하니까

약간 귀찮다고 생각될 수도 있지만, pyenv installer로 설치하면 한방에 설치되니 최소한 설치는 매우 편하게 되어있다. pyenv의 서브명령어로 pyenv virtualenv 를 사용가능하게 한다는것 정도만 알면되니 사용하는게 이득으로 생각된다.

맥의 경우

“`
$ brew install pyenv-virtualenv
“`
로 따로 설치할 수 있다.

virtualenv플러그인이 있으면 아래의 커맨드가 실행이 가능하다.

“`
$ pyenv virtualenv
“`

버젼을 지정하지 않으면 현재 시스템의 버젼으로 가상환경이 설정된다.
“`
$ pyenv version #으로 현재 버젼의 확인이 가능하다
$ pyenv virtualenv py34
“`

버젼을 지정해서 가상환경의 설정이 가능하다. (설치하려는 해당 파이썬 버젼은 pyenv의 디폴트 디렉토리에 이미 설치가 된 상황이어야 한다.)

“`
$ pyenv install 2.7.3 # 설치 안한 경우만 실행
$ pyenv virtualenv 2.7.3 py27
“`

#### 가상 환경 활성화

`pyenv versions`를 했을때에 리스트에 나오는 가상환경들을 `pyenv shell`이라는 명령어로 활성화 시킬 수 있다.

“`
$ pyenv versions
위의 명령을 실행했을 때 결과가 아래와 같다면

* system (set by PYENV_VERSION environment variable)
2.7.3
2.7.8
3.4.3
py27
py34
versions

$ pyenv shell 2.7.3
$ pyenv shell py34
“`
등의 커맨드로 활성화 시킬 수 있다.

virtualenv플러그인으로 만든 가상환경인 경우 `activate`, `deactivate`로 활성화 비활성화 할 수 있다. 위의 리스트에서는 `py27`과 `py34`가 virtualenv 플러그인으로 만든 가상환경이다.

“`
$ pyenv activate py27
$ pyenv deactviate
$ pyenv activate py34
“`

이런식으로 가능하다.

`autoenv`라는 것을 사용하면 폴더별로 들어갈 때 가상환경을 지정할 수도 있다고 한다.

#### 느낀점
확실히 추천들을 하실만한 것 같다. rbenv, nvm, rvm등등을 경험해보았는데, 비슷한 느낌으로 pyenv를 사용할 수 있었다. virtualenv는 파이썬 버젼을 업데이트할 경우 pyenv보다는 조금 더 귀찮은 작업들이 있는데, pyenv에서는 그냥 install하고 기존의 패키지만 다시 설치하면 되니 확실히 간편하게 될 것 같다. 그리고 명령어 자체도 virtualenv나 virtualenvwrapper보다는 사용하기 편한 느낌이다. 일단 타이핑하는거 자체도 좀 짧기도 하고…^^;
[/markdown]

파이썬 가상 환경 설정 및 장고 설치하기

[markdown]
갑자기 회사의 동료가 나에게 장고스터디를 해달라고 했다. 마침 장고를 보고있었던 나는 쥐뿔도 모르지만, 이제부터 준비하려고 장고를 열심히 보고 있다.  근데, 나쁜버릇이 나와서 설치부터 잘하고 싶은 마음이 드는 것이다.

남들은 그냥 `sudo pip install django` 이렇게 하고 넘어갔을 것을 괜시리 깔끔떨며 가상환경이라는 것을 만들어보기로 한다. 그럼 같이 한삽을 같이 퍼보도록 하자.

아래에서 실행한 스크립트들은 **virtualbox에 새로 설치한 ubuntu14.04 LTS**에서 아주 깔끔한 상태로 실행한 것들이다.  다른 Linux에서는 설치하는게 비슷하거나 약간 다를것이고, windows에서는 아~~주 많이 다를것이다. 그러므로 그점을 인지하고 보도록 하자.

사실 OSX는 예전에 정리해놓은 글이 있다. 똑같은걸 두번이나..적다니..ㅠㅠ

[맥에서 쟝고개발환경 만들기](http://gyus.me/?p=240)

###우분투에서 python3 설치
`sudo apt-get install python3-all`

###pip 설치
`sudo apt-get install python-pip `

###virtualenv 설치
virtualenv를 설치하는 이유는 여러가지가 있지만, 내가 아는 바로는 아래 4가지다.

– 파이썬 패키지를 설치할 때 관리자 권한이 아니라 유저 권한으로 설치 하고 싶음.
– 파이썬의 실행 환경을 리눅스의 것과 온전히 구분해서 서버를 깔끔하게 하고 싶음.
– python3을 실행할 때 그냥 python으로 실행하고 싶음.
– 개발환경과 실서버환경을 동일하게 맞추고 싶음.

그럼 설치해보자. (간단간단)

`sudo pip install virtualenv`

###virtualenvwrapper 설치
뭘 이런 헷갈리는걸 또 설치하냐고 물어볼 사람이 있을 것 같은데(나도 그랬음), 그냥 세트라고 생각하고 설치하는게 좋다. virtualenv를 훨씬 사용하기 간편하게 해준다.

`sudo pip install virtualenvwrapper`

###virtualenv 환경 설정
1. 디폴트 디렉토리 만들기 .virtualenv
mkdir ~/.virtualenvs
2. WORKON_HOME 환경 변수에 디폴트 디렉토리 등록하기
export WORKON_HOME=~/.virtualenvs
3. .profile(우분투 기준 유저 로그인시 실행되는 스크립트) 에 virtualenvwrapper를 임포트 하도록
위 파일의 가장 하단에 아래 스크립트 추가

`. /usr/local/bin/virtualenvwrapper.sh`
혹은
`source /usr/local/bin/virtualenvwrapper.sh`

###가상환경 만들어보기

위의 과정을 잘 따라했다면 `virtualenvwrapper.sh` 내에 있는 함수인 `mkvirtualenv` 함수를 사용할 수 있다.

`mkvirtualenv {{가상환경-이름}}`
요렇게 사용한다

`mkvirtualenv py2`

요렇게하면 py2라는 이름의 가상환경이 설치되고 그 가상환경을 사용할 수 있게(workon) 된다.

`which python`
명령어를 실행했을 때 아래와 같은 경로로 나오면 제대로 된것이다.
`/home/user_name/.virtualenvs/py2/bin/python`

가상환경에서 나가려면
`$ deactivate`
와 같이 실행한다

다시 들어가려면
`$ workon py2`
라고 하면된다.

###그럼 python3의 가상환경을 만들고 싶으면?

`virtualenv`가 인식하는 환경변수중에 `VIRTUALENV_PYTHON` 이라는 환경변수가 있는데, 저 변수에 `python3`의 경로를 넣어 주면 된다.

이렇게 해보자.
“`
export VIRTUALENV_PYTHON=`which python3`
mkvirtualenv py3
“`

이렇게 하면 환경변수 안쓰고도 된다!(이진석님 감사합니다.)
“`
mkvirtualenv py3 –python=`which python3`
“`
물론 위의 `which python3`이 제대로 되려면 `python3`이 설치가 되어있어야 한다.
(`sudo apt-get install python3-all`을 위에서 실행한 이유가 그것 때문)

이렇게 하면 파이썬3의 환경으로 가상환경이 만들어졌다.
파이썬 버젼을 확인해보자.
`(py3) ~ $ python -V `
`Python 3.4.0`

요런식으로 나오면 성공~!
긜고 pip3도 pip 로 실행된다.

####아..이제 환경설정이 됐으니 장고를 설치할 수 있다…;;;

### 장고설치
쟝고의 설치는 허무하게도 아래의 한줄

`pip install django`

장고 설치끝~
[/markdown]

[짧은 글]unity-googledrive 플러그인

웹개발 및 서버개발만 하다가 생각에도 없던 유니티를 건들게 되었다.  내가 맡은 부분은 google drive에서 파일을 업로드/다운로드 하는걸 맡았는데, 아래 플러그인으로 하면 간단히(?) 해결된다.
게다가 만드신 분이 한국사람이라 모르면 한국어로 질문해도 됨.
답변이 어마어마하게 빨리달린다. 마지막 커밋이 2년전이긴 하지만, 유지보수는 꾸준히 하고 계신듯.
다만 문서가 영어로 되어있고, 테스트할 때 장벽이 google developer console이라는 장벽이 있는데,  그 부분은 정리가 안되어 있어서, 짧게나마 내가 한 삽질을 정리해서 올림.
유니티 google drive 플러그인
테스트하기
1. Google Developers Console에 어플리케이션을 등록한다.

2. 해당 계정의 데이터에 대한 접근 권한 요청을 보낸다.
  OAuth2.0의 웹 어플리케이션용 클라이언트 ID를 하나 만든다.
URI 리다이렉션에는 http://localhost:9271 를 입력한다.
자바스크립트 시작위치는 디폴트값 그대로 둬도 상관 없음.
3. DriveTest.cs의 아래 코드의 부분에 클라이언트 ID와 보안 비밀을 집어 넣는다.
IEnumerator InitGoogleDrive()
  {
    initInProgress = true;
    drive = new GoogleDrive();
    drive.ClientID = “클라이언트 ID”;
    drive.ClientSecret = “클라이언트 보안 비빌”;
    // 이하 생략
}
4. 유니티에서 DriveTest 씬을 실행해본다.
끝~

리모트 – 사무실 따윈 필요없어!

book_cover_remote 간만에 여유가 좀 생겨서 책도 읽고 하면서 충전중인데, 개발자로서의 삶중에 정말 그랬으면 좋겠다는 소망은 원격근무를 하는거였다. 어느 정도였냐면, 원격근무를 할 수 있다면 내 월급의 10%를 깎아도 기꺼이 하겠다는 마음이 있었었다.

그러던 중에 외국에서는 ruby on rails로 유명한 DHH가 있는 37signals에서 remote라는 책이 나왔고, 우리나라에서도 유명하신 몇몇 분들이 읽었다는 것을 본적이 있는것 같다.

바빠서 그냥 언젠가는 읽어봐야지 하는중에, 한국어 판이 나왔다. ‘임정민’ 이라는 고마우신 분이 매끄럽게 번역을 해주셔서 금방 읽은것 같다. 책 내용 자체는 리모트(원격근무)를 자기네 회사에서는 어떻게 하고 있는지, 원격근무를 하지 않고 있는 회사에서는 어떻게 원격근무를 적용하면 되는지에 대한 내용들이 적혀있다.

예전에는 인프라가 받쳐주지 못해서 원격근무를 할수가 없었다면, 지금은 원격근무를 위한 인프라가 모두 갖춰져 있는데, 안할 이유가 없다는 얘기는 참 동의가 된다. 그리고 기업입장에서도 오피스를 마련하는데 드는비용을 줄일 수 있으며, 개인은 회사에 출근하고 퇴근하는 시간과 노력을 아낄 수 있으니 결과적으로 회사의 생산성이 올라간다는 내용이었다.

뭔가 엄청나게 충격을 주는 내용의 책은 아니었지만, 원격근무를 생각하고 있는 회사가 있다면, 이 책을 참고하면 우려되는 상황은 거의 다 적어져 있기때문에 원격근무를 잘 도입만 하면 되는 거 아닐까 라는 생각을 하게했다.

사실 힘 없는 사원입장에서는 읽어봐야 큰 감흥이 없다..ㅋㅋ
최소한 임원급은 되어야 읽었을 때 회사에 어떻게 적용할지 생각을 하면서 본다고 해야할까… 원격근무도입을 위한 실용서에 가깝기에 나는 그냥 그렇구나~~ 하면서 편하게 보고 금방읽었다.

boto의 profile_name 설정으로 여러개의 Credential 사용하기

[markdown]
# boto의 profile_name 설정으로 여러개의 Credential 사용하기

### 주의
AWS_CREDENTIAL_FILE 이 환경변수로 있는 경우에는 자동으로 해당 파일을 `boto`에서 인식하므로 여러개의 credential 설정을 사용할 수 없다. 이 경우에는 해당 설정을 삭제해야한다.

`boto`의 환경설정 파일로 인식되는 경로로 아래의 3가지가 있다.

* /etc/.boto : 모든 유저가 공유하는 세팅
* ~/.boto : 각 유저별 세팅
* ~/.aws/credentials : aws SDK와 공유하는 설정

우리가 만저볼 것은 `~/.boto` 파일로 각 유저별롤 세팅가능한 설정인데 profile 을 설정함으로서 여러개의 credential을 사용할 수 있다.

“`text
[Credentials]
aws_access_key_id = access_key_id1
aws_secret_access_key = secret_access_key1

[profile test]
aws_access_key_id = access_key_id2
aws_secret_access_key = secret_access_key2
“`

아래는 테스트 코드이다. `.boto` 파일에 설정한 내용에 따라 다른 AWS계정의 credential을 사용하게 될 것이다.

“`python
import boto.ec2

# 기본 Credentials 로 되어 있는 설정을 사용
conn = boto.ec2.connect_to_region(‘ap-northeast-1’)
conn.get_all_addresses()

# test 라고 되어 있는 설정을 사용
conn = boto.ec2.connect_to_region(‘ap-northeast-1′, profile_name=’test’)
conn.get_all_addresses()
“`
[/markdown]

AWS RDS의 타임존 변경하기

[markdown]

최근까지 N모사의 클라우드 서비스를 사용하다가, 혼자서 서버를 관리해야하는 부담 때문에 AWS로 넘어왔다. 그러면서 기존에 구상해 두었던, 서버 아키텍쳐를 AWS로 다 옮기는 중에 있는데, 그중에 하나는 Mysql-cluster를 RDS로 옮기기로 한 결정이었다. 그래서 RDS 인스턴스를 만들어보고 테스트 중에 있는데, 아니 타임존이 UTC로 되어 있어서 시간이 내가 의도한대로 나오지 않는 것이었다!

이걸 고치는 법을 아마존에서 공식적으로 지원하지는 않는 것으로 보이고(오라클은 최근에 지원이 되기 시작했다!) 뭔가 다른 방법으로 해야될 것 같아서 찾아보니 DB프로시져를 이용하는 방법이 있었다.

간단히 단계를 살펴보자면 아래와 같다.

1. 스토어드 프로시져의 작성
2. Parameter Group의 작성
3. RDS에 Parameter Group을 적용
4. RDS 인스턴스 재시작

이 작업을 하면서 주의해야될게 하나 있는데 `rdsadmin` 이라는 유저는 AWS쪽에서 DB인스턴스 관리용으로 사용되는 녀석으로 타임존을 건드리면 이상하게 동작할 것 같으니 이녀석의 타임존은 안건드려야 한다는 것이다.

이제 스토어드 프로시져부터 만들어보자

### 1. 스토어드 프로시져 만들기

프로시져 명을 `mysql.store_time_zone`이라고 했는데, `mysql`에는 실제로 사용할 DB의 이름을 넣도록 하자. 귀찮으면 그냥 둬도 상관은 없다.

“`sql
DELIMITER |
CREATE PROCEDURE mysql.`store_time_zone`()
IF NOT (POSITION(‘rdsadmin@’ IN CURRENT_USER()) = 1) THEN
SET SESSION time_zone = ‘Asia/Seoul’;
END IF |

DELIMITER ;
“`

### 2. Parameter Group 만들기

RDS에서는 MySQL의 파라메터를 `Parameter Group`으로 그룹단위로 관리하고 있다. mysql의 세션이 최초 접속시에 위에서 만들어둔 프로시져를 실행하도록 `init_connect`파라메터를 설정하기 위한 `Parameter Group`을 만들자.

RDS의 Parameter Groups에 들어가서 `Create DB Parameter Group`을 클릭한다.

![그림1](http://gyus.me/wp-content/uploads/2014/10/1-1-1.png)

`Yes, Create`를 클릭!

![그림2](http://gyus.me/wp-content/uploads/2014/10/2-1-1.png)

store-time-zone을 선택후 `Edit Parameters`를 클릭하자.

엄청 많은 파라메터들이 있는데 `init_connect` 파라메터를 찾아서 아래의 `CALL` 명령어를 입력하자

“`sql
CALL mysql.store_time_zone
“`

![그림3](http://gyus.me/wp-content/uploads/2014/10/31-1-1.png)

설정이 끝났으면 위로 올라와서 `Save Changes`를 클릭해서 설정을 저장한다.

![그림4](http://gyus.me/wp-content/uploads/2014/10/4-1-1.png)

### 3. RDS에 파라메터 그룹을 설정하기

![그림5](http://gyus.me/wp-content/uploads/2014/10/5-1-1.png)

RDS instance메뉴로 가서 DB Instance를 선택한다음 마우스 오론쪽을 클릭해서 `Modify` 메뉴로 들어가자.

`Parameter Group`을 위에서 작성한 그룹으로 변경하고 `Apply Immediately`를 체크하고 변경하자.
![그림6](http://gyus.me/wp-content/uploads/2014/10/6-1-1.png)

### 4. DB인스턴스의 재시작

적용후 DB인스턴스를 재시작해주면 된다.

잘 적용 되었는지 DB에 접속해서 확인을 해보자. 아래와 같이 쿼리를 날리면 아마 바뀌어진 타임존으로 시간이 나올 것이다.

적용전/적용후를 알 수가 없지만, 이 글을 포스팅한 시간이 2014년 10월 10일 오후 5시 50분경이니 잘나오는거라고 보시면 된다. ^^;

“`sql
mysql > select now();
“`

![그림7](http://gyus.me/wp-content/uploads/2014/10/7-1-1.png)

### Tip 커맨드라인으로 변경하기
** ※ `AWS RDS API`는 사용가능 한 상태임을 가정한다. **

앞서 본것 처럼 웹콘솔에 들어가서 작업을 해도 되지만, API로 하는 방법도 있다.
단계는 동일한데 단순히 API를 쓴다는 것만 다르다.

– 프로시져를 만든다.
– 파라메터 그룹을 만든다.
– RDB인스턴스의 파라메터 그룹 설정을 변경한다.
– RDB인스턴스 재시작

`프로시져는 위에서 만들어 봤으므로 생략하겠다`

#### 파라메터 그룹 만들기

아래의 커맨드로 그룹을 쉽게 만들 수 있다.

“`shell
$ rds-create-db-parameter-group store-time-zone –db-parameter-group-family mysql5.6 –description “change time zone” –region “ap-northeast-1”
“`

#### 파라메터 그룹 설정 적용하기

아래의 커맨드로 만든 그룹에 대한 설정을 하고 적용을 바로 할 수 있다.

“`shell
$ rds-modify-db-parameter-group PARAMGROUP –parameters “name=init_connect, value=’CALL mysql.store_time_zone’, method=immediate”
“`

#### 재시작도 해보자

**※ rdb 인스턴스 명을 알고 있어야 한다.**

“`shell
$ rds-reboot-db-instance {rdb instance 명}
“`

[/markdown]

NCloud에서 AWS로 이전하면서 한 삽질

[markdown]
###왜 변경하나
– 더 기능이 많고 더 싸다
– 오토스케일링 가능
– SSD가 기본 장착이라 IO가 좀 더 많이 나온다
– 돈계산도 복잡하다. 그렇지만, NCloud보다 약간! 싸다

###아쉬운점은
– 고정아이피 할당이 복잡하다
– 속도가 국내 IDC에 비해서는 확실히 느리다
– SSD가 기본 장착이라 용량이 적다
– 기능이 많아서 공부를 많이 해야한다.

###변경되는 점
– 패스워드 & 공용키로 로그인 => AWS에서 제공해주는 키파일로 로그인 (이거 유출되면 큰일남)
– 기존에는 www유저를 생성해서 웹서버를 운영했는데, 기본 ubuntu유저로 해도 되지 않을까라는 안이한 생각이 든다.
– 방화벽 관련 코드는 실행하면 안된다. (에러남)

###하면서 삽질한 거
– 기존의 방화벽 관련 코드를 다 삭제해야 했다.
– root로 로그인 하던 것들을 모두 수정해야했다
– 자동으로 로그인 하는 코드를 삭제
– chef server 설치중 메모리가 모자라서 인터럽트 걸림 (1기가에서 2기가로 올리니 괜찮아짐)
– chef server 설치후 레시피 업로드 중 용량이 부족하여 인스턴스를 끄고 이미지를 뜬후 용량을 증설하여 다시 시작.
– terminate했는데, 인스턴스가 바로 안 없어져서 당황
– 고정아이피는 VPS 설정을 해야만 설정할 수 있어서 또 당황
– 가입시 기본 인스턴스 생성 가능 숫자제한이 있음 (20개)
– 고정아이피도 할당 가능한게 제한이 있음(5개)
– fabric에서 리모트 명령 실행시 root로 실행해야 하는게 있는데, 기존 방식과 달라져서 sudo 옵션을 찾기까지 또 삽질

###VPC설정 (해야할게 많다)
– 인터넷 게이트웨이 설정
– 서브넷 설정
– 라우팅 테이블 설정
[/markdown]