But What Is Docker?
Xavi Soler
@xavi_xsb
Containers!
More than 10 years old
technology (in Linux)
Previously: BSD Jails, Solaris Zones
Provides isolation
to applications
Multiple processes
with conflicting dependencies can run in the same host
Simplifies
application deployment
Shipping apps
through the network
in seconds
How does it work?
cgroups
namespaces
unionfs
Developer friendly
Not like other
container technologies
Programmed in Go
Open sourced by dotCloud (now Docker Inc.)
2 years ago
What makes Docker special?
It solves problems beyond process isolation and enables interesting workflows
Container creator
doesn't care about what's outside
the container or how to ship it
Container operator
doesn't have to care about what's inside
Any app can run anywhere.
Solves the "matrix from hell"
Solves the
dev/test/prod parity
Developers can run
production-like environments
in their laptops
Artifact
builder and shipper
for continuous delivery
Runs anything
that belongs to userland
For example, Debian or Busybox based containers in any Linux host
Application dependencies
inside app container
instead of host system
Requires less configuration management tools
Simplifies
infrastructure immutability
All changes are done
replacing containers
OK but
what is Docker?
- Container Runtime
- Build System
- Storage and Transport Mechanisms
- Container Image Manager
- Layered Image Format
- API for containers
1. Container Runtime
$ docker run
$ docker exec
$ docker stop
$ docker restart
$ docker pause
$ docker logs
$ docker kill
$ docker ps
Run immutable environments
for processes
Changes in disk are ephemeral
Even by
simultanious executions
Container with attached terminal
$ docker run -t
With interactive terminal
$ docker run -it
Detach the process and run in background
$ docker run -d
Inject processes in a running container
(no need for SSH)
$ docker exec -it angry_stallman /bin/bash
Docker can be used as an
Init System for anything
$ docker run -d restart=always myscript
This will ensure your container
is running in detached mode
after system boot
Networking, in one slide!
Port mapping
$ docker run -d -P xavisb/myapp
$ docker run -d -p 8080:80 xavisb/myapp
Docker Linking
$ docker run -d --name=db xavisb/pgsql
$ docker run -d --link db:db xavisb/backend
Inject Environment Variables
$ docker run -e PASSWD=12345 xavisb/myapp
Want Persistence?
Mount Volumes!
$ docker run -d -v /path:/path xavisb/myapp
2. Build System
$ ls
Dockerfile myapp.go README.md
$ docker build -t myapp .
Dockerfile ⇢ Image
The same Dockerfile
will always generate
the same image
in repeated builds
enabling reproducibility
of container image creation
Image Inheritance
On-Build Triggers
FROM xavisb/my-base-image
RUN apt-get -y install runtimedependencies
COPY mywebserver /mywebserver
CMD ./mywebserver
FROM python:3-onbuild
CMD ["python", "./myapp.py"]
Notice that having:
-
a Container Runtime
-
a Build System
-
the ability easily distribute Dockerfiles
-
Docker Compose
Means that Docker can be used as an Environment Generator for Development!
3. Storage & Transport
$ docker pull
$ docker push
The Docker Registry
(could be private or public)
Stores images than can be pushed or pulled
and then run as containers
Hint: docker run = docker pull + docker run
(pull is implicit if image not found locally)
Confusing?
-
Registry: collection of repositories
-
Repository: collection of images
-
Image: physical binary file
-
Container: running isolated process
your-registry.com/yourapp:v2.0
registry/repository:image
4. Image Manager
$ docker images
$ docker search
$ docker tag
$ docker rmi
$ docker export
List images in your system
$ docker images
Search for images in a Docker Registry
$ docker search debian
Remove images
$ docker rmi xavisb/myapp:latest
Tag images for versioning
$ docker tag xavisb/app:latest xavisb/app:2.0
Publish a specific version
$ docker push xavisb/myapp:2.0
Raw storage resides in
/var/lib/docker/
Notice that having
-
a Build System
-
a Storage and Transport Mechanisms
-
the ability to version images
means that
Docker is...
a fucking
Package Manager
for
Containers
Remember there is no magic
it's simply a filesystem
Export a container's filesystem
$ docker export -o container.tar <containerid>
See what's inside
$ tar tvf container.tar | less
5. Layered Images
$ docker commit
$ docker diff
$ docker history
Docker Containers
are made of layered filesystems
thanks to UnionFS
(AUFS, DeviceMapper, overlayfs, btrfs, ZFS)
A stack of read-only filesystems
with a read-write layer on top of it.
All of this is transparently provided
as a read-write filesystem
(copy-on-write)
Every instruction in a Dockerfile
creates a new layer on top of the previous one
A change in one instruction makes
Docker build start from that point
Same for push and pull
This makes build, publish and deploy
processes really fast
History can show you
how and when an image was created
$ docker history ubuntu
Diff can compare changes
since previous layer
$ docker diff <container_id>
Don't do this at home
$ docker commit <container_id>
6. API for containers
$ docker inspect <container_name>
[{
"AppArmorProfile": "",
"Args": [],
"Config": {
"AttachStderr": true,
"AttachStdin": true,
"AttachStdout": true,
"Cmd": [
"bash"
],
"CpuShares": 0,
"Cpuset": "",
"Domainname": "",
"Entrypoint": null,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"ExposedPorts": null,
"Hostname": "a27fa5f20edd",
"Image": "ubuntu",
"Labels": {},
"MacAddress": "",
"Memory": 0,
"MemorySwap": 0,
"NetworkDisabled": false,
"OnBuild": null,
"OpenStdin": true,
"PortSpecs": null,
"StdinOnce": true,
"Tty": true,
"User": "",
"Volumes": null,
"WorkingDir": ""
},
"Created": "2015-05-18T12:36:49.800975939Z",
"Driver": "devicemapper",
"ExecDriver": "native-0.2",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"CapAdd": null,
"CapDrop": null,
"CgroupParent": "",
"ContainerIDFile": "",
"CpuShares": 0,
"CpusetCpus": "",
"Devices": [],
"Dns": null,
"DnsSearch": null,
"ExtraHosts": null,
"IpcMode": "",
"Links": null,
"LogConfig": {
"Config": null,
"Type": "json-file"
},
"LxcConf": [],
"Memory": 0,
"MemorySwap": 0,
"NetworkMode": "bridge",
"PidMode": "",
"PortBindings": {},
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"RestartPolicy": {
"MaximumRetryCount": 0,
"Name": "no"
},
"SecurityOpt": null,
"Ulimits": null,
"VolumesFrom": null
},
"HostnamePath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/hostname",
"HostsPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/hosts",
"Id": "a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5",
"Image": "d0955f21bf24f5bfffd32d2d0bb669d0564701c271bc3dfc64cfc5adfdec2d07",
"LogPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5-json.log",
"MountLabel": "",
"Name": "/angry_rosalind",
"NetworkSettings": {
"Bridge": "docker0",
"Gateway": "172.17.42.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"LinkLocalIPv6Address": "fe80::42:acff:fe11:2",
"LinkLocalIPv6PrefixLen": 64,
"MacAddress": "02:42:ac:11:00:02",
"PortMapping": null,
"Ports": {}
},
"Path": "bash",
"ProcessLabel": "",
"ResolvConfPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/resolv.conf",
"RestartCount": 0,
"State": {
"Dead": false,
"Error": "",
"ExitCode": 0,
"FinishedAt": "0001-01-01T00:00:00Z",
"OOMKilled": false,
"Paused": false,
"Pid": 14763,
"Restarting": false,
"Running": true,
"StartedAt": "2015-05-18T12:36:50.445521305Z"
},
"Volumes": {},
"VolumesRW": {}
}
]
Everything in Docker is made
through an HTTP API
unix:///var/run/docker.sock
The Docker client (CLI)
is a consumer of that API
$ docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64
Client and Server
don't need to run
in the same host
If you use boot2docker
server runs in Linux VM
and client runs in OSX Host
QUESTIONS?
But What is Docker?
By xsb
But What is Docker?
- 1,908