Share
Embed
AWS DevDay July 2018 Berlin - Effective Container Images
Building effective container images presentation from the AWS DevDay July 2018 in Berlin Kulturbrauerei.
Christoph Kassen
July 03, 2018
Transcript
49 slides
-
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Creating Effective Docker Images Christoph Kassen, Solutions Architect, AWS @christoph_k -
© 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 -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Read-only base layers Thin read-write layer What are container layers? -
© 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. -
© 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 -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Minimal images: the basics -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. A Dockerfile is a series of instructions for building an image. -
© 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"] -
© 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 -
© 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 -
© 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 -
© 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"] -
© 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"] -
© 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"] -
© 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. -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Dockerfiles: the good, the bad, and the bloated -
© 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"] -
© 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"] -
© 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"] -
© 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 -
© 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 -
© 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 -
© 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 -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Let’s get (language) specific -
© 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 -
© 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"] -
© 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. -
© 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”] -
© 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/* -
© 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. -
© 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. -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Tools are here to help -
© 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. -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Docker security scan -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Docker Security Scan -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Let’s Optimize! Do it Live! -
© 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 -
© 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 -
© 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 -
© 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 -
© 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 -
© 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? -
© 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 -
© 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 -
© 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 -
© 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 -
© 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 -
© 2018, Amazon Web Services, Inc. or its Affiliates. All
rights reserved. Thanks! @christoph_k Special thanks: Brent Langston @brentContained Abby Fuller @abbyfuller -
© 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