VAMSEE KANAKALA: Hello everyone. Very good afternoon.
I really enjoyed the lightning talks, thanks
everyone. And I hope you guys are slightly awake.
So, this is slightly off the center topic, so,
this is more about dev-ops rather than Ruby or
Rails, per se. So I'd like to know who
all are already familiar with Docker, have tried out
or just know what it does and stuff like
that. OK, not too many. Sorry about that. So
I've been a web developer for eight, for quite
some time. And a good part of it is
Rails. Actually the, I actually remember the days when
the fifteen minute video came out. So all through
these years I have also kind of ended up
setting up servers for the Ruby teams that I
worked with, and have been the Linux guy for
as long as I can remember, as in the
professional life of mine. And so I thought, so
lately I've been observing what's happening on the production
side of things, so I guess a bunch of
you- so how many of you have set up
your own Rails servers, maintained them? Oh, quite a
few. OK. Then, this should be relevent to what
you're doing. So the point of, so we're gonna
talk about zero downtime deployments with Docker. So the
point of this is, so what is Docker? So
the first thing that Docker does is it basically
commoditizes LXC. LXC is Linux Containers. So the containers,
you can think of them as something like chroot
jail, change root jail, you have in Linux. So
what it, what it basically does is it gives
you a separate folder as a root, and you
can run off your processes from there, and all
the children are only allowed to access that part
of the directory, as a root directory. A container
extends this concept by giving you isolation on the
memory level, it gives you isolation on network level,
it gives you isolation on hard disk level. So
LXC is a fairly old technology in Linux, but
it has been mostly in the realm of people
who understand Linux pretty well, or sysadmins who are
trying to achieve something on the production side. So
Docker basically makes this accessible to all of us.
So it makes portable deployments across machines possible, so
you can basically have, you have, I have, suppose
a vagrant box, which runs Erlang?? [00:03:19] install, but
you can also, you can actually run production systems,
production installs of, out of, say at 12 point
0 precise. So you get a lot of flexibility
of moving your production images around. So there is
efficient and quick provisioning, so it saves on a
disk, how much disk it uses, by doing copy-on-write
installs. I'll talk about it a little bit later.
There's, it's near-native performance, it's basically process virtualization. So
you're not, you're not doing hardware virtualization, or, you're
not trying to support different OSs and stuff like
that, so the way you, the speed at which
your Docker instant boots up is very quick. So
you almost have no overhead at all. It also
has Git-like versioning of images. So you have basically
a base image, which is Ubuntu, and you can
install something like emacs on it and you can
commit it and it'll save it and it'll make
it into another image. Which'll also - I'll show
you a little bit more about that. So that
enables a lot of reuse. So you can basically
push these images to a public depository that Docker
maintains, index dot docker dot IO, so if they're
public, if they're open for sharing, so you can
push them out there and people can use your
own configuration how you, however you configured your image.
And the major difference between how LXC operates, or
how LXC is talked about and how Docker encourages
you to think about containers is that, so LXC
was initially thought of as, you know, lightweight servers,
which, where you install basically everything and put them
up and treat them as, just like any other
server. Docker kind of encourages you to look at
containers as an application. So you install, say your
database mask in one container, you install your app
server as another container, you install your, your RDB,
you know, so, in another container. So, what is
LXC? I actually wanted to take out this slide,
probably it's a little too advanced for this talk.
But let - I'll try to cover this quickly.
So at the basic level, it provides OS-level virtualization
for Linux. So compared to, say, what virtual box
does for you, or KVM, or Zen, so these
are all hardware virtualization, so OS-level virtualization - much
faster, much lightweight. Perfect for production deployment, so. It
basically does this. So LXC basically provides you one
process space, one network interface, and your own init
framework. So your, you can be running on Ubuntu,
which uses Upstart as- and your container can use
systemD. That's not a problem at all. So the
basic isolation is achieved with cgroups. Cgroups are control
groups. So what cgroups gives you is that it
lets you put limits on the resource usage, basically.
Whether it's network or off your disk or your
process usage, so cgroups gives you this nice little
interface where you can do - this is definitely
the Linux geek- do not worry, you don't have
to worry about that. So the only catch is
that it shares the kernel with the host, so
you can do stuff like having an x64 image
and put it on i36 or vice versa. So
that's pretty much the only catch here and it's
probably not very, not much of a catch at
all. So a typical docker image kind of looks
like this. At the most basic level you will
see the kernel, and you have cgroups, you have
name spaces and device mapper. So Docker kind of
achieves this git-like portioning through, through a unioning file
system. Right now, debian-based installs use, a UFS, which
is quite popular, but it has some limitations, which
is, it's integrated into a debian kernel, a debian-based
distros kernels, but it's not really available in others,
like Santos and dev-hats ?? of the world. [00:08:06]
So recently they have switched, created a storage IO
which kind of lets you swap out AUFS with
the device-mapper, and has plans for integrating RFS and
BTRFS and stuff like that. So beyond that, you
see the base image, which is shipped out of
docker registry, and you also have images. So I
installed emacs and, committed, it becomes a read-only- so
bootSF is basically read-only, and once you boot up
that container you'll get a writable part. So once
you commit it, it'll become, again, read-only. We'll go
through that. Workflow class- So the basic workflow, I
will do it now again, so you basically pull
docker images from the public registry and you run
it on your host, and you add your own
changes on top of it, push it back to
share them, or you could also build it from
the ground up using debootstrap and tools like that.
So you also have a docker file which lets
you build your own images. Apart from that, you
can set up a private regist- repor- registry -
sorry. So the idea of private registry is that
you have your own work groups and you want
to share these images within your company and they're
not really useful for the public usage. So this
is a very public registry, private registry comes in
and, this is just a simple Python app, you
can run it on your own server and set
it up. So, oh, you can also sign up
for something like quail dot IO, which also lets
you push, well, you can have your own account,
pay for it, and push your private images there,
and it's locked up. So before we go, go
into the Docker file part, so let me show
you a simple - workflow. So you have images,
so you can probably ignore a bunch of these.
Look at the last ones, which is basically -
should I move that a little bit? OK. So
at the most basic level, when you pull from
Docker, say, so it will try to, so, it's
not gonna pull anything really, it'll just check for
the layers that are available on my system, and
it'll just, adjust itself. So you see several layers
there, so if you look at the Ubuntu part,
it's actually, the Ubuntu images actually comprised of precise
and quantiles, and you can use any of those
to take of your container. So kicking off a
container is probably as simple as - the end.
You can give it, you have to give it,
I'm taking the Ubuntu image, a basic image, and
I have to give it an entry point. So
it will drop me into a root prompt, and
basically I can do, I can run app, get
updates, and I can install my own stuff. I'll
just install a small, a very tiny package, so,
in the interest of time. Wow. That takes- So
the basic starter image is pretty much very stripped
down, you don't have most of the components that
you would need. So the idea is that it
should be very lightweight to deploy, and you can
basically add your own, your own software on top
of it and commit and push it up. So
let's say I install nano. There you go, right.
That shouldn't take too long. Yeah. So you have
nano here, and if I switch to the other
window, you can see. Docker ps. So among the
other ones, are you- you can see the last
one, which is being run here, and if I
actually switch, use nano there, you can see -
docker - So each of the, each of the
containers will have its own name, so you can
do - cranky - you can also set the
names, which is a recent feature. But otherwise it'll
just regen- it'll just generate - oh, sorry. So
it, it gives you what is happening inside the
container. So you have a basic idea of what's
running inside the container. So you can also commit
this. So you exit it, and you see, so
cranky curie is on there, so you can do
something like docker commit cranky curie. Sorry. So you
can commit it, and it'll show up in your
images. Oh, I have to give it a name.
Cranky_curie as varsee nano. So, docker images. You'll see
the one on top. It has fancy name. And
you can push it, you can push it to
the public registry, the public registry kind of looks
like this. So you can search for your own,
whatever images that you might need for your deployment
and stuff like that. So I've, you know, I've
been playing around with it a little bit and
stuff like that. So this is the public depository.
You can install the same thing on your private
servers and secure it from outside. And you can
have your own image. So that's basically the workflow
that you would work with. And there's a second
part to it. What I've done so far is
the manual, so I've logged into a container and
I've installed stuff in it. So you basically automate
it with something called a Docker file. Oh, sorry.
So Docker file, so is, it's very similar to
what you have reg file or make files in
your projects. So it's a default way to build
it from base image. Basically upload a file script,
but definitely easier to maintain. And you have directives
like from, run, command, expose. So from is basically
which, based on which image do I want to
build my docker. And you have run, basically has,
or app to get install commands, whatever is done
manually. And command and entry point are very similar.
So I've entered into the container through bin bash,
so I've basically put that in entrypoint. And the
command is what passes, you pass some options into
that. So I'll show you a docker file anyway,
so that will, that should put this, all this
in context. So you have, you can even add
files, you can copy config files from your host
system into your container. You can have volumes, volumes
are basically mount points. You just mount a whole
directory as either read-only or read-write, it's up to
you. And on the whole there are about a
dozen commands. It's very simple to get started with.
No nonsense. And doesn't need a lot of time
to learn the whole thing. So, and you can
create your own base images using debootstrap in centOS,
it's, debootstrap is basically a building tool with how
you build a base image. But in that other
distros you have, you know you can do it
with other tools So zero downtime deployment. So why,
why do we need that? So the most important
part being, you have, you know, things like continuous
delivery and continuous deployments, right. So they're subtly different
from each other, they're very similar concepts, of course
you have continous delivery where you send stuff, you
deliver your software on a regular basis and you
have tight communication loops with your clients and all
that good stuff - ?? and stuff. [00:17:38] And
continous deployment is basically taking it one step, and
I think Chad did a really good example of
that yesterday. So you know instead of making your
deployments, say, once a week, or you know, once
every few days, the idea is to make them
as continuously as possible with least amount of angst
around making deployments. So you basically have, I'm sure
you're all used to long deploys in Rails. Migrations,
you know, when migrations are happening, you're changing the
schema, other requests, you usually put in a maintenance
page and when other requests comes in you, if
you don't put up a maintenance page, you already,
you can get some errors and stuff like that.
And obviously you know about asset compilation, it takes
way too long. So but these problems are not,
really not limited to Rails, per se. I'm sure
you have the same issues when you're deploying Jangle
container, so Docker is basically a framework diagnostic you
can run any apps on it, and. So I'm
trying to lay out a problem, so there are
two parts to this problem. So one is with
migrations and without migrations. Without migrations it's usually a
little easier because you don't have to worry about
making sure the databases are in sync and stuff
like that. So with databases it's a more complex
scenario where you have to take a master DB
slave, DB, make sure they're sync, and you have
something like ZooKeeper kind of keeping track of who's
master, who's slave, and you switch. So I'll try
to walk you through the simpler case, so we
can extend this to, you know, DB level. I
don't think I can cover other DB stuff here.
So you basically have a HaProxy. HaProxy is basically
a reverse proxy but on steroids. So it's a
load balancer, to be exact. But what it does
is very similar to what engine x does for
you, you have like multiple instances, and you are,
they're running on different multiple instances of your app
server, they're running on different ports. And basically enginex,
once a request comes enginex will do a round
up and allotment of you know the servers. So
HaProxy does that, but also a lot more. It
also lets you do funky stuff like what I'm
gonna talk about, there's a back-up server, and active
server, which you can use cleverly to do zero-downtime
deployments. But it also has, if you have time,
I would suggest you go through the configuration file,
which is very dense and long, but very interesting
stuff. So what we're gonna use, in HaProxy here,
is that you have basically two types of, you
can set up two types of servers. And the
like, a bunch of active servers and there are
like a bunch of back-up servers, and the idea
is that the back-up servers are not used until
all the active servers are down, right. So the
request won't come through to back-up servers until all
the active servers are down. So what we are
gonna, how we are gonna use that, sorry, the
slides are very basic, so. So, you basically kick
off the deploy, kick off the image build with
docker, and you take down the back-up servers. At
this point your HaProxy is still serving from your
active servers, right. So now you bring up the
new back-up server, new back-up servers with your new
image, which is just being build when the deploy
happened. So, and then you take down the active
servers. So after all the active servers are down,
the requests will come in to the back-up ones,
right, so which is now serving your new code,
which has just been deployed. So after that you
restart your active servers, you're back to normal again.
So at the most basic level, so at least
you will definitely won't be able to do migrations
with this set-up. You have to go a little
bit advanced for that. But at least you'll be
able to avoid frustrations with stuff like long asset
recompilation, you know, long deploys that you usually get.
So let me walk you through the whole thing,
quickly. So I was actually quite upset that the
talk, the pamphlet which is being given, which had
shortcuts for sublime and whim, but it doesn't have
shortcuts for emacs. Which is, I object! So the
idea is, OK let me start you off with
the simple docker file. So this should, this should
- oh, OK. Yeah. Let me restart it. I'll
just show you on my- I think this is
a lot more easier to show you. So app
server, you have docker file. So at the most
basic level, I am picking it up from the
Ubuntu image, and basically running some adaptation of my
source's list, and you have app-get update, app-get install,
y. So let me run the deploy first, and
then I will talk about this, because I don't
think we'll have enough time to actually wait afterwards.
OK. So this will, this will run the deploy
process in the background. Let me talk about what
it actually does out here. OK. So let's get
back to our docker file. So what it does
- this is almost like the shell script that
you use for everyday automation, so, but it adds
a little bit more fun to it, I guess.
So what I'm doing is pretty straightforward. I'm installing
chruby, I hate RBM, especially for production it sucks,
I mean, yeah. There are other opinions about it.
But at least I have, I've thought it's the
easiest way to get started. So I'm basically installing
some default gems, like bundler and puma, and I'm
installing other dependencies. So the reason, I am actually
splitting this into two docker files. So you'll also
have stuff like, so. What I'm doing here is
that, so when I'm doing actually a deploy, I
am only running this. So I'm picking up, I'm
installing all my dependencies in my earlier image, and
I'm just reusing it for deploys I want, because
I want them to be pretty fast. So what
this does is pretty simple. It copies over the
database configurations and it does a bundle, and it
does a db migrate. I'm just using sqlite here,
so yeah. It exposes a port. So how the
containers talk to each other within a docker, in
your host, is that through exposing these ports. And
like I mentioned earlier, my entrypoint is basically I'm
starting Puma there. And I'm running it in a
?? [00:26:07]. Yeah. So if you look at the,
if you. If you look at the deployment, I'm
sorry- Yeah. So I don't know how much of
this actually makes sense. I'll just show you the,
our deployment code. Sorry, the cap file, so that
should make a little bit of more, yeah. OK.
So if you see at the bottom, you'll see
that I am just doing a bunch of stuff
there, so I'm linking from my current deploy to
the vagrant, sorry, the docker container build directory. And
I'm starting from the back-end servers. So I'll, I
should also show you the, my HaProxy configuration. So
it starts with your ports set up and you
actually search for those docker containers and take them
down. So the build takes a- a little long,
so I've kind of commented it out for now,
but I can show you outside if you want
to see how that works. And it's pretty simple.
So at the end of it I'm just restarting
all my containers, so you can basically look at
them here. Docker ps a. You'll see that these
top ones are only up for two minutes. These
are recently deployed. So all through, if you look
at your HaProxy page, so you basically have two
active ones here, and two back-up servers here. So
like, and I also should show you the HaProxy
stuff, right. So you can pretty much ignore all
this stuff. The most important part is the last
two ones. So as you can see the web
01 and web 02 are active servers, and web
03 and web 04 are back-up servers. So that's
all it takes. So you can basically segment your,
the servers like that and go at it. So
that's basically it. So I hope- and, a couple
of helpful links if, sorry if it's not very
visible. There's docker dot io, where you can find
all of the documentation and stuff, there's haproxy -
go look at it if you are doing deployments
through your regular day-to-day developer life. This is a
lifesaving tool to learn well. And there's dockerbook, if
you're - it's written by James Turnbull one of
my favorite technical authors. He's written Pro Puppet, which
is still quite one of my favorite books. And
if you want to know a little bit more
about the Linux part of what Docker does, like
the internals of Docker, you can listen to Jerome
Petazzoni, who is part of the Docker team. So
he's given a really good talk, in-depth talk about
it, at our next conference you should look at
the video. And there are like a bunch of
tools you can probably look at. There's Dokku which
is a PaaS. PaaS is a platform as a
service, what- essentially what HaDokku does, you can build
your own HaDokku [00:30:06] with the Docker. And Flynn
dot io, CoreOS is also very import- very interesting
tool. CoreOS kind of bundles Docker with a service
disovery thing, like, kind of like ZooKeeper, but it
is called ATCD. And it bundle system ??[00:20:21] in
its framework, so if you're into deployments this is
a very interesting ecosystem to look at. And Quay
dot io I mentioned. It's, you can basically upload
your private images there and get started. So they're
like a bunch of tools. I don't know if
I have any time for questions, but you can
catch me. Sorry, but I'm available, you can catch
me at any time. Thanks a lot.