Docker 19.03新機能 (root権限不要化、GPU対応強化、CLIプラグイン…)
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 > /helloFROM 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
を用いると、 amd64
、 arm64
など複数のアーキテクチャに対応したイメージを簡単にビルドすることが出来ます。複数アーキテクチャに対応したイメージをビルドするには、次の2つの方法があります。
- 先述の
docker context
コマンドを用いて、アーキテクチャ毎にリモートのDockerホストを登録する - 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
プラグインは、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 assemble
、 docker template
、 docker cluster
、 docker gmsa
、 docker registry
など多くのプラグインが付属するようです。
https://www.slideshare.net/ajeetraina/dockercon-2019-updates-announcements/26
おわりに
私たちNTTはオープンソースコミュニティで共に活動する仲間を募集しています。ぜひ弊社 ソフトウェアイノベーションセンタ紹介ページや、採用情報ページをご覧ください。