154
82

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

gVisorを使ってdockerコンテナをより安全に利用する

Last updated at Posted at 2018-05-03

はじめに

gVisorとは、KubeCon2018でローンチが発表されたOpen Container Initiative (OCI)に準拠したコンテナのランタイム runsc を含むプロジェクトのこと。
OCIについては、この記事 にわかりやすくまとめてある。

kZ7lPEDwkIFnoq4nqnhtRbnTzqrqzN7Y9aBZTaXoQ8Q= (1).png https://blog.docker.com/2016/04/docker-engine-1-11-runc/ から引用

上記の記事にある図の runc というものが、今デフォルトで利用されているランタイムで、 runc の部分をよりセキュアに(ホストカーネルと隔離して)実行させようとしているのが runsc

どうやってホストカーネルと隔離するかは、gVisorのREADMEにまとまっている。要するにDockerアプリケーションからのシステムコールをgVisorが一度受け取り、それをホストカーネルに渡す仕組みになっている。

Layers (1).png
https://github.com/google/gvisor から引用

注意点としては、まだ動かないかもしれないけど、動かなかったら教えてね、くらいのふわっとした状況だということ。

ためしてみる

今のところ、Linuxでの動作しか保証していないようなので、Linuxの環境を作る。今回はGCEで Ubuntu 16.04 LTS を選んだ。

Ubuntu 18.04 LTSだと、Docker, Bazelが正式にサポートされてない。また Container-Optimized OSはDockerバージョンが17.03と、gVisorの推奨するDockerバージョンを満たしていない。
※いずれも2018/05/04時点

Dockerのインストール

Get Docker CE for Ubuntu | Docker Documentation
ドキュメント通りにコマンドを実行すればいい。

$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https ca-certificates \
    curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce

Bazelのインストール

Installing Bazel on Ubuntu - Bazel

こちらもドキュメント通り行う。

$ sudo apt-get install pkg-config zip g++ zlib1g-dev unzip python
$ curl -OL https://github.com/bazelbuild/bazel/releases/download/0.13.0/bazel
-0.13.0-installer-linux-x86_64.sh
$ chmod +x bazel
-0.13.0-installer-linux-x86_64.sh
$ ./bazel
-0.13.0-installer-linux-x86_64.sh

gVisorのビルド

Installation < 略

$ sudo apt-get install git
$ git clone https://gvisor.googlesource.com/gvisor gvisor
$ cd gvisor
$ bazel build runsc
<ビルドにめっちゃ時間かかる>
$ sudo cp ./bazel-bin/runsc/linux_amd64_pure_stripped/runsc /usr/local/bin

Dockerのruntimeに runscを追加

/etc/docker/daemon.json を作成し、以下の内容を記入。

{
    "runtimes": {
        "runsc": {
            "path": "/usr/local/bin/runsc"
        }
    }
}

sudo systemctl restart docker でdockerデーモンを再起動し、設定を反映。

runtimeに runsc を設定して実行

$ sudo docker run --runtime=runsc -it ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
a48c500ed24e: Pull complete
1e1de00ff7e1: Pull complete
0330ca45a200: Pull complete
471db38bcfbf: Pull complete
0b4aba487617: Pull complete
Digest: sha256:c8c275751219dadad8fa56b3ac41ca6cb22219ff117ca98fe82b42f24e1ba64e
Status: Downloaded newer image for ubuntu:latest

<コンテナ内>
root@e1d3ad2716a8:/# echo hello
> hello

プロセスを見てみると、containerdはrunscを起動させているっぽい。一応 立ち上げたubuntuコンテナで、for文など試してみたけど問題なく動いた。

$ ps -auwx | grep docker
...
root     18501  0.0  0.0   9060  3760 ?        Sl   16:51   0:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/e1d3ad2716a8e38c72fc5c8091e7bf39b8047301a512d66a989537e2b11a5d4b -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runsc

gVisorのコードについて

https://github.com/google/gvisor/tree/master/runsc/cmd
ここでOCIに準拠したruntimeのインタフェースを定義している。

https://github.com/google/gvisor/tree/master/pkg/sentry
このあたりでシステムコールまわりの処理をしているっぽい。

セキュリティについて #1

他にセキュリティを強固にするためのランタイムに Kata Containersというものがある。(1pagerはこちら

これはそもそもVM上にあるコンテナが対象で、コンテナごとに軽量カーネルをつくる。超軽量なので、軽量カーネルなしのコンテナと同じパフォーマンスが出るらしい。 <100ms boot time と書いてあるので確かに爆速だ。

katacontainers.png https://medium.com/kata-containers/why-kata-containers-doesnt-replace-kubernetes-75e484679727

コードは見れていないが、VMと同程度のセキュリティが担保されそう。

セキュリティについて #2

2018年のDocker・Mobyという須田さんのプレゼンにもセキュリティについて触れている。 P.55から。 資料自体が、とても面白い。

runcをrootlessにするという考えもあるという話。
今回調べた結果、すでに色々なアプローチをとられていることがわかったので、どこかのタイミングでまとめたい。

Podmanというrootlessのアプローチのプロダクトも出ている。

感想

最近はもはや何かを実行するときはコンテナの中で実行することが多い。ローカルには基本的に言語の実行環境をインストールせず、コンテナで実行環境のバージョンなどを指定して実行するようになった。

もちろんanyenvなどを使ってバージョン管理する方法もあるけど、ローカルの依存関係が複雑になっていくのが嫌だ。
あとコンテナにしておけば、k8sで簡単に並列処理できるし。

その反面、使うコンテナに含まれるセキュリティホールについては意識していなかったので、gVisorの需要は高い。
gVisorがMacに対応されたら、デフォルトのランタイムをrunscに変えるだろう。

154
82
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
154
82

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?