Skip to content

Instantly share code, notes, and snippets.

@denvernine
Last active November 17, 2022 04:39
Show Gist options
  • Save denvernine/34e23ecb9a3bac9f678e194cd63cb187 to your computer and use it in GitHub Desktop.
Save denvernine/34e23ecb9a3bac9f678e194cd63cb187 to your computer and use it in GitHub Desktop.
Dockerの新しい機能の個人用まとめ

イマドキのDocker事情

開発環境のデファクトスタンダードとしてDockerが普及して久しいですが、Dockerはいまなお便利になり続けています。そこで新しい機能や流行(の兆し)についてちょっとまとめてみましょう。

rootless

Dockerでは大抵rootユーザーが使われていますが、これを利用した特権昇格が可能です。 1 これはセキュリティにも非常にまずいということは容易に想像できます。そこでnon-rootユーザーでDockerを実行しようというのがrootlessモードのようです。雑な理解だとdocker-daemonをログインユーザーで動かすことで問題を回避しているようです。v19.03以降で利用できて、v20.10以降は正式な機能として利用できるようになったようです。

導入は非常に簡単なのでちょっとやってみましょう。ではDockerをインストールするのと同時に dockerd-rootless-setuptool.sh もインストールされているようです。なければ curl -fsSL https://get.docker.com/rootless | sh でrootlessモードのDockerをインストールできます。

sudo systemctl disable --now docker.service docker.socket

sudo yum install fuse-overlayfs iptables \
  && sudo rm -rf /var/cache/yum \
  && sudo yum clean all

sudo sh -eux <<EOF
# Load ip_tables module
modprobe ip_tables
EOF

dockerd-rootless-setuptool.sh install

export PATH="/usr/bin:${PATH}" >> ~/.bashrc
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/docker.sock" >> ~/.bashrc

source ~/.bashrc

systemdを使ってサービスを起動します。

systemctl --user start docker
systemctl --user enable docker
sudo loginctl enable-linger $(whoami)
systemctl --user status -l docker

Distrolessイメージ

Distroless はGoogleが提供するDockerイメージで、パッケージマネージャはおろかシェルさえ含まれていません。よくベースイメージに使用されるalpineが約5MBなのに対して、Distrolessイメージは約2MB(!)しかありません。ちょっとどうなっているか理解できませんね。

distroless/base... はglibcなどを含むためイメージサイズが大きくなっています。

REPOSITORY                        TAG     IMAGE ID      CREATED       SIZE
alpine                            latest  e9adb5357e84  4 hours ago   5.57MB
gcr.io/distroless/static-debian11 latest  e70108cdcff6  52 years ago  2.36MB
gcr.io/distroless/base-debian11   latest  e883c5e0f185  52 years ago  20.3MB

Buildkit / buildx

Buildkit はDockerのMoby project 2 のひとつで、強力なキャッシュ機能をもち、並列的な依存関係の解決を行う次世代のビルドツールです。

Githubのリリースページ をみると、現在0.8.0が最新となっていてまだまだ開発段階といったところですが、v18.09以降のDockerに統合されており正式に利用できるようになりつつあります。

先述したように、v18.09以降で利用できて、v20.10以降は正式な機能として利用できるようになったようです。 3

  • 環境変数でBuildkitを使う

    DOCKER_BUILDKIT=1 docker build .
  • 設定ファイルでBuildkitを使う

    /etc/docker/daemon.json に以下を追記してdocker-daemonを再起動する。

    { "features": { "buildkit": true } }
    systemctl reload docker

もしくはCLIプラグインとして ~/.docker/cli-plugins/(システム全体で使うなら /usr/local/lib/docker/cli-plugins または /usr/local/libexec/docker/cli-plugins )にバイナリファイルを配置することで、サブコマンドから使うこともできます。おそらく日常的に使う分にはこちらのほうが簡単でしょう。 4

# e.g.)
mkdir -p "${HOME}/.docker/cli-plugins"
curl -sSL -o ~/.docker/cli-plugins/docker-buildx -- https://github.com/docker/buildx/releases/download/v0.8.0/buildx-v0.8.0.linux-amd64
chmod +x "${HOME}/.docker/cli-plugins/docker-buildx"

docker buildx build .

docker buildx install コマンドを実行すると、docker build でBuildkitを使うようになります。docker buildx uninstall で元に戻すこともできます。 5

docker build --help
# Usage:  docker build [OPTIONS] PATH | URL | -
# ...
docker buildx install
docker build --help
# Usage:  docker buildx build [OPTIONS] PATH | URL | -
# ...

heredoc

Dockerfileの書き方として、中間レイヤーの数に影響する RUN, COPY をできるだけ少なくするため、複数の処理を && で数珠つなぎにするのが一般的でした。でもこの書き方って美しくないよね?ということでヒアドキュメントを使って記述できるようになりました。 6

この機能を使うには、ファイル先頭に # syntax=docker/dockerfile:1-labs のような命令を記述します。コロン : のうしろにある数字ですが、これはdockerhubのdocker/dockerfileのタグに対応しています。 7 ちょっと簡単なDockerイメージを作ってみましょう。

# syntax=docker/dockerfile:1-labs
FROM gcr.io/distroless/static

RUN <<EOR
echo command1 >> /tmp/log
echo command2 >> /tmp/log
echo command3 && echo command4 >> /tmp/log
EOR

COPY <<robots.txt <<humans.txt /usr/share/nginx/html/
User-agent: *
Disallow: /
Sitemap: https://example.com/sitemaps/sitemap.xml
robots.txt
Locations:
  'Apostolic Palace': 00120 Vatican City
  'Buckingham Palace': London SW1A 1AA, United Kingdom
  'Imperial Palace': 1-1 Chiyoda, Chiyoda City, Tokyo 100-8111
humans.txt
docker build --no-cache --progress=plain .
# ...
#13 writing image sha256:f03b6105d1dc7221bcdd0778b946cc53b9c011f5f3f3cf60880b3330d1b9c96b 0.1s done
#13 DONE 2.6s

できたイメージを動かしてみて、結果を見てみます。

docker run --rm f03b6105d1d cat /tmp/log
# command1
# command2
# command4

docker run --rm f03b6105d1d ls -lhsaF /usr/share/nginx/html/
# total 8.0K
#    0 drwxr-xr-x 2 root root  42 Mar 17 07:03 ./
#    0 drwxr-xr-x 3 root root  18 Mar 17 07:03 ../
# 4.0K -rw-r--r-- 1 root root 164 Mar 17 06:51 humans.txt
# 4.0K -rw-r--r-- 1 root root  76 Mar 17 06:51 robots.txt

docker run --rm f03b6105d1d cat /usr/share/nginx/html/robots.txt
# User-agent: *
# Disallow: /
# Sitemap: https://example.com/sitemaps/sitemap.xml

期待通りにできていますね。ちなみに、 echo command3 はビルド中に実行されるのみでファイルへのリダイレクトは行われません。これも期待通りの動作です。

# ...
#11 [2/3] RUN <<EOR (echo command1 >> /tmp/log...)
#11 1.996 command3
#11 DONE 3.6s
# ...

kubernetesを使って分散ビルド

kubernetesと連携して、イメージビルドの負荷分散を行うことができるようです。すごいですね……。

# e.g.) 3つのpodで負荷分散を行いながらビルドする
docker buildx create --driver kubernetes --driver-opt namespace=docker-buildx --driver-opt replicas=3 --use
kubectl get po --namespace=docker-buildx

docker buildx build .

references

Footnotes

  1. DockerやLXDを使った権限昇格手法 | 晴耕雨読

  2. Moby

  3. Build images with BuildKit | Docker Documentation

  4. Docker Buildx | Docker Documentation

  5. Docker Buildx | Docker Documentation

  6. Introduction to heredocs in Dockerfiles - Docker Blog

  7. docker/dockerfile - Docker Image | Docker Hub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment