NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    依存関係を最小限に抑えたAmazon Linux 2023のコンテナを作成する

    本記事は  AWSアワード受賞者祭り  7日目の記事です。
    ✨🏆  6日目  ▶▶ 本記事 ▶▶  8日目  🏆✨

    ドーモ、浮田です。 昼食に素うどんばかり食べていたので、上司に心配されていました。 最近は釜玉うどんにバージョンアップしたので、上司も安心することでしょう。

    はじめに

    こんなことができるんだよ〜という記事です。

    コンテナのベストプラクティスの一つに、不要なパッケージをインストールしない*1ことが挙げられています。 これは、不要なパッケージをインストールしないことで依存関係を減らしイメージサイズを減らすためです。 今回は、依存関係に着目しAmazon Linux 2023(以下、AL2023)から依存関係を最小限に抑えたコンテナを作成します。 ベースコンテナには、AWSが提供しているAL2023ベースコンテナイメージを使います。

    コンテナイメージを小さくすることのメリット

    コンテナイメージを小さくすることのメリットを以下に記載します。

    • セキュリティの向上

     不要なパッケージを含めないことで、脆弱性が減少し攻撃対象領域が小さくなる。

    • コストの削減

     ECRのストレージコストやネットワーク転送コストを削減できる。

    • スケーラビリティの向上

     ECRからイメージをプルする時間やコンテナの起動時間を短縮することで、素早くスケーリングできトラフィックの急増に対応できる。

    Amazon Linux 2023を使うメリット

    AWSによる長期的なサポートとパッケージバージョンの固定化*2による運用のしやすさがメリットになります。 AL2023は、リポジトリがバージョニングされており、パッケージのバージョンが固定化されている*3ため、手元でパッケージのバージョン管理を意識することなく開発を進められます。

    GitHubのDependabotでベースイメージのバージョンを自動的に更新することができるので、例えば、AL2023のリリースタグが2023.6から2023.7になるとGitHubでPRを作成するなどの運用が可能です。

    また、AL2023はAWSからリリースノートが提供*4されており、どのパッケージに更新があるか分かりやすいです。

    コンテナイメージの作成

    bashのみをインストールしたコンテナイメージを作成します。

    イメージの作成には、マルチステージビルドを活用します。 最初のステージでは、dnfのinstallrootオプションでパッケージのインストール場所を指定し、bashをインストールします。 bashをインストールしたディレクトリを次のステージの/ディレクトリにコピーすることで、依存関係を最小限に抑えたコンテナイメージを作成することができます。

    dockerfileの解説

    buildステージで/installrootディレクトリを作成します。 dnfのinstallrootオプションでパッケージのインストール先に/installrootを指定します。 releaseverオプションでパッケージリポジトリのバージョンを指定します。 rpm -q system-releaseを叩くとsystem-release-2023.8.20250707-0.amzn2023.noarchのような結果を得られるので、そこからqueryformatオプションでバージョンのみを抜き出しています。 setopt=install_weak_deps=Falseオプションで依存関係が弱いパッケージのインストールをスキップします。 これで、依存関係を最小限に抑えたbashを/installrootディレクトリにインストールすることができます。

    buildステージの/installrootディレクトリをscratch*5ステージの/ディレクトリにコピーし、コンテナ起動時にbashを起動するようにしたら完成です。

    FROM public.ecr.aws/amazonlinux/amazonlinux:2023 AS build
    RUN mkdir /installroot
    RUN dnf -y \
      --installroot /installroot \
      --releasever=$(rpm -q system-release --queryformat '%{VERSION}') \
      --setopt=install_weak_deps=False \
      install bash \
      && dnf --installroot /installroot clean all
    
    FROM scratch AS scratch
    COPY --from=build /installroot /
    ENTRYPOINT ["bash"]

    ビルド結果

    ビルドすると26.1MBとかなり小さなイメージができました。

    $ docker images
    REPOSITORY                               TAG             IMAGE ID       CREATED          SIZE
    amazonlinux                              2023-bash       580da8cc865e   27 minutes ago   26.1MB
    public.ecr.aws/amazonlinux/amazonlinux   2023            aab732c9dab9   7 days ago       182MB
    public.ecr.aws/amazonlinux/amazonlinux   2023-minimal    39004e0140fb   7 days ago       120MB
    debian                                   latest          49c8d736314a   2 weeks ago      139MB
    fedora                                   latest          999a110c3d3c   3 weeks ago      174MB
    nginx                                    latest          889e2cc329c8   3 weeks ago      198MB
    ubuntu                                   latest          70ed52c84b4e   3 weeks ago      101MB

    実際に起動してみると、lsやdnfコマンドすらないですね。

    $ docker run -it --rm amazonlinux:2023-bash
    bash-5.2# echo /sbin/*
    /sbin/iconvconfig /sbin/ldconfig /sbin/zic
    bash-5.2# echo /bin/*
    /bin/alias /bin/bash /bin/bashbug /bin/bashbug-64 /bin/bg /bin/catchsegv /bin/cd /bin/command /bin/fc /bin/fg /bin/gencat /bin/getconf /bin/getent /bin/getopts /bin/hash /bin/iconv /bin/jobs /bin/ld.so /bin/ldd /bin/locale /bin/localedef /bin/pldd /bin/read /bin/sh /bin/sotruss /bin/sprof /bin/type /bin/tzselect /bin/ulimit /bin/umask /bin/unalias /bin/wait /bin/zdump

    比較として、AL2023のコマンド一覧を載せておきます。

    $ docker run -it --rm public.ecr.aws/amazonlinux/amazonlinux:2023
    bash-5.2# ls /sbin/
    alternatives  chroot  getpcaps     ldconfig  update-alternatives
    capsh         getcap  iconvconfig  setcap    zic
    bash-5.2# ls /bin/
    '['       dnf-3          id           pydoc3        sync
     alias        du             install          pydoc3.9      tac
     arch         echo           jobs         python3       tail
     awk          egrep          join         python3.9     tee
     b2sum        env            ld.so        read          test
     base32       expand             ldd          readlink      timeout
     base64       expr           link         realpath      touch
     basename     factor             ln           rm            tr
     basenc       false          locale       rmdir         true
     bash         fc             localedef        rpm           truncate
     bashbug      fg             logname          rpm2archive   trust
     bashbug-64   fgrep          ls           rpm2cpio      tsort
     bg       fmt            md5sum       rpmdb         tty
     ca-legacy    fold           mkdir        rpmkeys       type
     cat          gapplication       mkfifo       rpmquery      tzselect
     catchsegv    gawk           mknod        rpmverify     ulimit
     cd       gdbus          mktemp       runcon        umask
     chcon        gencat             modulemd-validator   sed           unalias
     chgrp        getconf            mv           seq           uname
     chmod        getent             nice         sh            unexpand
     chown        getopts            nl           sha1sum       uniq
     cksum        gio            nohup        sha224sum     unlink
     comm         gio-querymodules-64    nproc        sha256sum     update-ca-trust
     command      glib-compile-schemas   numfmt       sha384sum     users
     coreutils    gpg            od           sha512sum     vdir
     cp       gpg-error          p11-kit          shred         wait
     csplit       gpg2           paste        shuf          wc
     curl         gpgme-json         pathchk          sleep         wcurl
     cut          gpgv2          pinky        sort          who
     date         grep           pldd         sotruss       whoami
     dd       groups             pr           split         xmlcatalog
     df       gsettings          printenv         sprof         xmllint
     dir          hash           printf       stat          xmlwf
     dircolors    head           ptx          stdbuf        yes
     dirname      hostid             pwd          stty          yum
     dnf          iconv          pydoc        sum           zdump

    おわりに

    今回は、依存関係を最小限に抑えたAL2023のコンテナイメージを作成しました。 コンテナイメージを小さくすることで、セキュリティの向上やイメージをプルする時間が短縮されたことによるスケーラビリティの向上、ECRのストレージコストの削減など、多くのメリットがあります。 AL2023をもっと軽量にしたいけれど、言語の都合によりdistrolessを使いづらい...みたいな場合に、活用してみるのはありかもしれません。

    参考) Building bare-bones AL2023 container images, https://docs.aws.amazon.com/linux/al2023/ug/barebones-containers.html

    執筆者: 浮田 博揮
    クラウドエンジニア
    2025 Japan All AWS Certifications Engineers