Docker
runc
gVisor
katacontainers
DockerDay 3

コンテナ低位ランタイムの解説&パフォーマンス測定

Docker Advent Calendar 2018 3日目です。

こんにちは。入社一年目でインフラ周り触ってるエンジニアです。

至らぬところがあると思いますが、よろしくおねがいします。


TL;DR


  • 低位ランタイムはアプリケーションの隔離を行う

  • トレンドは隔離度を上げること

  • コンテナライフサイクルのパフォーマンスは runcgVisor(runsc) > kata-runtime

  • コンテナ上のアプリケーションのパフォーマンスは runc > gVisor(runsc)kata-runtime


  • gVisor(runsc)は現時点ではまだ不安定


コンテナ技術とは

軽量でイミュータブルに隔離したアプリケーションを動作させることができる仕組みです

有名どころだと、Docker、Kubernetesがあります

隔離したアプリケーションを動かす仕組みをランタイムと呼びますが、これには高位ランタイムと低位ランタイムがあります

高位ランタイムは主に低位ランタイムの操作、ネットワーキング、イメージの管理などを担います

本記事では低位ランタイムを取り扱います


低位ランタイムとは

実際にアプリケーションの隔離を行うランタイムです

NamespaceやCgroupでの隔離が有名ですが、最近ではvmで隔離する低位ランタイムも登場しています

低位ランタイムの仕様にはOCI Runtime SpecificationOCI Runtime Command Line Interfaceがあります

話がそれますが、Amazonが先日発表した超軽量のvmを使うFirecrackerは現状上記仕様を満たしていないので、今回の記事では測定しません(できない)

ただ、上記仕様に準拠する声明を出しているのでDockerやKubernetesの低位ランタイムとしてそのうち使えるようになるはずです


OCI Runtime Specification

主にコンテナのライフサイクル、構成ファイル(config.json)を定義しています

NamespaceやCgroup、セキュリティ関連の仕様を定義しています

コンテナのライフサイクルは仕様にもあるようにCreateStartKillDeleteのように進んでいきます

Killは能動的な操作で、自然にアプリケーションが終了した場合は呼ばれません

lifecycle.png

構成ファイルにはほぼ全ての情報が含まれている(コンテナの生死の判定など除く)ので困ったときに見ると問題を解決できるかもしれません


OCI Runtime Command Line Interface

低位ランタイムのCLIを定義しています

定義されているコマンドはcreatestartstatekilldeleteの5個です

普段使っている人が多い、runexecは意外にも定義されていません


低位ランタイム紹介

有名なものを紹介


runc

言わずと知れた低位ランタイム

元はDocker社、現在はOCIの持ち物

NamespaceやCgroupでアプリケーションの隔離を行います。現状一番使われている低位ランタイム


gVisor

開発:Google社

危険なシステムコールをgVisorがフックし、ホストカーネルに渡す低位ランタイム

MeltdownやSpectreなどの脆弱性があるとruncでは処理がとられてしまうが、gVisorでは隔離度が高いため攻撃が成立しません


kata-runtime

開発:Openstack Foundation

超軽量のカーネルを動作させることで隔離度を上げる低位ランタイム

VMの隔離性を持ちつつ、コンテナの軽量さを併せ持っています


パフォーマンス測定

続いてパフォーマンスの測定を行います

以下2つの視点からパフォーマンスを測定します

* コンテナライフサイクル

* コンテナ上のアプリケーション


測定環境

訳あってVM環境で動かしているので、Baremetal環境でやると違う値が出ると思いますので、参考程度にどうぞ


  • CentOS7.5 x86_64

  • Kernel Version: 4.19.0-1.el7.elrepo.x86_64

  • vCPU: 4

  • Memory: 8GiB


コンテナライフサイクルのパフォーマンス測定

特徴的な値を拾っていきます


  • 基本のプログラム(hello-world)

hello-worldを実行した際のグラフが以下です

runcとgVisorはほぼ同じ値ですが、kata-runtimeに関してはvmを起動する処理がどうしても入ってしまうので、ほかの低位ランタイムよりも起動に時間がかかっています

hello-world.png


  • 低負荷なプログラム(google/pause)

google/pauseに関しても同様にkata-runtimeだけが実行時間が長いです

google-pause.png


  • 高負荷なプログラム(rogeriopradoj/yes)

一方で高負荷なプログラムではkata-runtimeの方が実行時間が短かったです

PID1特別問題だと思い、dumb-initを試しましたが、結果は変わらずkata-runtimeが一番実行時間が短かったです

ホストカーネルの1プロセスとして動作するrunc、gVisorはハング時にシグナルを受け取りにくい?

知っている方いたら教えてください

yes.png


コンテナ上のアプリケーションのパフォーマンス測定

前章までは低位ランタイムの各ライフサイクルでかかる時間を測定しました

しかし、システムコールのエミュレーションなどがアプリケーションに及ぼす影響は調べられていないです

そこで、本章では低位ランタイム上でunixbenchを動かすことで網羅的にパフォーマンスを測定します

1cpuと4cpuで試します


runc

インデックスは1cpuで672.6、4cpuで1737.8

unix-runc.png


gVisor

4cpuではクラッシュしてしまったので、1cpuの結果のみ

インデックスは70

(さすがにこんなに低くならないと思うので、設定ミス?)

image.png


kata-runtime

インデックスは1cpuで124.2、4cpuで181

unix-kata.png


まとめ

低位ランタイムはいろいろな実装が出てきているが、環境を選ばないと著しい性能劣化が起こる可能性があります

gVisorのようにクラッシュする場面も出てくるかもしれないので、ご利用は計画的に