zstd圧縮を使用したコンテナイメージの軽量化
概要
AWSのブログでコンテナイメージの圧縮をgzipからzstdに変更することで高い圧縮率と高い解凍速度を得られるとあったので、圧縮部分を確認してみました。
(解凍速度は見ていません。)
環境
- Amazon ECR
- Docker Desktop for Mac v4.15.0
- aws cli 2.7.31
Dockerfile
以下を参考にCloudWatchエージェントをインストールしたDockerイメージを作るDockerfileを用意します。
FROM debian:11.6 as build
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates curl && \
rm -rf /var/lib/apt/lists/*
RUN curl -O https://s3.amazonaws.com/amazoncloudwatch-agent/debian/amd64/latest/amazon-cloudwatch-agent.deb && \
dpkg -i -E amazon-cloudwatch-agent.deb && \
rm -rf /tmp/* && \
rm -rf /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard && \
rm -rf /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl && \
rm -rf /opt/aws/amazon-cloudwatch-agent/bin/config-downloader
FROM scratch
COPY /tmp /tmp
COPY /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY /opt/aws/amazon-cloudwatch-agent /opt/aws/amazon-cloudwatch-agent
ENV RUN_IN_CONTAINER="True"
ENTRYPOINT ["/opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwatch-agent"]
ECRの事前準備
リポジトリの作成
ECRにgzip圧縮したコンテナを登録するcloudwatchリポジトリとzstd圧縮したコンテナを登録するcloudwatch-zstdリポジトリを作成しています。
% aws ecr describe-repositories | grep repositoryName
"repositoryName": "cloudwatch",
"repositoryName": "cloudwatch-zstd",
ECRの認証
AWS CLIを使用して認証し、作成したDockerイメージをリポジトリに登録できるようにします。
% export account_id=123456789012 #AWSのアカウントID
% aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
gzip圧縮した場合の確認
Docker Desktopをデフォルトのまま使用してDockerイメージを作るとgzip圧縮されます。
コンテナイメージの作成
zstdの場合となるべく合わせて、buildxを使用してコンテナイメージを作成します。
% docker buildx build --file Dockerfile --output type=image,name=${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/cloudwatch:1,push=true .
作成したイメージの圧縮アルゴリズム確認
mediaTypeでgzip圧縮されていることを確認できました。
% docker buildx imagetools inspect --raw ${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/cloudwatch:1 | grep mediaType
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"mediaType": "application/vnd.docker.container.image.v1+json",
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
イメージのサイズは33,619,130バイトでした。
% aws ecr describe-images --repository-name=cloudwatch | grep -e repositoryName -e imageSizeInBytes
"repositoryName": "cloudwatch",
"imageSizeInBytes": 33619130,
Docker Desktopの設定変更
Docker DesktopデフォルトのDocker Engineはまだzstd圧縮に対応していません。
zstd圧縮を使用するためにDocker Desktopでcontainerdを使用するように設定します。
Docker DesktopのPreferences - Features in development - Beta featuresでUse containerd for pulling and storing imagesにチェックを入れます。
Apply & restartをクリックし、containerdを使用するようにします。
zstd圧縮した場合の確認
コンテナイメージの作成
% docker buildx build --file Dockerfile --output type=image,name=${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/cloudwatch-zstd:1,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true,push=true .
作成したイメージの圧縮アルゴリズム確認
mediaTypeがzstdとなっていることを確認できました。
% docker buildx imagetools inspect --raw ${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/cloudwatch-zstd:1 | grep mediaType
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"mediaType": "application/vnd.oci.image.config.v1+json",
"mediaType": "application/vnd.oci.image.layer.v1.tar+zstd",
"mediaType": "application/vnd.oci.image.layer.v1.tar+zstd",
"mediaType": "application/vnd.oci.image.layer.v1.tar+zstd",
サイズは32,249,116バイトで、gzipの場合の95.9%でした。
% aws ecr describe-images --repository-name=cloudwatch-zstd | grep -e repositoryName -e imageSizeInBytes
"repositoryName": "cloudwatch-zstd",
"imageSizeInBytes": 32249116,
Discussion