Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[deSymfony] Docker on every environment
Search
Jose Armesto
September 16, 2016
Programming
680
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[deSymfony] Docker on every environment
Jose Armesto
September 16, 2016
More Decks by Jose Armesto
See All by Jose Armesto
Lessons learnt trying to deploy Docker in production
fiunchinho
0
190
Unit Testing Sucks (... and it's our fault)
fiunchinho
5
1.5k
Hexagonal Architecture
fiunchinho
9
1.2k
Other Decks in Programming
See All in Programming
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
5.6k
The NotImplementedError Problem in Ruby
koic
1
740
Creating Composable Callables in Contemporary C++
rollbear
0
110
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
520
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
100
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
240
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2k
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
0
230
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
130
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.5k
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
160
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
200
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
190
Building Adaptive Systems
keathley
44
3k
Writing Fast Ruby
sferik
630
63k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Transcript
None
None
None
Containers. How do we transport containers from development to production?
You take the red pill, you stay in Wonderland, and
I show you how deep the rabbit hole goes.
Docker provides a beautiful API that hides the real complexity.
Why do we call them containers?
ISO standards for containers were published between 1968 and 1970.
Software containers try to be the standard for Applications distribution
Applications runtime
Development Workflow Dev Prod CI / CD
CI / CD Development Workflow Dev Prod
None
Distribution: Container Images
Packaging applications for distribution is not a new problem.
❏ Disk images .iso ❏ VMware .vdmk ❏ Vagrant .box
❏ Amazon Machine Images AMI Systems Packaging
❏ zip/tgz ❏ Java jar/war ❏ Debian deb ❏ RedHat
rpm Application Packaging
Container images combine both system and application packaging. Old best
practices still apply.
Container images can be easily built using manifests.
Building the same manifest twice could produce different images.
The difference between how you think something works and how
it actually works risks hard-to-debug production issues. Gareth Rushgrove @garethr
None
❏ Which OS is it based on? ❏ Which packages
are installed? ❏ What application is running inside? Giving a running container
❏ Which OS is it based on? ❏ Which packages
are installed? ❏ What application is running inside? Giving a running container
Operating System Which Alpine? FROM alpine CMD [“echo”, “Knock”, ”Knock”,
“Neo”]
Operating System Is this better? FROM alpine:3.4 CMD [“echo”, “Knock”,
”Knock”, “Neo”]
Operating System Tags can be overwritten! 3.4 won’t be the
same in two weeks, probably FROM alpine:3.4 CMD [“echo”, “Knock”, ”Knock”, “Neo”]
❏ Which OS is it based on? ❏ Which packages
are installed? ❏ What application is running inside? Giving a running container
Packages Which pip? FROM alpine:3.4 RUN apk add -‐-‐update py-‐pip
CMD [“echo”, “Knock”, ”Knock”, “Neo”]
Versions Specify the version FROM alpine:3.4 RUN apk add -‐-‐update
py-‐pip=8.1.2-‐r0 CMD [“echo”, “Knock”, ”Knock”, “Neo”]
❏ Which OS is it based on? ❏ Which packages
are installed? ❏ What application is running inside? Giving a running container
Application Which version of our application? FROM alpine:3.4 RUN apk
add -‐-‐update py-‐pip=8.1.2-‐r0 COPY app.py /app.py CMD [“python”, “/app.py”]
Metadata Use Docker Labels for application metadata FROM alpine:3.4 ARG
vcs_ref="Unknown" ARG build_date="Unknown" RUN apk add -‐-‐update py-‐pip=8.1.2-‐r0 LABEL org.label-‐schema.vcs-‐ref=$vcs_ref \ org.label-‐schema.build-‐date=$build_date COPY app.py /app.py CMD [“python”, “/app.py”]
Metadata Use Docker Labels for application metadata FROM alpine:3.4 ARG
vcs_ref="Unknown" ARG build_date="Unknown" RUN apk add -‐-‐update py-‐pip=8.1.2-‐r0 LABEL org.label-‐schema.vcs-‐ref=$vcs_ref \ org.label-‐schema.build-‐date=$build_date COPY app.py /app.py CMD [“python”, “/app.py”]
Standard for Docker labels
Use labels to extract info
Metadata Use Docker Labels for application metadata FROM alpine:3.4 ARG
vcs_ref="Unknown" ARG build_date="Unknown" RUN apk add -‐-‐update py-‐pip=8.1.2-‐r0 LABEL org.label-‐schema.vcs-‐ref=$vcs_ref \ org.label-‐schema.build-‐date=$build_date COPY app.py /app.py CMD [“python”, “/app.py”]
Metadata Calculate the values for the labels $ docker build
\ -‐-‐build-‐arg vcs_ref=`git rev-‐parse HEAD` \ -‐-‐build-‐arg date=`date -‐u + "%Y-‐%m-‐%dT%H:%MZ"` \ -‐t your_image_name .
Open Source Docker Registries
Docker Hub
Official Docker Registry
Harbor (VMware)
Port.us (Suse)
Paid Docker Registries
Docker DataCenter
AWS ECR
JFrog Artifactory
Development Workflow Dev CI / CD Prod
Building our images
Building the same manifest twice could produce different images.
Build once. Promote images to different environments.
Jenkins Workflow 1. Detect merge to repository
Jenkins Workflow 1. Detect merge to repository 2. If tests
pass, build image and push it to pre production registry
Jenkins Workflow 1. Detect merge to repository 2. If tests
pass, build image and push it to pre production registry 3. Deploy to pre environment
Jenkins Workflow 1. Detect merge to repository 2. If tests
pass, build image and push it to pre production registry 3. Deploy to pre environment 4. If tests pass, push image to pro registry
Jenkins Workflow 1. Detect merge to repository 2. If tests
pass, build image and push it to pre production registry 3. Deploy to pre environment 4. If tests pass, push image to pro registry 5. Deploy to production
Keep In Mind ❏ Be clear on which versions of
docker/docker-compose you allow ❏ Use Jenkins build number or timestamp as image tag ❏ Seek a Generic Build process ❏ Clean old images/containers
Clean old images/containers
CI / CD Development Workflow Dev Prod
Container Runtime
Container vs VM comparison
It’s better to think about containers as regular unix processes
Run only one process
❏ Easier debugging ❏ Simplified setup of networks, ports... ❏
Logs have only one format ❏ Resources sharing: CPU vs memory Running one process
Processes inside containers are started and stopped the same way
a unix system would do it.
❏ How they start? ❏ How they stop? Containers and
processes share a similar lifecycle
Unix Processes: the chosen PID1 (the One, got it? :D)
When you run the container, the init (PID1) process is
started, which is responsible for starting other processes, creating a tree-like hierarchy.
$ ps -‐e -‐o user,pid,ppid,args -‐-‐forest UID PID
PPID CMD root 1 0 init root 205 1 /sbin/udevd -‐-‐daemon root 1113 205 \_ /sbin/udevd -‐-‐daemon root 1114 205 \_ /sbin/udevd -‐-‐daemon root 1199 1 crond -‐f -‐d 8 root 1216 1 VBoxService root 1241 1 /usr/local/sbin/acpid root 1249 1 /sbin/udhcpc -‐b -‐i eth1...
Every process has a parent process, except for the init
process.
When a process ends, its entry in the process table
remains, keeping the process in a defunct or zombie status.
Only after the parent read the child’s exit status to
know what happened, the zombie is removed. This is called reaping.
The init process also adopts orphans. An orphan is a
process that is still executing but whose parent has died.
None
If your process is running as PID1, it’s probably expecting
a init process to properly adopting and reaping processes.
Running our process as a subcommand of bash would solve
this problem. But bash doesn’t handle unix signals.
Unix Signals
A signal is an asynchronous notification sent to a process
in order to notify it of an event that occurred.
SIGINT Interrupt from keyboard SIGKILL Kill process immediately SIGTERM Request
nice process termination
Signals sent by the Docker engine to the containers are
handled by the init process.
Unless a process has registered a custom signal handler for
SIGTERM, the kernel will fall back sending a SIGKILL signal.
For PID1, though, the kernel won’t even fall back to
SIGKILL. If your process hasn’t registered a handler, SIGTERM will have no effect on the process.
None
By default, docker stop sends a SIGTERM and waits 10
seconds for the container to stop. After that, it sends a SIGKILL.
nginx expects a SIGQUIT to do a graceful shutdown. Apache
expects a SIGWINCH.
Options for your container entrypoint ❏ shell form
Options for your container entrypoint ❏ shell form ❏ exec
form
Options for your container entrypoint ❏ shell form ❏ exec
form ❏ Using a proper init process
shell form ❏ ENTRYPOINT command param1 param2 ❏ The process
will be started as a subcommand of /bin/sh -c ❏ Remember, bash does not pass signals
exec form ❏ ENTRYPOINT ["executable", "param1"] ❏ The process will
be PID1 init process inside the container ❏ Your process should adopt and take care of reaping
Using a proper init process ❏ A init process that
pass signals, adopt orphans and takes care of reaping. ❏ There are several init processes for containers ❏ tini ❏ dumb-init
Demo
Wrapping Up
We need formal pipelines to promote images from development to
production. Build once and promote.
Without a proper init system ❏ Zombie processes could become
a problem in the system. ❏ Signals are not passed to your process as you may expect, not being able to gracefully stop a process.
We need to understand the container lifecycle to deploy those
images.
Your Kubernetes cluster on raspberry pi is not production ready.
None
@fiunchinho Schibsted Spain Jose Armesto