Page 1
Real virtual environments without virtualenv
Mihai Iachimovschi
@mishunika [email protected]
Page 3
What’s inside?
– Consistency
Page 4
What’s inside?
– Consistency
– Diversity
Page 5
What’s inside?
– Consistency
– Diversity
– Isolation
Page 6
Building the dev env
Installing dependencies
- pip
- or the OS packaging tool
- or even easy_install?
Page 7
Building the dev env (cont)How?
- everything globally
- or inside a virtualenv
- or using conda
- Vagrant!?
Page 10
Deploying
Where?
- PaaS
Page 11
Deploying
Where?
- PaaS
- IaaS
Page 12
Deploying
Where?
- PaaS
- IaaS
- your own server
Page 13
Virtualenvs
venv Bvenv A
App A App B
shared system libraries and packages
OS Kernel
vevn C
App C
venv N
App N
Page 14
When something breaks…
Page 16
Pack it!
Let’s see how we can containerize it.
Page 18
“Container? It’s a VM!”
Page 19
“Container? It’s a VM!”
It’s not!
Page 20
“Container? It’s a VM!”
It’s not!
It’s just a process
Page 21
“Container? It’s a VM!”
It’s not!
It’s just a process
It shares the system kernel
Page 22
“Container? It’s a VM!”
It’s not!
It’s just a process
It shares the system kernel
It is running in it’s own namespace
Page 23
Containers
shared system libraries and packages
OS Kernel
Docker Engine
Page 24
Container anatomy
Page 25
Container anatomy (cont.)
Page 26
Container anatomy (cont.)
cgroups
Page 27
Container anatomy (cont.)
cgroups
namespaces
Page 28
What’s inside?
– System dependencies
– Separate libs & bins
– Limited endpoints
Page 30
Docker images
Self contained
Page 31
Docker images
Self contained
Isolated
Page 32
Docker images
Self contained
Isolated
Immutable
Page 33
Docker images
Self contained
Isolated
Immutable
Portable
Page 34
Docker containers
Isolated process
Disposable
Running over the image FS layers (AUFS)
Page 35
AUFS
image: docker.org
Page 36
Stacking = cumulative
How do we delete files?
Not re-writing them.
Page 37
How we delete?
image: docker.org
Page 38
Stacking = cumulativeHow do we delete files?
Not re-writing them.
Beware!
It is still cumulative,it’ll increase the size of the final image.
Page 39
“My data is not readonly!”
Page 40
“My data is not readonly!”
How to handle the actual app data?
Page 41
“My data is not readonly!”
How to handle the actual app data?
Volumes: Saving the state!
Page 43
Building images
– Raw product (source code)
Page 44
Building images
– Raw product (source code)
– Cooking recipe (Dockerfile)
Page 45
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 46
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 47
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 48
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 49
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 50
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 51
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 52
Dockerfile
FROM python:3.5 ENV PYTHONUNBUFFERED 1 RUN mkdir /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
Page 53
We’ll go through
– Building
– Running
– Gathering logs
– Sneaking into a container
Page 54
Build
docker build —t mihai/django-app .
Page 55
Build
docker build —t mihai/django-app .
Page 56
Build
docker build —t mihai/django-app .
Page 57
Build
docker build —t mihai/django-app .
Page 58
Build
docker build —t mihai/django-app .
Page 59
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 60
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 61
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 62
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 63
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 64
Run
docker run --publish 8000:8000 \ mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 65
Run (detached)
docker run --publish 8000:8000 \ --detach --name my_django_app mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 66
Run (detached)
docker run --publish 8000:8000 \ --detach --name my_django_app mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 67
Run (detached)
docker run --publish 8000:8000 \ --detach --name my_django_app mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 68
Run (detached)
docker run --publish 8000:8000 \ --detach --name my_django_app mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 69
Run +volumesdocker run --publish 8000:8000 \ --detach --name my_django_app --volume $(pwd):/code mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 70
Run +volumesdocker run --publish 8000:8000 \ --detach --name my_django_app --volume $(pwd):/code mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 71
Run +volumesdocker run --publish 8000:8000 \ --detach --name my_django_app --volume $(pwd):/code mihai/django-app \ python manage.py \ runserver 0.0.0.0:8000
Page 72
Gather logs
docker logs -f my_django_app
Page 73
Gather logs
docker logs -f my_django_app
Page 74
Gather logs
docker logs -f my_django_app
Page 75
Gather logs
docker logs -f my_django_app
Page 76
Gather logs
docker logs -f my_django_app
Page 77
Get inside the container
docker exec -it my_django_app sh
Page 78
Get inside the container
docker exec -it my_django_app sh
Page 79
Get inside the container
docker exec -it my_django_app sh
Page 80
Get inside the container
docker exec -it my_django_app sh
Page 81
Get inside the container
docker exec -it my_django_app sh
Page 82
Get inside the container
docker exec -it my_django_app sh
Page 83
So now we have it
Isolated
Has its dependencies bundled
It’s disposable
Page 84
But that’s not enough
Page 85
But that’s not enough
Page 86
But that’s not enough
How about external dependencies?
Page 87
But that’s not enough
How about external dependencies?
How about creating a full prod-like environment?
Page 88
But that’s not enough
How about external dependencies?
How about creating a full prod-like environment?
No problem!We just need more containers…
Page 89
Stack them, it’s easy!
Page 91
docker-compose.ymlversion: '2' services: db: image: postgres web: build: . command: python manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" depends_on: - db
Page 92
Run
docker-compose up
Page 93
extended compose yml
common.yml
docker-compose-prod.yml docker-compose-dev.yml
Page 94
Production composeversion: '2' services: ... web: extends: file: common.yml service: web command: uwsgi --ini uwsgi.ini depends_on: - db - nginx
Page 95
Production?
– Service discovery (Orchestration)
– Secrets
– Logging
Page 96
Service discovery– Compose
– Swarm
– Consul
– etcd
– ZooKeeper
Page 97
Secrets– env vars
– volumes with secrets
– docker-vault
– keywhiz
NB: Kubernetes has it built in
Page 98
Logging– stderr
– syslog
– journald
– json
– other custom logging drivers
Page 99
Docker for Mac & Windows
– Mac: xhyve
– Win: Hyper-V
Page 100
Summing up!Environments:
– uniform (dev, prod)
– self-contained
– properly isolated
– immutable.