Kata Containers on Oracle Linux について Oracle Open World でお話ししてきました

概要

2019/9にサンフランシスコで開催されたOracle Open World 2019で登壇する機会をいただきました。Linuxとセキュリティという切り口で、Oracle LinuxのPMのSimon Coterさんといっしょに、Kata Containersというセキュリティ指向のコンテナランタイムについてお話ししてきました。

実は英語で登壇するのは初めての経験だったので、出落ちのクレイジージャパニーズくらいの気持ちで行きましたが、それなりに形になってたようです。我ながらかなりの変態ミッションだったと思います。

  • 夏休みの個人旅行でOracle Open Worldに行く
  • 個人で登壇する
  • 英語で30分ぐらい話してデモもやる
  • アイスブレイクでけん玉をちょっとやる

Oracle Open Worldに登壇した日本人はいっぱいいますが、けん玉をやった人はいないでしょう。

Oracle Open World 2019 の資料はこちらのサイトからダウンロードできます。(英語版です)

events.rainfocus.com

2019/8に日本で開催された、Oracle Modern Cloud Day Tokyoでも、同じ内容を日本語でお話しさせてもらったので、そちらの資料を使って解説したいと思います。

Oracle Modern Cloud Day Tokyo の資料はこちらのサイトからダウンロードできます。

https://www.oracle.co.jp/campaign/moderncloudday/2019/

導入

表紙の背景に特に意味はありませんが、自分で撮影してきた天体写真をぶっ込むスタイルでいきました。この写真は2017年8月にアメリカで撮影してきた皆既日食の写真です。OOWで皆既日食を見た人がいるか聞いてみたら、2,3人手を上げてくれました。

余談ですが、2017/8/21 北米皆既日食の記事はこちら。

shakemid.hatenablog.com

自己紹介スライドはいつもながら自己主張強めです。OOWではちょっとけん玉やりました。だいぶうけてたのでアイスブレイクには成功したようです。芸は身を助ける、です。

アプリケーションコンテナ

コンテナ型仮想化の歴史は、1979年にUnixに実装されたchrootに遡ります。chrootはプロセスからファイルシステムを隔離する仕組みで、今でもよく使われます。2000年には、FreeBSDでJailという仕組みが導入されました。これはchrootをさらに強化したもので、プロセス空間も隔離します。Jailによって、OSの中に仮想OSを作るような使い方ができるようになりました。2005年には、Solaris 10でSolaris Zones (Solaris Containers)という仕組みが導入されました。これはほぼ仮想サーバのような機能で、ZonesがあるからSolarisを使っていた方も多いんじゃないかと思います。Solaris 11では、Kernelまで隔離した、Kernel Zonesというほぼハイパーバイザのような機能も導入されました。

またも余談ですが、2014年にSolarisのVPのBill Nesheimさんといっしょに、Solarisの仮想化についてお話ししたことがありました。我ながら、面白い機会をいただいていてありがたいことです。 www.sbbit.jp

Linuxでのコンテナ型仮想化も歴史が長く、2000年代半ば頃から、OpenVZ/Virtuozzoや、Linux-Vserverがレンタルサーバなどによく使われていました。初期のDockerでも使われていたLXCや、LXCを便利にした感じのLXDや、systemdに統合されたsystemd-nspawnなど、様々な実装があります。 2013年にDockerが登場してからアプリケーションコンテナが一気に広まってきました。2014年にKubernetesが登場し、今回紹介するKata Containersは2017年に登場したかなり新しい技術です。

今ではすっかり、「コンテナ」と言えば「アプリケーションコンテナ」のことを指すようになってしまいましたが、私は単に「コンテナ」と言うと、コンテナ型仮想化(OSレベル仮想化・システムコンテナ)の方を想像してしまうので、なるべく「アプリケーションコンテナ」と言うようにしていたりします。コンテナ型仮想化は、仮想サーバと同じような使い方をしますが、アプリケーションコンテナはその延長線上にはないのではないかと思います。

アプリケーションコンテナと従来のコンテナ型仮想化は似ていないと言いましたが、アプリケーションコンテナはサーバ仮想化などのインフラの話よりも、アプリケーション開発やDevOpsの文脈で語られることが多いのではないかと思います。Dockerの典型的な使い方としては、ビルド、パッケージング、デプロイという流れになると思いますが、昔からあるサーブレットコンテナととてもよく似ていたりします。アプリケーションコンテナとは、仮想サーバを置き換えるものではなく、アプリケーションをデリバリするためのものであると捉えるのがわかりやすいと思います。

アプリケーションコンテナのセキュリティ

ガートナーが最近出しているリサーチによると、2019年時点で、アプリケーションコンテナを商用で使っている組織は、ワールドワイドで30%未満とのことです。しかし、2022年にはこれが75%超になると予想されています。 会場の方に、アプリケーションコンテナを商用で使っているか聞いてみたところ、日本のModern Cloud Dayでは10%未満でしたが、アメリカのOpen Worldでは30~40%くらいの方が手を上げました。ガートナーのリサーチはそれなりに当たっていそうな感じです。 ガートナーは同じ記事の中で、アプリケーションコンテナを商用で使うための、6つの重要な要素を挙げていて、その1番目に「セキュリティ&ガバナンス」を挙げています。

www.gartner.com

アプリケーションコンテナのセキュリティと一言に言っても、どうすればいいのかなかなか難しいです。NIST(米国国立標準技術研究所)がよくまとまった文書を公開しているので、そちらを参照してみましょう。NIST SP800シリーズはセキュリティ関連の文書で、SP800-190 はアプリケーションコンテナのセキュリティについてまとめられています。2017年9月に公開されたものなので、かなり新しい文書です。 その中で、アプリケーションコンテナの典型的なアーキテクチャは上の図のようなコンポーネントから成り立っていると述べられています。図の左から、開発者がコンテナイメージを作って、テストして、レジストリに登録して、管理者がオーケーストレータを使ってホストにデプロイする、という流れになっています。Docker、Kubernetes、DockerHubなどは、このアーキテクチャの実装例といえます。

SP800-190はこちらからダウンロードできます。 csrc.nist.gov

一部の文書はIPAが日本語化して公開しています。SP800-190はまだないようです。 www.ipa.go.jp

同文書の中で、アプリケーションコンテナには5つの主要なリスクがあると述べられています。5つのリスクとは、イメージのリスク、レジストリのリスク、オーケストレータのリスク、コンテナランタイムのリスク、ホストOSのリスクです。

コンテナイメージの中身は、概ね上のような図のようになっています。先ほど、アプリケーションコンテナはアプリケーションをデプロイするためのものだと述べました。誤解を恐れずに言えば、アプリケーションの開発者はほぼアプリケーションにしか興味がないことが多いんじゃないかと思います。でも、コンテナの中身はOSイメージそのものなので、インフラやセキュリティの人は、ライブラリやユーザランドが気になってしまうのではないかと思います。 でも一般に、アプリケーションコンテナの場合は、中に入ってプロセスを監視したりログを監視するようなことはあまりやりません。むしろお行儀が悪いと言われたりします。これは仮想サーバのように使うコンテナ型仮想化の場合とは異なるやり方が必要になりますが、セキュリティとしてはコンテナイメージの中身も見る必要があります。DevOpsにセキュリティを加えたDevSecOpsのような考え方が必要になるということだろうと思います。

次に、ホストOSのリスクの中の、Kernelの共有の項目に注目したいと思います。一般的に、アプリケーションコンテナ環境では、アプリケーションレベルで隔離が行われているものの、Kernelを共有しており、ハイパーバイザによる仮想化より隔離のレベルが低いと考えられます。Kernelを共有しているので、1つのアプリケーションコンテナが侵害されれば、ほかのアプリケーションコンテナもリスクにさらされる可能性が高いといえます。この手の攻撃が刺さる可能性はそう高くないかもしれませんが、カーネルを共有していることがセキュリティの論点になることはあるということです。

Kata Containers

Kernelの共有がセキュリティのリスクになることがあるということから、ようやくKata Containersの話に入ります。ハイパーバイザの技術を利用し、 アプリケーションの強い隔離を実現するコンテナランタイムで、OpenStack Foundataion(OSF)がサポートしています。2017/12に出たばかりのとても新しい技術です。 コンテナオーケストレータは、今のところKubernetesデファクトスタンダードといえますが、一方、コンテナランタイムはいろいろな特性を持ったものが出てきています。Kata Containersはかなりセキュリティに振り切ったコンテナランタイムだと言えます。

katacontainers.io

この図は、Kata Containersのアーキテクチャを模式図にしたものです。一般的なコンテナランタイムでは、左の図のように、Kernelを共有して、Namespaceの機能でアプリケーションを隔離します。それに対して、Kata Containersでは、アプリケーションコンテナ毎にKernelが分離するので、ハイパーバイザによる仮想化と同等の隔離を実現しています。

この図は、DockerとKata Containersの関連性を表したものです。kata-runtimeはLow-Levelのコンテナランタイムです。また、CNCFが策定したOCI Runtime Specificationに準拠しています。Dockerでは、通常runCがLow-Levelコンテナランタイムとして使用されますが、もちろんrunCもOCI Runtime Specificationに準拠しています。つまり、runCをkata-runtimeに置き換えることが可能ということになります。Kata ContainersはDockerやKubernetesを置き換えるものではなく、組み合わせて使うものと考えるのがよいと思います。

Kata Containersは、Oracle Linuxでは Oracle Linux Cloud Native Environment (OLCNE) の一部として取り込まれています。とはいえ、OLCNEという製品があるわけでもなく、サービスがあるわけでもありません。Oracle Linuxには、クラウドでのアプリケーション開発や運用に必要な機能がバンドルされているという、コンセプトのようなものだと私は理解しています。

Demo

こんな感じの環境で簡単なデモを行いました。仮想化にはVMware Playerを使いましたが、Oracle LinuxのPMのSimonさんは、VirtualboxのPMでもあるので、できればVirtualboxを使いたいと思っていました。Kata ContainersはKVMを使うので、仮想環境で動かすには、Nested VMができる必要があります。Virtualbox 6.0でAMDのCPUではNested VMに対応しているのですが、IntelのCPUではまだ対応していませんでした。VMware PlayerではIntel CPUでもNested VMができました。Virtualbox 6.1では、Intel CPUでもNested VMに対応予定のようなので、期待したいと思います。 イベントでは機材トラブルがつきものなので、デモをやるのは度胸が必要です。幸い日本でもアメリカでもデモ環境はすんなり動いてくれてよかったです。

デモのシナリオです。Docker Hubから取得した、Nginxのイメージを、Docker+runC と Docker+kata-runtime でそれぞれ起動するというデモを行いました。docker run の --runtime オプションを指定するだけで、必要に応じてコンテナランタイムを切り替えることができ、混在させることもできます。 Solaris 11をよく知っている方は、Native ZonesとKernel Zonesとの関係に似ていると考えるとわかりやすいんじゃないかと思います。

Oracle LinuxでKata Containersを使うのはわりと簡単です。この手順は、Developer Previewでの手順なので、GA(General Availability)になったら変わるかもしれませんのでご了承ください。

必要なYumリポジトリを有効化します。

# yum-config-manager --enable ol7_addons
# yum-config-manager --enable ol7_developer
# yum-config-manager --enable ol7_developer_kvm_utils

必要なRPMをインストールします。

# yum install docker-engine
# yum install qemu
# yum install oracle-olcne-release-el7
# yum install kata-runtime

Dockerの起動オプションを変更して、kata-runtimeを有効にします。

# vi /etc/sysconfig/docker
---
OPTIONS='-D --add-runtime kata-runtime=/usr/bin/kata-runtime'

# systemctl restart docker

Kata Containersを使用するには、KVMが有効になっている必要があります。

# lsmod
…
kvm     643072  1 kvm_intel

設定がうまくいっていれば、docker info でランタイムが追加されているのがわかります。

# docker info
…
Runtimes: kata-runtime runc

docker run でコンテナを起動すると、runCの場合は1秒くらいで起動しますが、kata-runtimeは仮想マシンを起動するので4~5秒くらいかかりました。パフォーマンスのテストは詳細にはやっていませんが、KVMで仮想化しているのと同じくらいのオーバーヘッドはあると考えられます。 pstreeでプロセスを見ると、runCのほうはNginxのプロセスが見えているのに対して、kata-runtimeのほうは、qemuのプロセスが見えて、たしかに仮想化されているのがわかります。Nginxのプロセスは仮想マシンの中なので、ホストOSからは見えなくなっています。

まとめ

というわけで、アプリケーションコンテナを商用環境で使うときにはそれ相応のセキュリティを考慮する必要があるということと、Kernelの共有はセキュリティリスクとして論点になりうるという話から、ハイパーバイザの技術でアプリケーションコンテナを隔離するKata Containersというコンテナランタイムについて紹介しました。今後、Kata Containersが主流になるかはまったくわかりませんが、コンテナランタイムは必要に応じて特性の違うものを使い分けるようなケースが増えてくるのではないかと考えています。

またも余談ですが、最後のスライドも自分で撮影してきた天体写真をぶっ込みました。2018年に、世界有数の美しい星空だと言われる、ニュージーランドのテカポ湖で撮影してきた天の川の写真です。 ニュージーランド旅行の記事はこちらから。 shakemid.hatenablog.com