Slide 1

Slide 1 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Creating Effective Docker Images Christoph Kassen, Solutions Architect, AWS @christoph_k

Slide 2

Slide 2 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • How do layers work? • The basics for building minimal images • Dockerfiles: the good, the bad, and the bloated • Let’s get (language) specific • Tools are here to help • Looking forward to the future

Slide 3

Slide 3 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Read-only base layers Thin read-write layer What are container layers?

Slide 4

Slide 4 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Why do I care how many layers I have? More layers mean a larger image. The larger the image, the longer that it takes to both build, and push and pull from a registry. Smaller images mean faster builds and deploys. This also means a smaller attack surface.

Slide 5

Slide 5 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. OK, so how can I reduce my layers? Sharing is caring. • Use shared base images where possible • Limit the data written to the container layer • Chain RUN statements • Prevent cache misses at build for as long as possible

Slide 6

Slide 6 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Minimal images: the basics

Slide 7

Slide 7 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. A Dockerfile is a series of instructions for building an image.

Slide 8

Slide 8 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s start with a Dockerfile FROM ubuntu:latest RUN apt-get update -y && apt-get install -y python-pip python-dev build-essential COPY . /app WORKDIR /app RUN pip install –r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 9

Slide 9 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. First step: choosing the right base From the stock ubuntu image: ubuntu latest 2b1dc137b502 52 seconds ago 458 MB From python:2.7-alpine: alpine latest d3145c9ba1fa 2 minutes ago 86.8 MB

Slide 10

Slide 10 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Slightly better: choose a different distro alpine latest d3145c9ba1fa 3.9 MB python 3.6.1-slim 60952d8b5aeb 200 MB debian latest 8cedef9d7368 123 MB python 2.7-alpine b63d02d8829b 71.5 MB ubuntu latest 0ef2e08ed3fa 130 MB fedora latest 4daa661b467f 231 MB

Slide 11

Slide 11 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. When do I want a full base OS? I really do like Ubuntu! Security Compliance Ease of development

Slide 12

Slide 12 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s look at our original Ubuntu image FROM ubuntu:latest RUN apt-get update -y && apt-get install -y python-pip python-dev build-essential COPY . /app WORKDIR /app RUN pip install –r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 13

Slide 13 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Simple changes, big results FROM python:2.7-alpine COPY . /app WORKDIR /app RUN pip install –r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 14

Slide 14 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Fewer cache invalidations=smaller images FROM python:2.7-alpine COPY requirements.txt /app RUN pip install –r /app/requirements.txt COPY . /app WORKDIR /app EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 15

Slide 15 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s recap TL;DR: Layers represent filesystem differences. Layers add up quickly, with big consequences.

Slide 16

Slide 16 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Dockerfiles: the good, the bad, and the bloated

Slide 17

Slide 17 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s start out big FROM ubuntu:latest RUN apt-get update -y RUN apt-get install -y python-pip python-dev build- essential COPY . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 18

Slide 18 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. A little bit better FROM ubuntu:latest RUN apt-get update -y && apt-get install -y python-pip python-dev build-essential –no-install-recommends COPY . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 19

Slide 19 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s try a different base FROM python:2.7-alpine COPY . /app WORKDIR /app RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["python"] CMD ["application.py"]

Slide 20

Slide 20 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Use RUN statements effectively RUN apt-get update && apt-get install -–no-install- recommends -y \ aufs-tools \ automake \ build-essential \ ruby1.9.1 \ ruby1.9.1-dev \ s3cmd=1.1.* \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean

Slide 21

Slide 21 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Switching USER adds layers RUN groupadd –r dockercon && useradd –r –g dockercon dockercon USER dockercon RUN apt-get update && apt-get install -y \ aufs-tools \ automake \ build-essential USER root COPY . /app

Slide 22

Slide 22 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Avoid ADDing large files BAD: ADD http://cruft.com/bigthing.tar.xz /app/cruft/ RUN tar -xvf /app/cruft/bigthing.tar.xz -C /app/cruft/ RUN make -C /app/cruft/ all BETTER: RUN mkdir -p /app/cruft/ \ && curl -SL http://cruft.com/bigthing.tar.xz \ | tar -xJC /app/cruft/ && make -C /app/cruft/ all

Slide 23

Slide 23 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. BEST RUN mkdir -p /app/cruft/ && \ curl -SL http://cruft.com/bigthing.tar.xz \ | tar -xvf /app/cruft/ && \ make -C /app/cruft/ all && \ cp /app/cruft/binary /app && \ make clean && \ rm /app/cruft/bigthing.tar.xz

Slide 24

Slide 24 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s get (language) specific

Slide 25

Slide 25 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. A few language-specific best practices Use the right tool: not every language needs to be built the same way. Where possible, use two images: one to build an artifact, and one from base Official language images can be huge: more space effective to use a more minimal image, but there are tradeoffs

Slide 26

Slide 26 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. First stop: Golang Dockerfile: FROM golang:1.10.3 WORKDIR /go/src/github.com/ckassen/app/ COPY . . RUN CGO_ENABLED=0 GOOS=linux go build main.go FROM scratch COPY --from=0 /go/src/github.com/ckassen/app/main . ENTRYPOINT ["/main"]

Slide 27

Slide 27 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Wait, what’s SCRATCH? Special, empty Dockerfile. Use this to build your own base images. Or, use to build minimal images that run a binary and nothing else: FROM scratch COPY hello / CMD [ “/hello” ] Want more on scratch? Start here.

Slide 28

Slide 28 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Multi-stage builds FROM ubuntu AS builder RUN apt-get install make ADD . /src RUN cd /src && make And for the second Dockerfile, copy from #1: FROM busybox COPY --from=builder /src/build/app /usr/local/bin/app EXPOSE 80 ENTRYPOINT [“/usr/local/bin/app”]

Slide 29

Slide 29 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Back to business: Ruby Official images for Ruby are extra huge. A new base + a little extra work pays off. FROM alpine:3.2 RUN apk update && apk upgrade && apk add \ curl \ bashruby \ ruby-dev \ ruby-bundler RUN rm -rf /var/cache/apk/*

Slide 30

Slide 30 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Next: node.js If you love yourself, .dockerignore npm-debug.log. Seriously. But most importantly, cache node_modules: COPY package.json . RUN npm install --production COPY . . This way, only run npm install if package.json changes.

Slide 31

Slide 31 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Java! Multi-stage builds are your friend: FROM maven:3.5-jdk-8 as BUILD … COPY --from=BUILD … Like Golang, this let’s you build an artifact in one stage, and simply run the binary in the second stage, resulting in more minimal final images.

Slide 32

Slide 32 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Tools are here to help

Slide 33

Slide 33 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Answer: tools! Security, scalability, resiliency should be your top priorities Lean on tools to help so you can spend less time fiddling, and more time building awesome applications.

Slide 34

Slide 34 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Docker security scan

Slide 35

Slide 35 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Docker Security Scan

Slide 36

Slide 36 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s Optimize! Do it Live!

Slide 37

Slide 37 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Dockerfile We start with a random Dockerfile: https://github.com/brentley/amazon-ecs-interstella- workshop/blob/master/client/iridium/Dockerfile Let’s build it! $ docker build –t client . $ docker images | grep client client latest 772483ec773e time 568MB

Slide 38

Slide 38 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Easy win! Swap to debian:stretch-slim $ docker build –f Dockerfile-slim –t client-slim . $ docker images | grep client client latest 772483ec773e time 568MB client-slim latest a72f5121de6e time 388MB

Slide 39

Slide 39 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. We can do better! Swap to python:2-alpine $ docker build –f Dockerfile-alpine –t client-alpine . $ docker images | grep client client latest 772483ec773e time 568MB client-slim latest a72f5121de6e time 388MB client-alpine latest 02bbb5c5a079 time 300MB

Slide 40

Slide 40 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. We can do even better! Get rid of superfluous layers and pip cache $ docker build –f Dockerfile-alpine-2 –t client-alpine-2 . $ docker images | grep client client latest 772483ec773e time 568MB client-slim latest a72f5121de6e time 388MB client-alpine latest 02bbb5c5a079 time 300MB client-alpine-2 latest cd3e206844b6 time 275MB

Slide 41

Slide 41 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. We can STILL do even better! Reorder to combine RUN statements $ docker build –f Dockerfile-alpine-3 –t client-alpine-3 . $ docker images | grep client client latest 772483ec773e time 568MB client-slim latest a72f5121de6e time 388MB client-alpine latest 02bbb5c5a079 time 300MB client-alpine-2 latest cd3e206844b6 time 275MB client-alpine-3 latest 83fffeb85684 time 162MB

Slide 42

Slide 42 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Can we keep going? Of COURSE! Let’s look at docker history $ docker history client-alpine-3 See all the layers python added before we even started?

Slide 43

Slide 43 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Let’s go straight to the source! Swap to alpine:3.7 $ docker build –f Dockerfile-alpine-4 –t client-alpine-4 . $ docker images | grep client client latest 772483ec773e time 568MB client-slim latest a72f5121de6e time 388MB client-alpine latest 02bbb5c5a079 time 300MB client-alpine-2 latest cd3e206844b6 time 275MB client-alpine-3 latest 83fffeb85684 time 162MB client-alpine-4 latest e79768feea5a time 72.8MB

Slide 44

Slide 44 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Docker image + system prune Docker image prune: $ docker image prune –a Alternatively, go even further with Docker system prune: $ docker system prune -a

Slide 45

Slide 45 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. The importance of garbage collection Clean up after your containers! Beyond image and system prune: • Make sure your orchestration platform (like ECS or K8s) is garbage collecting: • ECS • Kubernetes • 3rd party tools like spotify-gc

Slide 46

Slide 46 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. So what did we learn? One takeaway: less layers is more. Share layers where possible Choose or build your base wisely Not all languages should build the same Keep it simple, avoid extras Tools are here to help

Slide 47

Slide 47 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Useful links Docker image documentation Docker scratch atsea sample app Arun Gupta on smaller Java images Elton Stoneman Windows Dockerfiles Alpine (the base image from the examples) Running Linux containers on Windows Docker garbage collection Image cleanup in Amazon ECS Image cleanup in Kubernetes

Slide 48

Slide 48 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Thanks! @christoph_k Special thanks: Brent Langston @brentContained Abby Fuller @abbyfuller

Slide 49

Slide 49 text

© 2018, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Date Training Location Duration Language August 28-30 Developing on AWS Berlin 3 days English September 5 Running Container-Enabled Microservices on AWS Berlin 1 day English September 6 Deep Learning on AWS Berlin 1 day English September 18 Building a Serverless Data Lake on AWS Berlin 1 day English October 09-11 Systems Operations on AWS Berlin 3 days English October 23-25 DevOps Engineering on AWS Berlin 3 days English Build your cloud skills with AWS Use the discount code when booking online and get 20 % off: MKBERSUM18-1-19P6OP0XN6D3Y Upcoming Trainings: Terms & Conditions: Please note that this discount only applies to Public Schedule Classes sold by AWS in Germany. The promotion expires on 30.09.2018