Dockerのイメージビルド中でapt-getを高速化するたった1つの方法

2023-04-24Bash,Docker

はじめに

(追記)煽りタイトルが思っていたより反響があるのだなと思いました。

Dockerのイメージビルド処理は少しでも速い方が、試行錯誤にかかる時間を減らすことができます。

apt-get にかかる時間が全体のそこそこの時間を占めているのでなんとかできないかと思いました。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ bash -version | head -n 1
GNU bash, バージョン 5.0.11(1)-release (x86_64-apple-darwin18.6.0)

何も対処しない場合の処理時間

curlpostgresql-client が必要だったので、この2つをインストールしただけのイメージを作成してみます。

以下のような Dockerfile を作成します。

FROM ubuntu:19.10

RUN apt-get update \
  && apt-get install --no-install-recommends -y \
    curl \
    postgresql-client \
  && apt-get clean \
  && rm -r /var/lib/apt/lists/*

この Dockerfile を使ってイメージをビルドしてみます。

  • 3回実行します。
  • ログが大量に出力されるため、 before.log というファイルにリダイレクトし捨てておきます。
  • time コマンドでどのぐらいの処理時間がかかるのかを確認してみます。
$ for ((i = 0; i < 3; i++)); do
  time docker build --no-cache -t genzouw/test . 2>&1 >>before.log
done

docker build --no-cache -t genzouw/test . 2>&1 >> before.log  1.86s user 1.22s system 3% cpu 1:24.17 total
docker build --no-cache -t genzouw/test . 2>&1 >> before.log  1.81s user 1.28s system 4% cpu 1:14.72 total
docker build --no-cache -t genzouw/test . 2>&1 >> before.log  1.92s user 1.38s system 2% cpu 1:51.64 total

ブレは大きいですが、平均すると 90.18s ほどの処理時間がかかっています。

高速化

apt-get を高速化するための施策を実施します。

実は、 Dcoker に限らず、Debian系OSで apt-get する場合全般に適用できる高速化になります。

以下のコマンドを実行し、 apt-get で利用するパッケージダウンロード元のリポジトリを日本のサーバに変更します。
ネットワーク通信にかかる時間を減らすことが期待できます。

sed -i 's@archive.ubuntu.com@ftp.jaist.ac.jp/pub/Linux@g' /etc/apt/sources.list

security.ubuntu.com に関しては変更して良いものか判断つかず、ひとまずそのままにしました。

対処した場合の処理時間

1行だけ処理が増えて、以下のような Dockerfile となりました。

FROM ubuntu:19.10

LABEL maintainer "genzouw <genzouw@gmail.com>"

RUN sed -i 's@archive.ubuntu.com@ftp.jaist.ac.jp/pub/Linux@g' /etc/apt/sources.list

RUN apt-get update \
    && apt-get install --no-install-recommends -y \
        curl \
        postgresql-client \
    && apt-get clean \
    && rm -r /var/lib/apt/lists/*

先程と同様、3回実行してみます。

$ for ((i = 0; i < 3; i++)); do
  time docker build --no-cache -t genzouw/test . 2>&1 >>after.log
done

docker build --no-cache -t genzouw/test . 2>&1 >> after.log  1.77s user 1.24s system 10% cpu 27.722 total
docker build --no-cache -t genzouw/test . 2>&1 >> after.log  1.83s user 1.18s system 12% cpu 24.825 total
docker build --no-cache -t genzouw/test . 2>&1 >> after.log  1.71s user 1.10s system 11% cpu 23.795 total

なんと 25.44s になりました。単純に 3倍以上 の速度改善となりました。

ひとこと

当面は日本リージョンでの稼働を考えた場合の高速化ですが、 Kubernetes の利用や海外展開などと絡めて考える必要はあります。
海外リージョンで実行した場合は逆に遅くなってしまいますね。 ( CI/CDサーバを海外リージョンに配置してビルドするようなケース )

その他 apt-fast の速度も調査してみたい。

2023-04-24Bash,Docker