Akihiro Suda
Jul 23 · 15 min read

NTTの須田です。2019年7月23日に公開された、Docker 19.03の新機能をお伝えします。2018年11月8日にリリースされたDocker 18.09以来、8ヶ月ぶりのリリースです。

root権限不要化

従来のDockerは、ホストのroot権限でデーモン(dockerd)を動作させる必要があったため、脆弱性や設定ミスを突かれると、ホストのroot権限を奪われる恐れがありました。

Docker 19.03では、非rootユーザでデーモンを実行できるようになりました(Rootlessモード)。 Rootlessモードを有効化することで、万一Dockerに脆弱性や設定ミスがあっても、攻撃者にホストのroot権限を奪取されることを防ぐことが出来ます。ただし、現時点ではcgroupを利用できないなどの制約があります。

RootlessモードのDockerは, curl -fsSL https://get.docker.com/rootless | sh コマンド1行で、ユーザのホームディレクトリ内に sudo無しで簡単にインストール出来ます。Webブラウザ内で試用することも可能です。

$ curl -fsSL https://get.docker.com/rootless | sh$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock$ docker run ...

Rootlessモードの詳細は、5月に執筆した記事 RootlessモードでDockerをより安全にする[DockerCon発表レポート] をご覧ください。

GPU対応強化

従来のDockerでNVIDIAのGPUを用いるには、 docker コマンドの代わりに nvidia-docker コマンドを用いたり、OCIランタイムとして --runtime=nvidia (nvidia-docker2) を指定したりする必要がありました。

Docker 19.03では、Docker自体にGPU連携機能 docker run --gpus …が組み込まれました。

$ docker run --gpus all
$ docker run --gpus 2,driver=nvidia,capabilities=compute

現時点では nvidia ドライバのみが実装されていますが、将来的にはNVIDIA以外のベンダのGPU向けのドライバも実装されることが期待されます。

なお、 nvidia ドライバを利用するには、 nvidia-container-cli がホスト上にインストールされている必要があります。

docker buildの強化

Docker 18.06にて試験的に、Docker 18.09にて正式に採用されたBuildKitモード ( DOCKER_BUILDKIT=1 docker build ) が、一層強化されています。

docker build --cache-from

docker buildは、レジストリ上のイメージをキャッシュとして用いる( --cache-from )ことが出来ます。しかしながら、Docker 18.06・18.09では、BuildKitモードが有効である場合、 --cache-from にイメージを指定することが出来ませんでした。

Docker 19.03では、BuildKitモードが有効な場合でも、--cache-from にイメージを指定出来ます。ただし、 --cache-from に指定するイメージは、 --build-arg BUILDKIT_INLINE_CACHE=true を付けてビルドされている必要があります。

docker build --output

ビルドしたイメージの内容を、 --output で指定したディレクトリ内に書き出せるようになりました。

$ cat Dockerfile
FROM alpine
RUN apk add --no-cache figlet
RUN figlet hello > /hello
FROM scratch
COPY --from=0 /hello /hello
$ docker build --output ./out .$ ls -l out/
total 4
-rw-r--r-- 1 suda suda 138 Jul 1 20:41 hello
$ cat out/hello
_ _ _
| |__ ___| | | ___
| '_ \ / _ \ | |/ _ \
| | | | __/ | | (_) |
|_| |_|\___|_|_|\___/

docker context

docker コマンドの接続先ホストを、”context”として管理できるようになりました。kubectl のcontextと似ています。

$ docker context create foo --docker "host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file"
foo
Successfully created context "foo"
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT ...
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
foo tcp://myserver:2376
$ docker --context=foo run ...

CLIプラグイン

docker コマンドをプラグインで拡張できるようになりました。 /usr/lib/docker/cli-plugins または ~/.docker/cli-plugins に、プラグインバイナリ docker-foo を配置すると、 docker foo として実行できるようになります。

既に数多くのプラグインが実装・公開されています。

docker buildx

docker buildx プラグインをインストールすると、BuildKitを用いて docker build コマンドの機能を強化した docker buildx コマンドが利用できるようになります。

docker buildx は、BuildKitモードの docker build ( export DOCKER_BUILDKIT=1 )とよく似ていますが、より先進的な機能を備えています。

例えば、 docker buildx を用いると、 amd64arm64 など複数のアーキテクチャに対応したイメージを簡単にビルドすることが出来ます。複数アーキテクチャに対応したイメージをビルドするには、次の2つの方法があります。

  1. 先述の docker context コマンドを用いて、アーキテクチャ毎にリモートのDockerホストを登録する
  2. QEMU user-mode emulationを用いて、1台のDockerホストで複数アーキテクチャをエミュレートする

性能面では1.の方法が優れていますが、本記事では簡単な2.の方法を紹介します。

まず、 amd64 アーキテクチャのホストにて linuxkit/binfmt イメージをprivilegedモードで起動し、ホストの /proc/sys/fs/binfmt_misc に、QEMU user-mode emulationのバイナリを登録します。

$ docker run --rm --privileged linuxkit/binfmt:v0.7
$ ls -l /proc/sys/fs/binfmt_misc/
total 0
-rw-r--r-- 1 root root 0 Jul 2 17:04 qemu-aarch64
-rw-r--r-- 1 root root 0 Jul 2 17:04 qemu-arm
-rw-r--r-- 1 root root 0 Jul 2 17:04 qemu-ppc64le
-rw-r--r-- 1 root root 0 Jul 2 17:04 qemu-s390x
--w------- 1 root root 0 Jul 2 17:04 register
-rw-r--r-- 1 root root 0 Jul 2 17:04 status

これで、Linuxカーネルは、 amd64 以外のアーキテクチャのバイナリを、QEMU user-mode emulationを用いてCPUをエミュレートしながら実行できるようになります。なお、一般的に「QEMU」として認知されているQEMU full-system emulationと異なり、VMは作成されません。

続いて、 docker buildx create 及び docker buildx inspect --bootstrapを用いて、BuildKitバックエンドを起動します。

$ docker buildx create --use
epic_blackburn
$ docker buildx inspect --bootstrap
...
Name: epic_blackburn0
...
Platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6

これで、docker buildx buildを用いて、複数アーキテクチャに対応したイメージをビルド・プッシュできるようになります。

$ docker buildx build -t example.com/foo --push --platform linux/amd64,linux/arm64 ...

docker buildx プラグインは、Docker社により https://github.com/docker/buildx にて提供されています。Docker for Mac/Winには標準で付属します。

docker app

docker app プラグインを使うと、 docker-compose.yml 及びイメージを、1つのCloud Native Application Bundle (CNAB)にまとめて、レジストリにプッシュしたり、プルしたりできるようになります。

例として、 example-voting-app.dockerapp をプッシュしてみます。

$ cat ./example-voting-app.dockerapp/docker-compose.yml
version: "3.6"
services:
redis:
image: redis:alpine
ports:
- "6379:6379"
db:
image: postgres:9.4
ports:
- "5432:5432"
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "${vote.port}:80"
deploy:
replicas: ${vote.replicas}
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "${result.port}:80"
worker:
image: dockersamples/examplevotingapp_worker
$ docker app push ./example-voting-app.dockerapp --platform linux/amd64 -t example.com/foo.dockerapp

プッシュしたアプリケーションバンドルは、 docker app render を用いて、 docker-compose.yml に復元することができます。 ただし、元の docker-compose.yml で指定されていたDocker Hub上のイメージではなく、バンドルにコピーされたイメージが用いられます。

$ docker app render example.com/foo.dockerapp
version: "3.6"
services:
db:
image: example.com/foo.dockerapp@sha256:4d915cbb7d4f93a8b1d73fc62496d0e1757599b0e1c567fd349fa9e47720f868
ports:
- mode: ingress
target: 5432
published: 5432
protocol: tcp
redis:
image: example.com/foo.dockerapp@sha256:98547c3529f6b02e3c789c8f4a96d6bb8469b9119150c955370753b93f9a67f2
ports:
- mode: ingress
target: 6379
published: 6379
protocol: tcp
result:
image: example.com/foo.dockerapp@sha256:83b568996e930c292a6ae5187fda84dd6568a19d97cdb933720be15c757b7463
ports:
- mode: ingress
target: 80
published: 60081
protocol: tcp
vote:
deploy:
replicas: 2
image: example.com/foo.dockerapp@sha256:8e64b18b2c87de902f2b72321c89b4af4e2b942d76d0b772532ff27ec4c6ebf6
ports:
- mode: ingress
target: 80
published: 60080
protocol: tcp
worker:
image: example.com/foo.dockerapp@sha256:55753a7b7872d3e2eb47f146c53899c41dcbe259d54e24b3da730b9acbff50a1

アプリケーションバンドルは、 docker app installを用いて、SwarmやKubernetesにデプロイすることも可能です。ただし、Kubernetesへデプロイするには、Compose on Kubernetesがインストールされている必要があります。

$ docker app install --orchestrator kubernetes example.com/foo.dockerapp

docker appプラグインは、Docker社により https://github.com/docker/app にて提供されています。Docker for Mac/Winには標準で付属します。

docker wasm

docker wasm プラグインを使うと、WASMアプリケーションをDockerコンテナのように扱うことができます。

例えば、 tonistiigi/hello イメージは、 docker run コマンドで起動すると通常のコンテナとして実行され、docker wasm run コマンドで起動するとWASMランタイム(wasmtimeまたはwasmer)上で実行されます。(前述の docker buildx プラグインを用いて、マルチプラットフォームイメージとしてビルドされています。)

$ docker run tonistiigi/hello
Hello world, I am linux/amd64!
$ docker wasm run tonistiigi/hello
Hello world, I am wasi/wasm!

また、docker wasm run tonistiigi/viu:docker を実行すると、面白いデモ画像が表示されます。

docker wasm run tonistiigi/viu:docker

docker wasm プラグインは、Tõnis Tiigi氏により https://github.com/tonistiigi/wasm-cli-plugin にて配布されています。

docker expose

docker expose プラグインを使うと、ngrokを用いて簡単にコンテナをインターネットに公開できます。

$ docker run --name nginx -d nginx 
$ docker expose nginx 80
...
https://deadbeef.ngrok.io
...

docker expose プラグインは、 Łukasz Lach氏により https://github.com/lukaszlach/clip にて配布されています。

docker microscan

docker microscan プラグインを使うと、Aqua MicroScannerを用いてイメージ中の脆弱性をスキャンできます。

$ docker microscan debian
No critical vulnerabilities found in debian

docker microscanプラグインは、 docker expose プラグインと同じくŁukasz Lach氏により、 https://github.com/lukaszlach/clip にて配布されています。

Enterprise Editionのプラグイン

Docker 19.03をベースとしたエンタープライズ製品であるDocker Enterprise 3.0には、 docker assembledocker templatedocker clusterdocker gmsadocker registry など多くのプラグインが付属するようです。

https://www.slideshare.net/ajeetraina/dockercon-2019-updates-announcements/26

おわりに

私たちNTTはオープンソースコミュニティで共に活動する仲間を募集しています。ぜひ弊社 ソフトウェアイノベーションセンタ紹介ページや、採用情報ページをご覧ください。

nttlabs

NTT Open Source

Akihiro Suda

Written by

Moby (former Docker Engine), BuildKit, and containerd maintainer. https://github.com/AkihiroSuda

nttlabs

nttlabs

NTT Open Source

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade