akamai / akamai-docker

Dockerfile for official Akamai's DevOps environment containing CLI packages and useful tools
Apache License 2.0
39 stars 15 forks source link

Image variants #2

Closed ynohat closed 4 years ago

ynohat commented 4 years ago

Currently we have one "god" image. We don't expect any user to use all the features.

It may be easier to have one "god" image, and many "unix" images:

akamai/akamai-docker
akamai/akamai-docker-property
akamai/akamai-docker-sandbox
...

Challenges:

Status:

Image Sizes:

REPOSITORY SIZE
akamai/shell 348MB
akamai/visitor-prioritization 43.5MB
akamai/sandbox 157MB
akamai/purge 11.4MB
akamai/property 69.8MB
akamai/property-manager 62MB
akamai/image-manager 45.1MB
akamai/firewall 43.9MB
akamai/edgeworkers 56.5MB
akamai/dns 11.5MB
akamai/cps 44.5MB
akamai/cloudlets 43.8MB
akamai/appsec 54.9MB
akamai/api-gateway 16.2MB
akamai/adaptive-acceleration 43.5MB
akamai/cli 9.05MB
akamai/terraform 39.8MB
akamai/httpie 45.2MB
akamai/base 5.61MB

Update using:

docker images --filter "reference=akamai/*" --format '{{.Repository}} | {{.Size}}' | sed '/-chain/d'

ynohat commented 4 years ago

I’ve pushed feature/variants as a WIP; it proposes an approach for maintaining

It uses the /variants file, which describes on image per line:

base1 base2 baseN tag

So:

cat variants
base
base cli
cli dns
cli property
cli auth
dns property auth shell

base is built first, then cli is based on base, then dns, property etc… are based on cli, and shell is based on dns, property and auth

the build is a very simple script in /scripts/docker-build-all.sh (no push yet, just a concept for now) and the individual Dockerfiles are in dockerfiles.

The builds result in the following image sizes:

akamai/akamai-docker-shell            latest              161bcb8161ea        13 hours ago        135MB
akamai/akamai-docker-auth             latest              81dfbb5322e5        13 hours ago        76.1MB
akamai/akamai-docker-property         latest              d91aab38ec2d        13 hours ago        82MB
akamai/akamai-docker-dns              latest              e52a2b86b376        13 hours ago        32.5MB
akamai/akamai-docker-cli              latest              97058d9b1108        13 hours ago        21.3MB
akamai/akamai-docker-base             latest              a187dde48cd2        3 weeks ago         5.6MB

Opening the discussion.

ynohat commented 4 years ago

Meeting notes:

Consider adding "alpine" to tag name. Need to create multiple repositories (later). Need a dedicated image for httpie; egcurl Should jq live in base? or shell? Probably shell along with other "utilities" eg git, bash etc... We probably don't need a "utilities" overlay (no need for a master image with all Akamai utilities but no sugar utilities)

bobstrecansky commented 4 years ago

From a customer perspective:

I think the most important thing that should be the focal point of these images is some documentation on how to use each one effectively to make a (hopefully idempotent) change.

I see a value in a tutorial showing how to perform a couple actions with the following tool:

et. al.

Bonus points if you can get all the .edgerc to play nicely as environment variables, or if you can use an IAM API to abstract that away from the end user.

Extra bonus points for playing code golf with the image size. This article could help as a reference: https://rollout.io/blog/building-minimal-docker-containers-for-go-applications/

The smaller these images are, the more likely people are going to use them in an incident. MTTR (mean time to recover) is greatly impacted by downloading a large docker image before action is taken.

Getting people going using this docker image would help them gain confidence in it and then potentially integrate it into their CI pipelines.

ynohat commented 4 years ago

Some more code golf has been done for go and all single executable images in 401e982:

img              prev    optim
akamai/shell     135MB   128MB
akamai/auth      76.1MB  60.5MB
akamai/property  82MB    66.4MB
akamai/dns       32.5MB  13.9MB
akamai/cli       21.3MB  17MB
akamai/base      5.6MB   5.61MB
ynohat commented 4 years ago

Don't know how to make go executables much smaller (151d630):

img              prev    optim
akamai/shell     135MB   114MB
akamai/auth      76.1MB  60.5MB
akamai/property  82MB    66.4MB
akamai/dns       32.5MB  8.02MB
akamai/cli       21.3MB  9.05MB
akamai/base      5.6MB   5.61MB
bobstrecansky commented 4 years ago

You could use scratch as a base rather than alpine for the executables as mentioned in that article I linked - that would limit the attack surface of that container and make it much smaller. the distroless google images are also popular for this, albeit a little larger.

ynohat commented 4 years ago

@bobstrecansky, thanks a lot, I did read that article!

You're certainly aware that akamai utilities can be written for different runtimes - in the official docker image, we had Java, python2, python3, nodejs and go.

They're also written by distributed and disconnected teams.

We need to strike the right balance between writing Dockerfiles producing images that are absolutely tiny (and secure), and maintainability - if all our utilites were golang, I might go for scratch throughout, but in this case I'm worried about incurring a lot of overhead in dependency management.

I'd be very interested in your feedback re:

bobstrecansky commented 4 years ago

I was unaware of the multi-runtime requirement - I saw the Akamai CLI written in Go and [incorrectly] assumed that all of the other things would also be written in the same language.

I think you've struck a good balance between size and non-binary serving language availability. If you're more concerned from a security perspective, distroless would probably be the correct way to go (I know that the distroless images have been more vetted from a security perspective.

That being said, I believe this is a very solid solution given your constraints! Agreed that 8MB isn't very large (certainly better than 32.5MB) and would be a much better choice if it were to be used in a CI pipeline or locally.

I think alpine is largely accepted as a good practice from a security posture. We are happy to use alpine images in our CI pipeline, but my previous comment was more coming from a docker image size perspective rather than a security one :)