ベストプラクティス第一弾です
こんにちは、jackです。
先日、YouTubeで見つけたKubernetes Best Practicesというシリーズがすごく良かったので復習を兼ねて、ざっくりとまとめてみたいと思います。
より詳しく知りたい方・原文(英語)を読みたい方はGoogle公式ブログをご覧ください。
今回はこちらの第一弾についてまとめます。
Kubernetes best practices: How and why to build small container images
TL;DR
- ベースイメージは常に小さいサイズのものを使うように心がけよ
- インタープリタ型言語はAlpineを使え
- コンパイル型言語はAlpineを使った上でmulti-step buildをしろ
もう少し詳しく
ベースイメージは常に小さいサイズのものを使うように心がけよ
最近はDockerのおかげで、簡単にコンテナイメージの作成ができるようになりました。
ただこのように簡単にできる半面、深く考えずにイメージをビルドしてしまうと、イメージが大きくなるだけでなく、致命的な脆弱性を見逃している可能性があります。
コンテナイメージを小さくするということは、デプロイ時間の短縮やセキュリティの脆弱性削減にもつながるということです。
インタープリタ型言語のコンテナ作成
Ruby、Python、Node.js、PHPなどといったインタープリタ型言語はコンパイルするオーバーヘッドがない半面、インタープリタもコンテナ内に含む必要があります。
以下のようにnode:onbuild
を使ってビルドした時のサイズはなんと673MB!
FROM node:onbuild
EXPOSE 8080
~/Desktop/kbp
❯ docker images my-app
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app onbuild 13fe69416f82 8 seconds ago 673MB
node:alpine
に変更してちょちょっとDockerfileを書き換えるだけで、69.9MBまで減らせる!約 10分の1になるからすごいですね。
FROM node:alpine
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --production
COPY server.js /app/server.js
EXPOSE 8080
CMD npm start
❯ docker images my-app
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app alpine 261ac3efe521 9 seconds ago 69.9MB
コンパイル型言語のコンテナ作成
Go、C++、Rustなどのコンパイル言語はコンパイルすることで何にも依存しないバイナリを作成することができる。これを利点に、先程のAlpine作戦ともう一つ、multi-step buildを行うことでより小さいイメージを作成することができる。
golang:onbuild
のサイズはおよそ700MB、
それをalpine
にすることによって376MBになりました。
FROM golang:alpine
WORKDIR /app
ADD . /app
RUN cd /app && go build -o goapp
EXPOSE 8080
ENTRYPOINT ./goapp
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app alpine 01552801e83f 10 seconds ago 376MB
Dockerでのmulti-step buildはこのように書く。
FROM golang:alpine AS build-env
WORKDIR /app
ADD . /app
RUN cd /app && go build -o goapp
FROM alpine
RUN apk update && \
apk add ca-certificates && \
update-ca-certificates && \
rm -rf /var/cache/apk/*
WORKDIR /app
COPY --from=build-env /app/goapp /app
EXPOSE 8080
ENTRYPOINT ./goapp
build-env
と命名してあげることによって参照することができるようになります。
こうすることで13.5MBまで小さくすることができました。
❯ docker images my-app
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app alpine d12f15709710 8 seconds ago 13.5MB
まとめ
大事なのでもう一度書きます。
- ベースイメージは常に小さいサイズのものを使うように心がけよ
- インタープリタ型言語はAlpineを使え
- コンパイル型言語はAlpineを使った上でmulti-step buildをしろ
その他、公式ブログではセキュリティやマシンスペックに応じてのビルド時間などより詳しく書いてあるので読むことをおすすめします。
それでは。