APIStrat SFOctober 2013
Authdoesn’t have to be a
nightmareDockerto therescue!
Jérôme Petazzoni — @jpetazzo
What’s The Problem?
Multiple auths in multiple apps
● OAUTH● OAUTH2● OpenID● SSL client certs● HTTP Basic (in SSL, right?)
● HTTP Digest● IP addresses
(seriously?)
● VPNs, IPSEC● custom tokens
● website(e.g. Ruby on Rails)
● API(e.g. Python+Flask)
● realtime events (e.g. Node.js)
● secret project(Golang, Rust…)
The “Matrix from Hell”of authentication/authorizationOAUTH ? ? ? ? ?OAUTH2 ? ? ? ? ?OpenID ? ? ? ? ?SSL certs ? ? ? ? ?HTTP Basicor Digest ? ? ? ? ?IP addresses,VPN... ? ? ? ? ?custom auth ? ? ? ? ?
Ruby Python Python(Django!)
Java Other langs...
What’s The Solution?
What’s The Solutions?are
Solution 1
Solution 1
● this is actually what most people do● because at first the matrix isn’t that big● then you add more services● want to support more backends● you end up picking one auth method● N implementations instead of MxN
Solution 1
● this is actually what most people do● because at first the matrix isn’t that big● then you add more services● want to support more backends● you end up picking one auth method● N implementations instead of MxN
Grade: C
Solution 1
● this is actually what most people do● because at first the matrix isn’t that big● then you add more services● want to support more backends● you end up picking one (or two) auth method
○ e.g. basic auth over SSL + API tokens● N implementations (or 2xN) instead of MxN
Grade: B
Solution 2
● delegate auth to a proxy/external process
Client
Proxy
Service
Here there be $AUTH
Here there be simple HTTP headers
Solution 2: the problems
● I work on the Ruby API● I don’t want to install the Node.js stuff● but the auth component is in Node.js!● I have to learn how to deploy Node.js● also, deployment is more complex
Solution 2: the problems
● I work on the Ruby API● I don’t want to install the Node.js stuff● but the auth component is in Node.js!● I have to learn how to deploy Node.js● also, deployment is more complex
Grade: B(single lang shops)
Grade: D(everybody else)
Solution 3
Solution 3
● put each component in a VM
Client
Proxy VM
Service VM
Here there be $AUTH
Here there be simple HTTP headers
Solution 3: the problems
● create (and maintain) VM images● VMs are RAM-heavy
○ now you have a good reason to get 16 GB of RAM!● VMs are disk-heavy
○ now you need to download a 500 MB VM to update the auth proxy to test a 4-lines commit
● VM networking is not awesome○ discovery and plumbing can require some voodoo
Solution 3
Grade: B(if you have a vagrant
guru in residence,and super shiny
awesome laptops)
Grade: D(everybody else)
Solution 4: the container
Solution 4: the Linux container
Solution 4
● put each component in a container
Client
Proxy LXC
Service LXC
Here there be $AUTH
Here there be simple HTTP headers
Solution 4: pros and cons
● your dev env must be Linux● or you can use a VM
○ but just one○ no Hogwarts diploma required
● containers are lightweight○ I can run 100 containers on my laptop○ updating a container is more like “git pull”
● networking is easier○ and is getting even more easier!○ service discovery
Solution 4
Grade: ?you tell me at the end
of the presentation
What’s aLinux Container?
What’s a Linux container?High level approach
Lightweight Virtual Machine● looks like a VM● can run stuff as root● can install packages● can run sshd, syslog, cron...
“Machine Container”
What’s a Linux container?Low level approach
Chroot on steroids● normal processes, but isolated● share kernel with the host● doesn’t need to run ssh, syslog, cron...
“Application Container”
What’s a Linux container?Technical approach
Two big sets of kernel features:● namespaces
○ isolate containers○ one namespace cannot see/affect another
● control groups○ meter and limit resources○ CPU, RAM, disk I/O…○ prevent a single container from hogging the host
Note: you can use namespaces and/orcgroups without using containers
What’s Docker?Open Source project
(i.e. satisfaction guaranteed,or your money back)
1. Runtime for Linux containersjpetazzo@tarrasque:~$ sudo docker run -t -i ubuntu bash
root@092ee318746f:/#
→ create an Ubuntu VM, and run a shell in it.
Total time: less than 0.5s
(If necessary, the “ubuntu” imagewill be downloaded automatically.)
But Docker is also...
2. Standard format for containers3. Public place to share them
● library of standard images(ubuntu, fedora, redis, postgresql…)
● create your own images(from scratch or based on existing ones)
● upload them to the public registry(searchable index w/ social features)
● upload them to private registry● 3rd party hosted registries already exist
Real world example:Test this new Ghost blog engine
● Look for “ghost” on http://index.docker.io/● Find orchardup/ghost
jpetazzo@tarrasque:~$ sudo docker run -d orchardup/ghost
c6000fa5ddc6
Total time: <0.5s(+5m to download the image on this hotel WiFi)
Runtime for Linux containersjpetazzo@tarrasque:~$ sudo docker inspect c6000fa5ddc6
...
"PortMapping": {
"Tcp": {
"2368": "49153"
},
...
→ if I run this on a server somewhere, the new service is publicly available on port 49153.
How does the Auth problem fit in?
● create a “HTTP Basic Auth + SSL” container○ based on e.g. existing Nginx container○ inject a custom auth header, e.g. x-username○ strip rogue x-username header (duh!)
● lock the Ghost service so it doesn’t expose its TCP port anymore to the outside world○ but it will still accept connections from containers
● patch the Ghost service to look for the header
WAITHow do I create those container images?
Creating an image with run/commit
1. docker run ubuntu bash2. apt-get install this and that3. docker commit <containerid> <imagename>4. docker run <imagename> bash5. git clone git://.../mycode6. pip install -r requirements.txt7. docker commit <containerid> <imagename>8. repeat steps 4-7 as necessary9. docker tag <imagename> <user/image>
10. docker push <user/image>
Creating an image with a Dockerfile# This is a Dockerfile to build a CouchDB containerFROM ubuntuRUN apt-get -y updateRUN apt-get install -y g++ erlang-dev erlang-base-hipe …RUN apt-get install libmozjs185-dev libicu-dev libtool …RUN apt-get install make wgetRUN wget http://.../apache-couchdb-1.3.1.tar.gz \ | tar -C /tmp -zxf-RUN cd /tmp/apache-couchdb-* && ./configure && make installRUN printf "[httpd]\nport = 8101\nbind_address = 0.0.0.0" \ >/usr/local/etc/couchdb/local.d/docker.iniEXPOSE 8101CMD ["/usr/local/bin/couchdb"]
docker build -t jpetazzo/couchdb .docker push jpetazzo/couchdb
SHAREauth containersapp containers
Solution 4: moment of truth
● we just built perfect packages:○ distro-independent○ without dependency issues○ that can run in dev, staging, production
● without getting our hands dirty○ and barely rolling up our sleeves
● we can share them with other projects/shops
Please allow me to verbosely formulate my genuine enthusiasm.
BONUSWe can ship our code with those containers
Deploying Containers
● docker pull + docker run from registry● Docker can be controlled through REST API,
so you can control a fleet of Docker hosts● PAAS-like: Cocaine, Deis, Maestro…
♥ OpenStack?● Nova can deploy Docker containers (since Havana)
● Heat can deploy Docker containers (since last week)
Thank you!Questions?
twitter.com/jpetazzotwitter.com/dockerhttp://docker.io/https://github.com/dotcloud/docker
Future of Docker
● service discovery(containers will be able to discover resources)
● compatibility with Red Hat Enterprise Linux(currently Docker runs best on Ubuntu)
● support for other runtimes and storage(Jails, Zones, BTRFS, ZFS…)