【和訳】コンテナとストレージの問題:
コンテナ普及の要因分析 #docker
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
本稿は2017年4月7日「Containers and Storage: Why We Aren’t There Yet」を和訳したものです。
IBMのコンテナ技術の専門家、James Bottomley氏の 先日ボストンで開催されたLinux Foundation Vault storage カンファレンスでの発表の内容によると、コンテナのオーケストレーション系の技術が多く登場しているが、定常的ストレージの問題が解決されなければ、本格的な普及は難しい、と述べている。
根本的な問題:ステートフルストレージ(恒常的ストレージ)はLinux系のアーキテクチャにおいては、外部ストレージシステムのファイルシステム自体のユーザID (fsuid) と コンテナ内で生成されるユーザID (uids) との連携を維持する事が出来ない事。
Linuxカーネル側は、superblock user namespaceの提供を通してこの問題の対応に取り組んでいるが完全なソリューションとは言いがたく、コンテナ側の努力もまだまだ必要である。
ネームスペースの世界
ここでLinuxのuser namespacesの重要な役割を知る必要がある、とBottomley氏は述べる。コンテナセキュリティはnamespacesに依存してることは知られているが、誤解が多いとのこと。本来セキュリティシステムというのはシステムから人を締め出すために存在するが、namespaceはその逆で、ユーザに大きな権限を与える事が役割である、と指摘している。
Root権限での処理はnamespace内では使えるが、その外では使うことはできない。例えば、mountコマンドをnamespace内で実行できても、普通のユーザとしては実行できない、等の制限がある。
ユーザのnamespaceは内部のinterior uidと外部のexterior uidをマッピングし、このexterior uidがカーネルから見えるもの。interior uidはコンテナ内のユーザが見えるもの。
この異なる世界を統合しようとして色々と努力がされているが、結局コンテナオーケストレーションのシステムは全てroot内で運用する、という問題性のある必要性を生んでしまっている。
「User namespaceに関するバグや問題はこういった統合の試みから生まれている。」とBottomley氏は述べる。例えば、ネットワークユーティリティ機能がnamespace内で稼働する事で、権限のエスカレーションに関連したセキュリティの問題が表面化する、と指摘している。Docker社がv1.10で実装した、user namespacesのサポートについても、問題の多い機能だ、と言い切っている。
従って、user namespace上のオペレーションは全てroot権限を持つオペレーションになる。業界全体が目指しているのは権限を持たないコンテナの運用であるが、クラウド上でデプロイする世界において、まだまだ道のりが長い、とBottomley氏は述べる。
大きな問題は、コンテナが外部ストレージにデータを書き込む時。ストレージシステムは通常自分のuidを持ち(上記のfsuid)、ユーザの持つカーネルuidと対応づけられている。カーネルがuidとfsuidとの間の連携を保つ。Root内のコンテナはuid=0を持ち、カーネルがそれをコンテナのオーナーの持つuid(fsuidに対応)に変換し、これはシステム上のすべてのユーザが見える様になる。
ここまでは問題ないが、コンテナを共有しようとすると問題が発生する。Docker Hubの様に、コンテナを共有できる環境において、それぞれ異なるroot環境で造られているコンテナの共存環境は混乱の要因になる。
どんなOSでも、コンテナ内では稼働するためにはuid=0(root権限)を持つ必要がある。しかし、そのままだとコンテナ内のOSが外部のファイルシステムをアクセスしようとするとアクセス権限エラーを受ける結果になる。コンテナイメージ上のIDが全くマッピングされて居ないので外部からは誰のものなのかがわからないからである。
という事で、コンテナには権限の付与が必要になる、という事に繋がる。しかし、単純にコンテナにusernameのrootではなく、システムのroot権限を与えるわけにはいかない。外部から来たコンテナに無条件にホストのroot権限をあげるわけにはいかないからである。たとえ、一部の権限を提供したとしても(一部のディレクトリへのアクセス、等)、大事なファイルの削除などの被害を被る事が簡単に起きる。
2016/10に、Linux 4.8がリリースされ、super block user namespace(変数名:s_user_ns)と呼ばれる機能が発表された。これは、Red Hat社のエンジニアでEric Biederman氏が開発したもの。s_user_ns は、コンテナ内のuser namespace上のuidを保持し、fuidスペースでの使用できる様にする。Bottomley氏によると、これにより特定のコンテナイメージから安全にファイルの実行や変更が可能になる、とのこと。
ただし、s_user_ns は、superblocksと呼ばれる、ファイルシステムが指定した特定の領域の上でしか使用できない、という制限がある。コンテナにおいては、Bind Mount機能を使ってディレクトリのコピーを作る必要があるが、この機能はSuper Block領域では使用できない。そのため、ShiftFSと呼ばれる、Super Block上でのBind Mountを可能にする機能を使う。要は、他のユーザとファイルシステムをコンテナ経由で共有したい場合はShiftFSを使う必要がある、ということ。
これにはセキュリティ上の危険性が伴う。オーケストレーションレイヤーでこのメカニズムを注意深く管理する必要があるため、オーケストレーションレイヤーに対してセキュリティ上の信用があって初めてこの仕組みが成立する、ということである。