Transcript
Page 1: Posquit0 - Fabric을 이용한 ssh streamlining

Application Deployment를 위한,

Fabric의 SSH Streamlining

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

박 병진 (Posquit0) | POSTECH CSE 10 | Jul. [email protected]

“Must be the change that you want to see in the world!”

포스텍 개발자 네트워크 PoApper

Page 2: Posquit0 - Fabric을 이용한 ssh streamlining

No Content

1 Intro

2 Deployment with Fabric

3 Tips

포스텍 개발자 네트워크 PoApper

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

Page 3: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric

“System Administration 혹은 Application Deployment를 위해 SSH의 사용을 간소화 시켜주는 도구"

파이썬(Python)으로 작성된 도구로, 사용자가 작성한 임의의 파이썬 코드를 fab 명령어로 호출.=> fabfile.py 작성

Fabric이 제공하는 주요 기능1) 로컬 혹은 원격의 명령어 실행2) 원격의 sudo 명령어 실행 가능3) 파일 업로드 / 다운로드

Intro: Fabric

from fabric.api import run

def host_info():run(‘uname –a’)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab –H localhost host_info[localhost] Executing task ‘host_info’[localhost] run: uname –a[localhost] Login password for ‘posquit0’:

※ 비슷한 도구로 루비(Ruby)로 작성된 Capistrano가 있다. (Ruby 프로젝트의 경우, 이를 고려할 것.)

Page 4: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 설치하기

다음은 sudo 권한이 없는 서버를 이용하고 있다고 가정.

1) sudo 권한이 없는 경우 fabric을 설치하기 위한 가상환경을 생성한다.

2) 파이썬 패키지 관리자인 pip를 이용하여 fabric을 설치한다.

Intro: Fabric 설치하기

※ sudo 권한이 있을 경우 가상환경이 아닌 서버에 fabric을 설치하도록 한다.

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# mkvirtualenv --no-site-packages --distribute myenvNew python executable in myenv/bin/pythonInstalling distribute………………done.Installing pip………………………done.posquit0:~ (myenv) #

posquit0:~ (myenv) # pip install fabricDownloading/unpacking fabric…

Page 5: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(1) – Hello, Fabric!

1) 현재 폴더에 fabfile.py를 아래와 같이 작성한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(1)

from fabric.api import run

def hello():“”” Hello Fabric! “””print “Hello, Fabric!”

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab helloHello, Fabric!

Done.

Page 6: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(2) – 명령에 인자 주기

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(2)

# ... (생략)

def helloTo(name=“world”):“”” Hello to {name} “””print “Hello, %s” % name

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab helloTo:Posquit0Hello, Posquit0posquit0:~# fab helloTo:name=LasVegasHello, LasVegas

Page 7: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(3) – 로컬 명령 실행

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(3)

# ... (생략)

def restartServices(name=None):“”” Restart services as apache2, nginx, mysql, etc. “””if name is None:

local(“sudo service apache2 restart”)local(“sudo service nginx restart”)local(“sudo service mysql restart”)

else:local(“sudo service %s restart” % name)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab restartServicesposquit0:~# fab restartServices:mysql

Page 8: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(4) – 원격 명령 실행

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(4)

# ... (생략)

def host_info():“”” Check host information “””run(‘uname –a’)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab –H localhost host_info[localhost] Executing task ‘host_info’[localhost] run: uname –a[localhost] Login password for ‘posquit0’:

Page 9: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(5) – 원격 sudo 명령 실행

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(5)

# ... (생략)

def reboot():“”” Reboot remote server. “””sudo(‘reboot’)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab –H ubuntu.poapper.com:2222 reboot블롸뷁복꿸뛣뿌르구꼬흔따르리뽀꾸라릐뉘구존즤규…Bye…

Page 10: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(6) – 파일 전송

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(6)

# ... (생략)

def copyVimConfigTo():“”” Copy Vim Config to remote server: .vim/, .vimrc “””run(‘rm –rf ~/.vim;rm .vimrc’)put(‘~/.vim’, ‘~/’)run(‘ln –s ~/.vim/.vimrc ~/.vimrc’)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab –H ubuntu.poapper.com:2222 copyVimConfigTo[Ubuntu.poapper.com] put: ~/.vim/…………

Page 11: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric 시작해보기(7) – 파일 다운로드

1) 현재 폴더에 fabfile.py를 아래의 내용을 추가한다.

2) Fab 명령어를 통해 자신이 작성한 모듈을 호출해본다.

Intro: Fabric 시작해보기(7)

# ... (생략)

def copyVimConfigFrom():“”” Copy Vim Config from remote server: .vim/, .vimrc “””local(‘rm –rf ~/.vim;rm .vimrc’)get(‘~/.vim’, ‘~/’)local(‘ln –s ~/.vim/.vimrc ~/.vimrc’)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# fab –H ubuntu.poapper.com:2222 copyVimConfigFrom[Ubuntu.poapper.com] get: ~/.vim/…………

Page 12: Posquit0 - Fabric을 이용한 ssh streamlining

Fabric의 원리“현재 위치에서 상위 폴더로 이동해가며, fabfile.py를 검색한다. 하위 폴더는 찾지 않는다.“

Example : Podori 프로젝트

- 프로젝트의 최상위(root) 폴더에 fabfile.py 작성- 하위폴더(nginx, podori, diet 등)에서 fab 호출 가능.- 상위폴더(Podori 프로젝트 폴더 외부)에서 호출 불가능.

=> 프로젝트 단위의 fabfile.py 작성을 위한 설계

Intro: Fabric의 원리

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

Project/podori.poapper.com/ㅁ apache2/ㅁ log/ㅁ nginx/ㅁ podori/

ㅁ main/ㅁ diet/AUTHORSfabfile.pyINSTALLpip-requirementsREADME.mdrobot.txt

Page 13: Posquit0 - Fabric을 이용한 ssh streamlining

Core Functionality- Run() : 원격 서버에서 명령어를 수행한다.- Local() : 로컬 서버에서 명령을 수행한다.- Sudo() : 원격 서버에서 루트권한으로 명령을 수행한다.- Reboot() : 원격의 시스템을 재시작(Reboot)한다.- Put() : 로컬 서버에서 원격 서버로 파일을 전송한다.- Get() : 원격 서버에서 로컬 서버로 파일을 전송한다.- Require() : 다양한 함수들 간의 의존성을 만든다.

=> 전제조건 없이 함수가 실행되는 것을 방지한다.

Intro: Core Functionality

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

def run(command, shell=True, pty=True, combine_stderr=None,quit=False, warn_only=False, stdout=None, stderr=None, timeout=None

)def local(command, capture=False, shell=None)def sudo(

command, shell=True, pty=True, combine_stderr=None,quit=False, user=None, warn_only=False, stdout=None,stderr=None, group=None, timeout=None

)

Page 14: Posquit0 - Fabric을 이용한 ssh streamlining

Configuration (1) – Fabric Environment (env)Fabric API의 env 변수에 설정들을 보관하며, 이는 Python Dictionary의 Wrapper Class이다.

- Hosts & Roles- Code Repositories- Shell- User & Password- etc.

Intro: Configuration (1)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

from fabric.api import env

env.roledefs = {‘develop’ : [‘ubuntu.poapper.com’, ‘work.posquit0.com’],‘product’ : [‘pou.poapper.com],

}

env.user = ‘posquit0’

# … 생략

Page 15: Posquit0 - Fabric을 이용한 ssh streamlining

Configuration (2) – Global Settings (~/.fabricrc)~/.fabricrc는 Fabric의 전역 설정 파일로, Fabric이 실행 전에 우선 실행된다. (Python 코드 작성)

Intro: Configuration (2)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

from fabric.api import env

env.roledefs = {‘develop’ : [‘ubuntu.poapper.com’, ‘work.posquit0.com’],‘product’ : [‘pou.poapper.com],

}

env.passwords = {‘[email protected]’ : ‘skRtldhkd><’,‘[email protected]’ : ‘dlrjf2013alesi’

}

Page 16: Posquit0 - Fabric을 이용한 ssh streamlining

모듈확인- 현재 Fabric이 인식한 fabfile의 명령어를 Docstring과 함께 출력한다.

Intro: 모듈 확인

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# fab –lAvailable commands:

all Use all serversapplyChanges push to remote repository, pull to product servercommit Commit your changesdev Use development server settingshello Hello Fabric!helloTo Hello To {name}host_info Print Host’s Informationprod Use production server settingsreboot Reboot remote server.restartServices Restart Services as Apache2, Nginx, MySQL, etc.

※ 파이썬 프로그래밍을 할 때는, Docstring을 작성하는 습관을 들이도록 합시다 :D

Page 17: Posquit0 - Fabric을 이용한 ssh streamlining

No Content

1 Intro

2 Deployment with Fabric

3 Tips

포스텍 개발자 네트워크 PoApper

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

Page 18: Posquit0 - Fabric을 이용한 ssh streamlining

Git Repository 생성

1) 프로젝트 폴더를 생성 후, Git Repository로 등록한다.

2) Remote Repository를 생성한 후, 기존의 프로젝트 폴더는 제거한다.

Deployment with Fabric: Git Repository 생성

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# mkdir myprojectposquit0:~# cd myproject/posquit0:~/myproject# git initInitialized empty Git repository in myproject/.git/posquit0:~/myproject# touch README; git add .posquit0:~/myproject# git commit –m “First Commit”

posquit0:~# git clone --bare myproject myproject.gitposquit0:~# touch myproject.git/git-daemon-export-okposquit0:~# rm –rf myprojectposquit0:~# cd myproject.gitposquit0:~/myproject# git --bare update-server-infoposquit0:~/myproject# mv hooks/post-update.sample hooks/post-update

Page 19: Posquit0 - Fabric을 이용한 ssh streamlining

프로젝트 복제1) 실제 서비스 운영을 위한 위치(가정)에서 이전 단계에서 만든 Remote Repository를 복제한다.

git clone ssh://{사용자 계정}@{Host 이름}:{Port}/{Repository 경로} {{생성 폴더이름}}

2) 개발을 위한 위치(외부 서버라 가정)에서 또 다시 Remote Repository를 복제한다.

Deployment with Fabric: 프로젝트 복제

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~# git clone ssh://[email protected]:22/~/myproject.git product

posquit0:~# git clone ssh://[email protected]:22/~/myproject.git develop

Page 20: Posquit0 - Fabric을 이용한 ssh streamlining

변경사항 적용(1) – Without Fabric1) 개발 서버에서 변경사항을 저장하고 Commit 한다.

2) 개발서버의 내용을 Remote Repository에 적용한다. (Push)

3) Remote Repository의 내용을 운영 서버에 적용한다. (Pull)

Deployment with Fabric: 변경사항 적용(1)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# git add .posquit0:~/develop# git commit –m “Several Changes! May be…”

posquit0:~/develop# git push

posquit0:~# cd productposquit0:~/product# git pull

Page 21: Posquit0 - Fabric을 이용한 ssh streamlining

변경사항 적용(2) – With Fabric1) fabfile.py를 프로젝트의 최상위 폴더에 작성한다.

2) 개발서버의 변경 사항을 커밋하고 fab 명령을 통해 Remote Repository 및 운영 서버에 적용한다.

Deployment with Fabric: 변경사항 적용(2)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# vim fabfile.py

# ... (생략)

def applyChanges():local(‘git push’)run(‘cd product/; git pull’)

posquit0:~/develop# git add .posquit0:~/develop# git commit –m “Several Changes! May be…”posquit0:~/develop# fab applyChanges

※ 호스트 정보가 Fabric에 등록되어 있지 않아, 호스트 정보를 물어 볼 것이다.

Page 22: Posquit0 - Fabric을 이용한 ssh streamlining

Host 정보 입력(1) – 전역 Host1) fabfile.py의 내용에 다음을 추가한다.

2) 다시 한 번 fab 명령을 통해 applyChanges를 호출해보자.

Deployment with Fabric: Host 정보 입력(1)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# vim fabfile.py

# ... (생략)env.hosts = [

[email protected]:22’,]# ... (생략)

posquit0:~/develop# git add .posquit0:~/develop# git commit –m “Added Host Information”posquit0:~/develop# fab applyChanges

※ 호스트 정보가 Fabric에 등록되어 있어, 호스트 정보를 물어 보지 않고 진행된다.

Page 23: Posquit0 - Fabric을 이용한 ssh streamlining

Host 정보 입력(2) – 개별 Host 관리- fabfile.py의 내용에 env.hosts에 관한 내용을 다음과 같이 변경한다.

Deployment with Fabric: Host 정보 입력(2)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

def dev():“”” Use development server settings “””env.hosts = [

[email protected]:22’,]

def prod():“”” Use production server settings “””env.hosts = [

[email protected]:22’,]

def all():“”” Use all servers “””env.hosts = [

[email protected]:22’,‘[email protected]:22’,

]

Page 24: Posquit0 - Fabric을 이용한 ssh streamlining

Host 정보 입력(2) – 개별 Host 관리- 다음과 같이 목표 서버를 지정하여 명령을 수행할 수 있다.

Deployment with Fabric: Host 정보 입력(2)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# git add .posquit0:~/develop# git commit –m “Divided host information”posquit0:~/develop# fab dev applyChangesposquit0:~/develop# fab prod applyChangesposquit0:~/develop# fab all applyChanges

※ 각 호스트 별로 프로젝트 폴더의 위치를 env에 저장하여, 이를 참조하도록 applyChanges 모듈을 수정한다.

Page 25: Posquit0 - Fabric을 이용한 ssh streamlining

No Content

1 Intro

2 Deployment with Fabric

3 Tips

포스텍 개발자 네트워크 PoApper

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

Page 26: Posquit0 - Fabric을 이용한 ssh streamlining

Roles (1) – 역할 별 모듈 수행- Roles는 Host를 역할 별로 분류하여 파이썬 태그를 이용하여 모듈을 수행 할 Role을 지정할 수 있다.

- 두 개 이상의 Role을 지정할 수도 있다.

Tips:Roles (1)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

※ get_version() 모듈은 ‘develop’ 그룹의 Hosts들에서 수행 될 것이다.

from fabric.api import env, roles, run

env.roledefs = {‘develop’ : [‘ubuntu.poapper.com’, ‘work.posquit0.com’],‘product’ : [‘pou.poapper.com],

}

@roles(‘develop’)def get_version():

run(‘cat /etc/issue’)

@roles(‘develop’, ‘product’)def get_version():

run(‘cat /etc/issue’)

Page 27: Posquit0 - Fabric을 이용한 ssh streamlining

Roles (2) – 문제 해결- 기본으로 제공되는 Fabric의 roles 태그는 명령어 --roles 옵션으로 오버라이드가 안된다.

=> 사용자 정의 태그를 작성하여 roles 태그를 교체하여 문제를 해결할 수 있다.

Tips:Roles (2)

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

※ get_version() 모듈은 ‘test’ 그룹의 Hosts들에서 수행 될 것이다.

# ... (생략)def default_roles(*role_list):

def selectively_attach(func):if not env.roles and not env.hosts:

return roles(*role_list)(func)else:

if env.hosts:func = hosts(*env.hosts)(func)

if env.roles:func = roles(*env.roles)(func)

return funcreturn selectively_attach

@default_roles(‘develop’, ‘product’)def get_version():

run(‘cat /etc/issue’)

posquit0:~/develop# fab get_version --roles test

Page 28: Posquit0 - Fabric을 이용한 ssh streamlining

Dealing with Failures – With 문 사용- 기본적으로 Task가 실패할 경우(에러가 발생할 경우), Fabric은 종료된다.

=> Failure가 예상되는 경우, Context Manager를 통해 경고문만 출력하도록 한다.

Tips: Dealing with Failures

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

from __future__ import with_statementfrom fabric.api import local, settings, run

def symlinkTo(src, dst):“”” Make a symbolic link “””with settings(warn_only=True):

run(‘rm %s’ % dst)run(‘ln –s %s %s’ % (src, dst))

※ Python 2.5 버전의 경우 with문 사용을 위해서는 __future__를 import 하여야 한다.

Page 29: Posquit0 - Fabric을 이용한 ssh streamlining

Invoke 구현 – 임의의 원격 sudo 명령 수행- 다음과 fabfile에 invoke를 구현한다.

Tips: Invoke 구현

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

@roles(‘all’)def invoke(command):

“”” Invoke arbitrary commands to remote server “””sudo(command)

Page 30: Posquit0 - Fabric을 이용한 ssh streamlining

Server Package Updates- 다음과 같이 fabfile에 서버 패키지 업데이트를 위한 모듈을 작성한다.

- Fab 명령을 통해 원격 서버의 패키지 업데이트를 수행한다.

Tips: Server Package Updates

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

posquit0:~/develop# fab update

def update():“”” Update Packages on server “””sudo(‘aptitude update; aptitude safe-upgrade’)

Page 31: Posquit0 - Fabric을 이용한 ssh streamlining

참고자료?

Fabric Docs: http://docs.fabfile.org

포스텍 개발자 네트워크 PoApper

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining

Page 32: Posquit0 - Fabric을 이용한 ssh streamlining

Thank You for Listening!

포스텍 개발자 네트워크 PoApper

커뮤니티 팀 내부 세미나 – Fabric을 이용한 SSH Streamlining