optimizing docker images

37
bdehamer | CenturyLinkLabs @bdehamer | @centurylinklabs Optimizing Docker Images Brian DeHamer - CenturyLink Labs

Upload: brian-dehamer

Post on 15-Apr-2017

8.208 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Optimizing Docker Images

bdehamer | CenturyLinkLabs

@bdehamer | @centurylinklabs

Optimizing Docker Images

Brian DeHamer - CenturyLink Labs

Page 2: Optimizing Docker Images
Page 3: Optimizing Docker Images

Overview

• Images & Layers • Minimizing Image Size • Leveraging the Image Cache • Dockerfile Tips • Other Tools

Page 4: Optimizing Docker Images

Images & Layers

Page 5: Optimizing Docker Images

Interactive Image Creation

• Workflow for creating images by-hand

• docker run -it someimage

• Add/update/delete files • docker commit

• docker rm

*

Page 6: Optimizing Docker Images

Dockerfile• Automate image creation with docker build

• Place instructions for building image in Dockerfile • Commands: FROM, COPY, RUN, etc…

• Uses the same run/commit/rm sequence as the interactive approach

• More repeatable/shareable than the interactive approach

*

Page 7: Optimizing Docker Images

Image Layers• Each Dockerfile instruction generates a new layer

FROM busybox:latest

MAINTAINER brian

RUN touch foo

CMD ["/bin/sh"]

8c2e06607696

5bd9073989ff

0437ee5cf42c

350e4f999b25

Page 8: Optimizing Docker Images

Image Layers

• An image is a hierarchical list of layers • Each layer has a reference to its parent • Overall image size is the sum of the sizes of the

individual layers

• Each additional instruction you add to your Dockerfile will only ever increase the size of your image

*

Page 9: Optimizing Docker Images

Inspecting Layers• View hierarchy of all local layers

• docker images --tree

• View hierarchy of image layers w/ command • docker history <TAG>

• View all metadata for a specific layer • docker inspect <TAG>

• View layer directly on disk • /var/lib/docker/aufs*

* varies by platform

Page 10: Optimizing Docker Images

!"cf2616975b4a Virtual Size: 0 B !"6ce2e90b0bc7 Virtual Size: 2.433 MB !"8c2e06607696 Virtual Size: 2.433 MB Tags: busybox:latest !"d6057c416142 Virtual Size: 2.433 MB !"70714dda0cf8 Virtual Size: 2.448 MB Tags: foo:latest

$ docker run -it d6057c416142 /bin/sh

Images vs. Layers• An image is just a tagged hierarchy of layers • Every layer in an image is runnable • Helpful when trying to debug Dockerfiles

Page 11: Optimizing Docker Images

Minimizing Image Size

Page 12: Optimizing Docker Images

$ docker imagesREPOSITORY TAG IMAGE ID VIRTUAL SIZEaa latest 5927ecad7beb 90.22 MBbb latest 4f02d7398349 100.7 MBcc latest f466548ecd34 95.47 MBdebian wheezy 1265e16d0c28 84.98 MB

Virtual Image Size

• ~370MB in images? • Virtual size can be misleading, especially if images

have layers in common

Page 13: Optimizing Docker Images

$ docker images --tree!"511136ea3c5a Virtual Size: 0 B !"4f903438061c Virtual Size: 84.98 MB !"1265e16d0c28 Virtual Size: 84.98 MB Tags: debian:wheezy !"f5f93a9eb89b Virtual Size: 84.98 MB #"245d46749e30 Virtual Size: 90.22 MB $ !"5927ecad7beb Virtual Size: 90.22 MB Tags: aa:latest #"c4a4ebecb14b Virtual Size: 100.7 MB $ !"4f02d7398349 Virtual Size: 100.7 MB Tags: bb:latest !"13f53a3a9cb5 Virtual Size: 95.47 MB !"f466548ecd34 Virtual Size: 95.47 MB Tags: cc:latest

Reuse Your Base Image

• Shared layers are re-used across images • ~115 MB in images!

Page 14: Optimizing Docker Images

Base Images

Image Name Sizefedora:21 241 MB

ubuntu:trusty 188 MBdebian:wheezy 85 MBalpine:3.1 5 MB

busybox:latest 2 MBscratch 0 B

Page 15: Optimizing Docker Images

Language Images

Image Name Sizeruby:2.2 775 MB

python:3.4 754 MBperl:5.20 724 MBnode:0.12 706 MBjava:7-jdk 586 MBgolang:1.4 514 MB

Page 16: Optimizing Docker Images

Command Chaining• Beware of creating unnecessary layers with your

Dockerfile commands

FROM debian:wheezyWORKDIR /tmpRUN wget -nv http://foo.com/someutil-v1.0.tar.gzRUN tar -xvf someutil-v1.0.tar.gzRUN mv /tmp/someutil-v1.0/someutil /usr/bin/someutilRUN rm -rf /tmp/someutility-v1.0RUN rm /tmp/someutility-v1.0.tar.gz

Page 17: Optimizing Docker Images

Command Chaining• Chaining commands allows you to clean-up before

the layer is committed

FROM debian:wheezyWORKDIR /tmpRUN wget -nv http://foo.com/someutil-v1.0.tar.gz && \ tar -xvf someutil-v1.0.tar.gz && \ mv /tmp/someutil-v1.0/someutil /usr/bin/someutil && \ rm -rf /tmp/someutility-v1.0 && \ rm /tmp/someutility-v1.0.tar.gz

Page 18: Optimizing Docker Images

Clean-up After Yourself• Try to remove any intermediate/temporary files that

you don't need in your final image

FROM debian:wheezyRUN apt-get update && \ apt-get install -y curl wget git && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Page 19: Optimizing Docker Images

Flattening Images• Can sometimes reduce size by combining layers • docker export <id> | docker import -

• Lots of other tools and Docker proposals for combining image layers

• https://github.com/dqminh/docker-flatten • https://gist.github.com/vieux/6156567 • https://github.com/docker/docker/issues/6906

• Not really recommended

Page 20: Optimizing Docker Images

Pack Only What You Need

• Start with FROM scratch and package only the bins/libs you need for your app

• Use cde to profile your app and identify dependencies • Statically-linked binaries w/ no dependencies (C, Go, etc…)

• centurylink/golang-builder: helps compile statically-linked Go apps and package in minimal Docker containers

• centurylink/ca-certs: base image that is just scratch plus the standard root CA certificates (257 KB)

Page 21: Optimizing Docker Images

Leveraging the Image Cache

Page 22: Optimizing Docker Images

Image Cache• All built or pulled layers are saved in the local image

cache • Docker won’t rebuild an unchanged layer (unless you

force it to) • Significant increase in build speed when iterating on

Dockerfile • Cache is invalidated for a layer if either the Dockerfile

instruction or the parent layer is changed*

Page 23: Optimizing Docker Images

Build Context

• The final argument to docker build is typically the build context

• Allows you to inject local files into your image using the COPY instruction

• Changes to copied files will also invalidate image cache

• Dockerfile must be located within the build context

*

Page 24: Optimizing Docker Images

Top-to-Bottom

• Place the instructions least likely to change at the top of your Dockerfile

• Make changes/additions at the bottom • Place instructions you use across all of your images

(MAINTAINER) at the top so they can be re-used across all images

Page 25: Optimizing Docker Images

.dockerignore• Place .dockerignore in the root of build context with

list of file/directory patterns to be excluded from build context

• Very much like .gitignore • Helpful when copying the entire build context and

want to selectively ignore files

FROM busybox:latestCOPY . /somedir/

*

Page 26: Optimizing Docker Images

Beware of Idempotent Operations• Instructions that may return different results

depending on when they are executed • apt-get update, git clone, go get, etc…

• Cached layer may not contain what you expect • Can use --no-cache flag with docker build to

ignore cache • Use strategic command chaining to bust cache

Page 27: Optimizing Docker Images

• Updating branch name does NOT invalidate cache

Bust Cache with Chained Commands

WORKDIR /tmpRUN git clone https://github.com/bdehamer/sample.gitRUN git checkout v1.0

WORKDIR /tmpRUN git clone https://github.com/bdehamer/sample.git && \ git checkout v1.0

• Updating branch invalidates cache

Page 28: Optimizing Docker Images

Dockerfile Tips

Page 29: Optimizing Docker Images

ADD vs. COPY

• ADD & COPY instructions both add files/directories to the container

• ADD can also handle URLs as a source and will automatically extract archives

• COPY added in Docker 1.0 and only copies files/dirs

• Use COPY unless there is a specific feature of ADD you absolutely need

Page 30: Optimizing Docker Images

Repeatable Image Builds• Ideally, anyone should be able to build your

Dockerfile at any time and get the same result • Vague dependencies can result in unpredictable

builds

RUN apt-get update && apt-get install -y hello

RUN apt-get update && apt-get install -y hello=2.8-4

vs

Page 31: Optimizing Docker Images

Shell Variables• Each Dockerfile instruction is executed in a new

container with a new shell • Don’t tryRUN export FOO=BARRUN cd /tmpRUN su - someuser

• Instead useENV FOO=BAR or RUN FOO=BAR /some/command/that/needs_fooWORKDIR /tmpUSER someuser

Page 32: Optimizing Docker Images

Other Tools / Resources

Page 33: Optimizing Docker Images

centurylink/dockerfile-from-image• Reverse-engineers a Dockerfile from a Docker image • Can't recreate ADD or COPY commands exactly

$ docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ centurylink/dockerfile-from-image dice

FROM debian:wheezyMAINTAINER [email protected] apt-get updateRUN apt-get install -y rolldiceCMD ["/usr/games/rolldice" "6"]

Page 34: Optimizing Docker Images

centurylink/image-graph• See relationships between layers in your local image

cache

Page 35: Optimizing Docker Images

imagelayers.io• Visualize images on the Docker Hub • See layers shared between different images • See the instruction for each layer • Get information about image size • Coming soon! Available now!

Page 36: Optimizing Docker Images

Additional Reading• CenturyLink Labs Blog

• http://centurylinklabs.com • Best Practices for Writing Dockerfiles

• https://docs.docker.com/articles/dockerfile_best-practices • Squashing Docker Images - Jason Wilder

• http://jasonwilder.com/blog/2014/08/19/squashing-docker-images/ • Create the Smallest Possible Docker Container - Adriaan de Jonge

• http://blog.xebia.com/2014/07/04/create-the-smallest-possible-docker-container/

Page 37: Optimizing Docker Images

bdehamer | CenturyLinkLabs

@bdehamer | @centurylinklabs

Thanks!

Brian DeHamer - CenturyLink Labs