SlideShare a Scribd company logo
D O C K E R 를 이 용 하 여 P Y T H O N 개 발 환 경 을
빠 르 게 구 성 하 고 , 백 앤 드 서 비 스 를 탐 색 하 는 기
술 , 실 행 환 경
P Y C O N K R - 2 0 1 5
B Y U N G W O O K A H N
1
Who am I
ByungWook Ahn
G+ : https://plus.google.com/+EricAhns
device driver(windows, linux) experienced
media streaming experienced
CDN experienced
docker experienced
Platform Architecture Team, SKPlanet
Py conkr 20150829_docker-python
D O C K E R
C O N TA I N E R
D O C K E R - M A C H I N E
D O C K E R - C O M P O S E
S A M P L E A P P A R C H I T E C T U R E
T E S T E N V I R O N M E N T
P E R F O R M A N C E 

T O D A Y …
h t t p s : / / w w w . d o c k e r . c o m / 	
  
B U I L D , S H I P, R U N
A n o p e n p l a t f o r m f o r
d i s t r i b u t e d a p p l i c a t i o n s f o r
d e v e l o p e r s a n d s y s a d m i n s
D O C K E R
C O N TA I N E R
F R O M u b u n t u
R U N 
a p t - g e t u p d a t e & & 
a p t - g e t i n s t a l l - y p y t h o n p y t h o n - d e v p y t h o n -
p i p p y t h o n - v i r t u a l e n v & & 
r m - r f / v a r / l i b / a p t / l i s t s / *
$ c a t D o c k e r f i l e
$ docker build -t=“mypython” . <- image 생성 ( 현재 디렉토리에 있는
Dockerfile을 참조)
$ docker images <- Docker Host의 image 확인
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mypython latest ecc926c495f8 7 seconds ago 373.6 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
mysql latest c45e4ba02f47 12 days ago 283.8 MB
python 2.7 e1857ee1f3b5 5 weeks ago 674.4 MB
nginx latest 6886fb5a9b8d 5 weeks ago 132.9 MB
$ docker run -it mypython python <- container 실행
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
$ docker ps -a <= docker host의 containers print
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b596713d6934 mypython "python" 2 seconds ago Exited (0) 2 seconds ago clever_hypatia
Docker Host example
$ top
docker container : ubuntu 2ea
container : ubuntu(nginx)
D O C K E R - M A C H I N E
VirtualBox
vmware
Microsoft Hyper-V
SOFTLAYER
openstack
Microsoft Azure
AWS
rackspace
DigitalOcean
create & remove
run
➜ 0 2 - S R C d o c k e r- m a c h i n e l s
N A M E A C T I V E D R I V E R S TAT E U R L S WA R M
d e f a u l t v i r t u a l b o x S t o p p e d
d e v v i r t u a l b o x S t o p p e d
p y c o n k r v i r t u a l b o x S t o p p e d
p y c o n k r 0 2 v i r t u a l b o x S t o p p e d
p y c o n k r 0 3 v i r t u a l b o x S t o p p e d
p y c o n k r 0 4 v i r t u a l b o x S t o p p e d
p y c o n k r 0 5 v i r t u a l b o x S t o p p e d
DOCKER-COMPOSE
W E B
D B
$ docker-compose up -d
C O N F I G R AT I O N ?
= > YA M L
$ cat docker-compose.yml
db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=hellopython
- MYSQL_DATABASE=shopping_db
ports:
- "3306:3306"
web:
build: ./web_api/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/web_api
ports:
- "8000:8000"
links:
- db:db
Sample Application
A N G U L A R
J S O N
P Y T H O N
R E S T A P I
P Y T H O N
R E S T A P I
D B
L O A D
B A L A N C E R
L O A D
B A L A N C E R
A N G U L A R
J S O N
A N G U L A R
J S O N
P Y T H O N
R E S T A P I
P Y T H O N
R E S T A P I
D B
L O A D
B A L A N C E R
L O A D
B A L A C E R
A N G U L A R
J S O N
J AVA
R E S T A P I
J AVA
R E S T A P I
G O L A N G
R E S T A P I
G O L A N G
R E S T A P I
R O U T I N G
R E D I S
Restful API…
T E S T E N V I R O N M E N T
1 2
Traffic Gen. Server
Dell R620
2.0 GHz/2P/12C
32G
Docker Host.
HP DL380G7
2.13GHz/1P/4C
24GB
load testing tool?
nGrinder/Apache ab/locust.io
T E S T E N V I R O N M E N T
$ docker inspect web1
[{
"AppArmorProfile": "",
"Args": [
"-g",
"daemon off;"
],
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"CpuShares": 1024, =>
"Cpuset": "",
"Domainname": “",
…
…
$ docker inspect web2
[{
"AppArmorProfile": "",
"Args": [
"-g",
"daemon off;"
],
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"CpuShares": 512, =>
"Cpuset": "",
"Domainname": “",
…
…
$ docker inspect web3
[{
"AppArmorProfile": "",
"Args": [
"-g",
"daemon off;"
],
"Config": {
"AttachStderr": false,
"AttachStdin": false,
"AttachStdout": false,
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"CpuShares": 512, =>
"Cpuset": "",
"Domainname": “",
…
…
C P U :
5 0 %
C P U :
2 5 %
C P U :
2 5 %
T E S T C A S E
web_api_case_01
Django(1.8.3) + djangodb + MySQL 5.6.23
web_api_case_02
Django(1.8.3) + No DB operation
web_api_case_03
Django(1.8.3) + djangodb + PostgreSQL 9.4.4
web_api_case_04
Django(1.8.3) + djangodb + (django-cache-machine) + MySQL 5.6.23
web_api_case_demo
load balancer -> web_api_case_01
http://web_api:8000/shoppling/ APIs를 가진 예로 :
N G R I N D E R / A PA C H E A B / L O C U S T. I O
nGrinder : agent 컨테이너 5개 생성하여 테스트
// controller
$ docker run -d -v ~/.ngrinder:/root/.ngrinder --name ngrinder -p 80:80 -p 16001:16001 -p
12000-12009:12000-12009 ngrinder/controller:3.3
// agent
$ docker run -d -e 'CONTROLLER_ADDR=ngrinder:80' --link ngrinder:ngrinder ngrinder/agent:3.3
nginx : 1.9.2
index.html, 600 bytes
D E M O - C A S E 1 : S A M P L E A P P
settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'shopping'
)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'shopping_db',
'USER': 'root',
'PASSWORD': 'hellopython',
'HOST': 'db',
'PORT': 3306,
}
}
S A M P L E A P P
models.py


from django.db import models
class Shopping(models.Model):
product_code = models.TextField()
product_title = models.CharField(max_length=100, verbose_name = "Product name")
product_price = models.IntegerField(default='0', verbose_name = "Product price")
class Meta:
verbose_name = "Product list"
verbose_name_plural = "Favorite lists"
S A M P L E A P P
// views.py
def shopping_list(request):
"""
List all code shoppinglists, or create a new shopping.
"""
if request.method == 'GET':
shoppinglists = Shopping.objects.all()
serializer = ShoppingSerializer(shoppinglists, many=True)
return JSONResponse(serializer.data)
// serializers.py
from rest_framework import serializers
from shopping.models import Shopping
class ShoppingSerializer(serializers.ModelSerializer):
class Meta:
model = Shopping
fields = ('product_code', 'product_title', 'product_price')
urls.py
urlpatterns = [
url(r'^shopping/$', views.shopping_list)
]
S A M P L E A P P
db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=hellopython
- MYSQL_DATABASE=shopping_db
ports:
- "3306:3306"
web:
build: ./web_api/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/web_api
ports:
- "8000:8000"
links:
- db:db
demo : case1
P E R F O R M A N C E : C A S E 1
P Y T H O N
R E S T A P I
M Y S Q LL O A D T O O L
D E M O : C A S E 2
views.py
def shopping_list(request):
"""
List all code shoppinglists, or create a new shopping.
"""
if request.method == 'GET':
return JSONResponse({"product_code":"1005","product_title":"BILLIE GOES TO TOWN
SHOPPER","product_price":28})
P E R F O R M A N C E : C A S E 2
P Y T H O N
R E S T A P I
L O A D T O O L
N G I N X - G U N I C O R N
web:
restart: always
build: ./web
expose:
- "8000"
volumes:
- /usr/src/app/static
env_file: .env
command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 12 -b :8000
nginx:
restart: always
build: ./nginx/
ports:
- "80:80"
volumes:
- /www/static
volumes_from:
- web
links:
- web:web
N G I N X - G U N I C O R N
server {
listen 80;
server_name example.org;
charset utf-8;
location /static {
alias /usr/src/app/static;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
N G I N X - G U N I C O R N
gunicorn docker_django.wsgi:application -w 2
gunicorn docker_django.wsgi:application -w 12
D E M O : C A S E 3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'shopping_db',
'USER': 'postgres',
'PASSWORD': 'hellopython',
'HOST': 'db',
'PORT': 5432,
}
}
web:
build: ./web_api/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/web_api
ports:
- "8000:8000"
links:
- db:db
db:
image: postgres
ports:
- "5432:5432"
environment:
- DB_USER=postgres
- DB_PASS=hellopython
- DB_NAME=shopping_db
D E M O : C A S E 3
P E R F O R M A N C E : C A S E 3
D E M O : C A S E 4
settings.py
CACHE = {
'default':{
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'memcached:11211'
}
}
views.py
def shopping_list(request):
"""
List all code shoppinglists, or create a new shopping.
"""
if request.method == 'GET':
data = cache.get('shoppinglists')
if data is None:
shoppinglists = Shopping.objects.all()
serializer = ShoppingSerializer(shoppinglists, many=True)
data = serializer.data
cache.set('shoppinglists', data, 60) # seconds
return JSONResponse(data)
db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=hellopython
- MYSQL_DATABASE=shopping_db
ports:
- "3306:3306"
memcached:
image: memcached:1.4
ports:
- "11211:11211"
web:
build: ./web_api/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/web_api
ports:
- "8000:8000"
links:
- db:db
- memcached:memcached
D E M O : C A S E 4
P E R F O R M A N C E : C A S E 4
P Y T H O N
R E S T A P I
M Y S Q LL O A D T O O L
M E M C A C H E D
D E M O
P Y T H O N
R E S T A P I
M Y S Q L
M E M C A C H E D
W E B PA G E
H A P R O X Y
W E B PA G E
W E B PA G E
H A P R O X Y
P Y T H O N
R E S T A P I
P Y T H O N
R E S T A P I
web:
restart: always
build: ./web_api/
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/web_api
expose:
- "8000"
links:
- db
- memcached
weblb:
restart: always
image: tutum/haproxy
links:
- web
ports:
- "80:80"
environment:
- BACKEND_PORT=8000
db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=hellopython
- MYSQL_DATABASE=shopping_db
ports:
- "3306"
memcached:
image: memcached:1.4
ports:
- "11211"
demo-composer.yml
- haproxy
- mysql
- memcached
- python django restframeowork
$ docker-compose build .
$ docker-compose scale web=3
$ docker-compose up -d —no-recreate
P E R F O R M A N C E : D E M O
demo
Thanks : Q&A

More Related Content

PDF
Http capturing
PDF
Keep it simple web development stack
PDF
Roll Your Own API Management Platform with nginx and Lua
PDF
Centralize your Business Logic with Pipelines in Elixir
ZIP
AnyMQ, Hippie, and the real-time web
PDF
RestMQ - HTTP/Redis based Message Queue
PDF
Logstash for SEO: come monitorare i Log del Web Server in realtime
PDF
Using ngx_lua in UPYUN
Http capturing
Keep it simple web development stack
Roll Your Own API Management Platform with nginx and Lua
Centralize your Business Logic with Pipelines in Elixir
AnyMQ, Hippie, and the real-time web
RestMQ - HTTP/Redis based Message Queue
Logstash for SEO: come monitorare i Log del Web Server in realtime
Using ngx_lua in UPYUN

What's hot (20)

PDF
Containers for sysadmins
PPT
Realtime Analytics Using MongoDB, Python, Gevent, and ZeroMQ
PDF
HTTP For the Good or the Bad - FSEC Edition
PDF
Redis & ZeroMQ: How to scale your application
PDF
Redis as a message queue
PDF
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
PDF
Learning Dtrace
PDF
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
PDF
ZeroMQ Is The Answer: PHP Tek 11 Version
PDF
Node.js API 서버 성능 개선기
PDF
"Swoole: double troubles in c", Alexandr Vronskiy
PDF
Get Soaked - An In Depth Look At PHP Streams
PDF
Tips on how to improve the performance of your custom modules for high volume...
PDF
Using Puppet to Create a Dynamic Network - PuppetConf 2013
PDF
Trading with opensource tools, two years later
PPT
Working with databases in Perl
PDF
Debugging: Rules & Tools
PDF
PL/Perl - New Features in PostgreSQL 9.0
ODP
Caching and tuning fun for high scalability
PDF
Devinsampa nginx-scripting
Containers for sysadmins
Realtime Analytics Using MongoDB, Python, Gevent, and ZeroMQ
HTTP For the Good or the Bad - FSEC Edition
Redis & ZeroMQ: How to scale your application
Redis as a message queue
WordPress Security - ওয়ার্ডপ্রেসের সিকিউরিটি
Learning Dtrace
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
ZeroMQ Is The Answer: PHP Tek 11 Version
Node.js API 서버 성능 개선기
"Swoole: double troubles in c", Alexandr Vronskiy
Get Soaked - An In Depth Look At PHP Streams
Tips on how to improve the performance of your custom modules for high volume...
Using Puppet to Create a Dynamic Network - PuppetConf 2013
Trading with opensource tools, two years later
Working with databases in Perl
Debugging: Rules & Tools
PL/Perl - New Features in PostgreSQL 9.0
Caching and tuning fun for high scalability
Devinsampa nginx-scripting
Ad

Viewers also liked (11)

PDF
High perforance-browse-networking-2015-bwahn
PDF
Docker command
PDF
Cdn gslb-20151209
PDF
Docker deploy
PDF
Docker remote-api
PDF
Spring rest-doc-2015-11
PDF
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
PDF
Py conkr 20150829_docker-python
PDF
Tensorflow in Docker
PDF
[코세나, kosena] 빅데이터 구축 및 제안 가이드
PDF
Swift server-side-let swift2016
High perforance-browse-networking-2015-bwahn
Docker command
Cdn gslb-20151209
Docker deploy
Docker remote-api
Spring rest-doc-2015-11
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
Py conkr 20150829_docker-python
Tensorflow in Docker
[코세나, kosena] 빅데이터 구축 및 제안 가이드
Swift server-side-let swift2016
Ad

Similar to Py conkr 20150829_docker-python (20)

PDF
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
PDF
Burn down the silos! Helping dev and ops gel on high availability websites
PDF
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
PDF
Puppet Camp London 2015 - Helping Data Teams with Puppet
PDF
glance replicator
PDF
Perl web frameworks
PDF
Curscatalyst
PPTX
Running Docker in Development & Production (#ndcoslo 2015)
PDF
Puppet Camp 2012
PDF
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
PDF
IR Journal (itscholar.codegency.co.in).pdf
PPTX
REST with Eve and Python
PDF
MongoDB Europe 2016 - Debugging MongoDB Performance
PDF
Play With Docker
KEY
dotCloud and go
PPT
Why and How Powershell will rule the Command Line - Barcamp LA 4
PDF
Using docker for data science - part 2
PDF
Docker by Example - Basics
PDF
Adding replication protocol support for psycopg2
PDF
AWS Study Group - Chapter 03 - Elasticity and Scalability Concepts [Solution ...
파이썬 개발환경 구성하기의 끝판왕 - Docker Compose
Burn down the silos! Helping dev and ops gel on high availability websites
Helping Data Teams with Puppet / Puppet Camp London - Apr 13, 2015
Puppet Camp London 2015 - Helping Data Teams with Puppet
glance replicator
Perl web frameworks
Curscatalyst
Running Docker in Development & Production (#ndcoslo 2015)
Puppet Camp 2012
Django로 만든 웹 애플리케이션 도커라이징하기 + 도커 컴포즈로 개발 환경 구축하기
IR Journal (itscholar.codegency.co.in).pdf
REST with Eve and Python
MongoDB Europe 2016 - Debugging MongoDB Performance
Play With Docker
dotCloud and go
Why and How Powershell will rule the Command Line - Barcamp LA 4
Using docker for data science - part 2
Docker by Example - Basics
Adding replication protocol support for psycopg2
AWS Study Group - Chapter 03 - Elasticity and Scalability Concepts [Solution ...

Recently uploaded (20)

PPTX
presentation_pfe-universite-molay-seltan.pptx
PPTX
Slides PPTX World Game (s) Eco Economic Epochs.pptx
PDF
The New Creative Director: How AI Tools for Social Media Content Creation Are...
PPTX
Funds Management Learning Material for Beg
PDF
RPKI Status Update, presented by Makito Lay at IDNOG 10
PPTX
introduction about ICD -10 & ICD-11 ppt.pptx
PPTX
Introuction about WHO-FIC in ICD-10.pptx
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PPTX
INTERNET------BASICS-------UPDATED PPT PRESENTATION
PDF
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
PDF
Paper PDF World Game (s) Great Redesign.pdf
PDF
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
PDF
SASE Traffic Flow - ZTNA Connector-1.pdf
PPTX
Digital Literacy And Online Safety on internet
PPTX
artificial intelligence overview of it and more
PDF
Unit-1 introduction to cyber security discuss about how to secure a system
PDF
Slides PDF The World Game (s) Eco Economic Epochs.pdf
PPTX
international classification of diseases ICD-10 review PPT.pptx
PPTX
innovation process that make everything different.pptx
PDF
Decoding a Decade: 10 Years of Applied CTI Discipline
presentation_pfe-universite-molay-seltan.pptx
Slides PPTX World Game (s) Eco Economic Epochs.pptx
The New Creative Director: How AI Tools for Social Media Content Creation Are...
Funds Management Learning Material for Beg
RPKI Status Update, presented by Makito Lay at IDNOG 10
introduction about ICD -10 & ICD-11 ppt.pptx
Introuction about WHO-FIC in ICD-10.pptx
Tenda Login Guide: Access Your Router in 5 Easy Steps
INTERNET------BASICS-------UPDATED PPT PRESENTATION
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
Paper PDF World Game (s) Great Redesign.pdf
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
SASE Traffic Flow - ZTNA Connector-1.pdf
Digital Literacy And Online Safety on internet
artificial intelligence overview of it and more
Unit-1 introduction to cyber security discuss about how to secure a system
Slides PDF The World Game (s) Eco Economic Epochs.pdf
international classification of diseases ICD-10 review PPT.pptx
innovation process that make everything different.pptx
Decoding a Decade: 10 Years of Applied CTI Discipline

Py conkr 20150829_docker-python

  • 1. D O C K E R 를 이 용 하 여 P Y T H O N 개 발 환 경 을 빠 르 게 구 성 하 고 , 백 앤 드 서 비 스 를 탐 색 하 는 기 술 , 실 행 환 경 P Y C O N K R - 2 0 1 5 B Y U N G W O O K A H N 1
  • 2. Who am I ByungWook Ahn G+ : https://plus.google.com/+EricAhns device driver(windows, linux) experienced media streaming experienced CDN experienced docker experienced Platform Architecture Team, SKPlanet
  • 4. D O C K E R C O N TA I N E R D O C K E R - M A C H I N E D O C K E R - C O M P O S E S A M P L E A P P A R C H I T E C T U R E T E S T E N V I R O N M E N T P E R F O R M A N C E 
 T O D A Y …
  • 5. h t t p s : / / w w w . d o c k e r . c o m /   B U I L D , S H I P, R U N A n o p e n p l a t f o r m f o r d i s t r i b u t e d a p p l i c a t i o n s f o r d e v e l o p e r s a n d s y s a d m i n s D O C K E R
  • 6. C O N TA I N E R
  • 7. F R O M u b u n t u R U N a p t - g e t u p d a t e & & a p t - g e t i n s t a l l - y p y t h o n p y t h o n - d e v p y t h o n - p i p p y t h o n - v i r t u a l e n v & & r m - r f / v a r / l i b / a p t / l i s t s / * $ c a t D o c k e r f i l e
  • 8. $ docker build -t=“mypython” . <- image 생성 ( 현재 디렉토리에 있는 Dockerfile을 참조) $ docker images <- Docker Host의 image 확인 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mypython latest ecc926c495f8 7 seconds ago 373.6 MB ubuntu latest 91e54dfb1179 4 days ago 188.4 MB mysql latest c45e4ba02f47 12 days ago 283.8 MB python 2.7 e1857ee1f3b5 5 weeks ago 674.4 MB nginx latest 6886fb5a9b8d 5 weeks ago 132.9 MB $ docker run -it mypython python <- container 실행 Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> $ docker ps -a <= docker host의 containers print CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b596713d6934 mypython "python" 2 seconds ago Exited (0) 2 seconds ago clever_hypatia
  • 9. Docker Host example $ top docker container : ubuntu 2ea container : ubuntu(nginx)
  • 10. D O C K E R - M A C H I N E VirtualBox vmware Microsoft Hyper-V SOFTLAYER openstack Microsoft Azure AWS rackspace DigitalOcean create & remove run ➜ 0 2 - S R C d o c k e r- m a c h i n e l s N A M E A C T I V E D R I V E R S TAT E U R L S WA R M d e f a u l t v i r t u a l b o x S t o p p e d d e v v i r t u a l b o x S t o p p e d p y c o n k r v i r t u a l b o x S t o p p e d p y c o n k r 0 2 v i r t u a l b o x S t o p p e d p y c o n k r 0 3 v i r t u a l b o x S t o p p e d p y c o n k r 0 4 v i r t u a l b o x S t o p p e d p y c o n k r 0 5 v i r t u a l b o x S t o p p e d
  • 11. DOCKER-COMPOSE W E B D B $ docker-compose up -d C O N F I G R AT I O N ? = > YA M L $ cat docker-compose.yml db: image: mysql environment: - MYSQL_ROOT_PASSWORD=hellopython - MYSQL_DATABASE=shopping_db ports: - "3306:3306" web: build: ./web_api/ command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/web_api ports: - "8000:8000" links: - db:db
  • 12. Sample Application A N G U L A R J S O N P Y T H O N R E S T A P I P Y T H O N R E S T A P I D B L O A D B A L A N C E R L O A D B A L A N C E R A N G U L A R J S O N
  • 13. A N G U L A R J S O N P Y T H O N R E S T A P I P Y T H O N R E S T A P I D B L O A D B A L A N C E R L O A D B A L A C E R A N G U L A R J S O N J AVA R E S T A P I J AVA R E S T A P I G O L A N G R E S T A P I G O L A N G R E S T A P I R O U T I N G R E D I S Restful API…
  • 14. T E S T E N V I R O N M E N T 1 2 Traffic Gen. Server Dell R620 2.0 GHz/2P/12C 32G Docker Host. HP DL380G7 2.13GHz/1P/4C 24GB load testing tool? nGrinder/Apache ab/locust.io
  • 15. T E S T E N V I R O N M E N T $ docker inspect web1 [{ "AppArmorProfile": "", "Args": [ "-g", "daemon off;" ], "Config": { "AttachStderr": false, "AttachStdin": false, "AttachStdout": false, "Cmd": [ "nginx", "-g", "daemon off;" ], "CpuShares": 1024, => "Cpuset": "", "Domainname": “", … … $ docker inspect web2 [{ "AppArmorProfile": "", "Args": [ "-g", "daemon off;" ], "Config": { "AttachStderr": false, "AttachStdin": false, "AttachStdout": false, "Cmd": [ "nginx", "-g", "daemon off;" ], "CpuShares": 512, => "Cpuset": "", "Domainname": “", … … $ docker inspect web3 [{ "AppArmorProfile": "", "Args": [ "-g", "daemon off;" ], "Config": { "AttachStderr": false, "AttachStdin": false, "AttachStdout": false, "Cmd": [ "nginx", "-g", "daemon off;" ], "CpuShares": 512, => "Cpuset": "", "Domainname": “", … … C P U : 5 0 % C P U : 2 5 % C P U : 2 5 %
  • 16. T E S T C A S E web_api_case_01 Django(1.8.3) + djangodb + MySQL 5.6.23 web_api_case_02 Django(1.8.3) + No DB operation web_api_case_03 Django(1.8.3) + djangodb + PostgreSQL 9.4.4 web_api_case_04 Django(1.8.3) + djangodb + (django-cache-machine) + MySQL 5.6.23 web_api_case_demo load balancer -> web_api_case_01 http://web_api:8000/shoppling/ APIs를 가진 예로 :
  • 17. N G R I N D E R / A PA C H E A B / L O C U S T. I O nGrinder : agent 컨테이너 5개 생성하여 테스트 // controller $ docker run -d -v ~/.ngrinder:/root/.ngrinder --name ngrinder -p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller:3.3 // agent $ docker run -d -e 'CONTROLLER_ADDR=ngrinder:80' --link ngrinder:ngrinder ngrinder/agent:3.3
  • 19. D E M O - C A S E 1 : S A M P L E A P P settings.py INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'shopping' ) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'shopping_db', 'USER': 'root', 'PASSWORD': 'hellopython', 'HOST': 'db', 'PORT': 3306, } }
  • 20. S A M P L E A P P models.py 
 from django.db import models class Shopping(models.Model): product_code = models.TextField() product_title = models.CharField(max_length=100, verbose_name = "Product name") product_price = models.IntegerField(default='0', verbose_name = "Product price") class Meta: verbose_name = "Product list" verbose_name_plural = "Favorite lists"
  • 21. S A M P L E A P P // views.py def shopping_list(request): """ List all code shoppinglists, or create a new shopping. """ if request.method == 'GET': shoppinglists = Shopping.objects.all() serializer = ShoppingSerializer(shoppinglists, many=True) return JSONResponse(serializer.data) // serializers.py from rest_framework import serializers from shopping.models import Shopping class ShoppingSerializer(serializers.ModelSerializer): class Meta: model = Shopping fields = ('product_code', 'product_title', 'product_price') urls.py urlpatterns = [ url(r'^shopping/$', views.shopping_list) ]
  • 22. S A M P L E A P P db: image: mysql environment: - MYSQL_ROOT_PASSWORD=hellopython - MYSQL_DATABASE=shopping_db ports: - "3306:3306" web: build: ./web_api/ command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/web_api ports: - "8000:8000" links: - db:db
  • 24. P E R F O R M A N C E : C A S E 1 P Y T H O N R E S T A P I M Y S Q LL O A D T O O L
  • 25. D E M O : C A S E 2 views.py def shopping_list(request): """ List all code shoppinglists, or create a new shopping. """ if request.method == 'GET': return JSONResponse({"product_code":"1005","product_title":"BILLIE GOES TO TOWN SHOPPER","product_price":28})
  • 26. P E R F O R M A N C E : C A S E 2 P Y T H O N R E S T A P I L O A D T O O L
  • 27. N G I N X - G U N I C O R N web: restart: always build: ./web expose: - "8000" volumes: - /usr/src/app/static env_file: .env command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 12 -b :8000 nginx: restart: always build: ./nginx/ ports: - "80:80" volumes: - /www/static volumes_from: - web links: - web:web
  • 28. N G I N X - G U N I C O R N server { listen 80; server_name example.org; charset utf-8; location /static { alias /usr/src/app/static; } location / { proxy_pass http://web:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
  • 29. N G I N X - G U N I C O R N gunicorn docker_django.wsgi:application -w 2
  • 31. D E M O : C A S E 3 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'shopping_db', 'USER': 'postgres', 'PASSWORD': 'hellopython', 'HOST': 'db', 'PORT': 5432, } }
  • 32. web: build: ./web_api/ command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/web_api ports: - "8000:8000" links: - db:db db: image: postgres ports: - "5432:5432" environment: - DB_USER=postgres - DB_PASS=hellopython - DB_NAME=shopping_db D E M O : C A S E 3
  • 33. P E R F O R M A N C E : C A S E 3
  • 34. D E M O : C A S E 4 settings.py CACHE = { 'default':{ 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'memcached:11211' } } views.py def shopping_list(request): """ List all code shoppinglists, or create a new shopping. """ if request.method == 'GET': data = cache.get('shoppinglists') if data is None: shoppinglists = Shopping.objects.all() serializer = ShoppingSerializer(shoppinglists, many=True) data = serializer.data cache.set('shoppinglists', data, 60) # seconds return JSONResponse(data)
  • 35. db: image: mysql environment: - MYSQL_ROOT_PASSWORD=hellopython - MYSQL_DATABASE=shopping_db ports: - "3306:3306" memcached: image: memcached:1.4 ports: - "11211:11211" web: build: ./web_api/ command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/web_api ports: - "8000:8000" links: - db:db - memcached:memcached D E M O : C A S E 4
  • 36. P E R F O R M A N C E : C A S E 4 P Y T H O N R E S T A P I M Y S Q LL O A D T O O L M E M C A C H E D
  • 37. D E M O P Y T H O N R E S T A P I M Y S Q L M E M C A C H E D W E B PA G E H A P R O X Y W E B PA G E W E B PA G E H A P R O X Y P Y T H O N R E S T A P I P Y T H O N R E S T A P I
  • 38. web: restart: always build: ./web_api/ command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/web_api expose: - "8000" links: - db - memcached weblb: restart: always image: tutum/haproxy links: - web ports: - "80:80" environment: - BACKEND_PORT=8000 db: image: mysql environment: - MYSQL_ROOT_PASSWORD=hellopython - MYSQL_DATABASE=shopping_db ports: - "3306" memcached: image: memcached:1.4 ports: - "11211" demo-composer.yml - haproxy - mysql - memcached - python django restframeowork $ docker-compose build . $ docker-compose scale web=3 $ docker-compose up -d —no-recreate
  • 39. P E R F O R M A N C E : D E M O
  • 40. demo