前回は,root権限で起動するコンテナを使って多段にネストさせたコンテナを起動させたり,LXCコンテナ内でDockerを起動したりしました。今回は,一般ユーザで起動する非特権コンテナでネストを試してみます。16.04で採用された,一般ユーザに書き込み権限のあるcgroupを作るためのpam_cgfsも紹介します。pam_cgfsコンテナのネストを試す前に,一般ユーザ権限で起動する非特権コンテナで使用するpam_cgfsというPAMモジュールを紹介します。pam_cgfsはLXCFSに含まれています。Ubuntuではこれまで,cgmanagerやパッチを適用したsystemd-logindを使って,ユーザ権限で操作できるcgroupを作成し,非特権コンテナを起動してきました。16.04では,ログイン時にpam_cgfsというPAMモジュールを使って,ユーザ権限で操作できるcgroupを作成しています。pam_cgfsは,/etc/pam.d以下にある,いろいろなPAMの設定ファイルでincludeされているcommon-sessionやcommon-session-noninteractiveで,以下のように定義されています。freezer,memory,name=systemdオプションでユーザ向けのcgroupを作成するcgroupfsツリーを指定しています。16.04ではfreezer,memoryサブシステムと,systemd用のcgroupツリーにユーザ用のcgroupを作成し,initとしてsystemdを採用した非特権コンテナが起動できるように設定しています。これでログイン時にpam_cgfsによりユーザ所有のcgroupが作成されますので,一般ユーザ権限で起動したコンテナからcgroupが利用できます。非特権コンテナのネストLXCは一般ユーザによる特権を持たないコンテナでもネストをサポートしています。前回に試した特権コンテナと同じように,一般ユーザでネストしたコンテナを作成してみましょう。16.04上で実行しています。一般ユーザでコンテナを作成し,起動するための設定は,この連載の第17回をご参照ください。ここでは,ネストさせるすべての層で,コンテナを非特権コンテナとして起動してみます。この記事の例では,一般ユーザとしてubuntuユーザを利用しています。非特権コンテナをネストさせる場合のIDマッピング非特権コンテナ内で非特権コンテナを動かす際には注意が必要です。非特権コンテナの場合,コンテナ内のuid,gidとホストのuid,gidをマッピングさせました。注意が必要なのはその際のマッピングの数です。Ubuntuではユーザを追加すると,/etc/subuid,/etc/subgidに65536個のサブIDの定義を追加します。次のようになっています。/etc/sub{u,g}id/etc/subuid:ubuntu:165536:65536/etc/subgid:ubuntu:165536:65536これは通常システムを起動すると65536個のIDを使うためです。ホストOS上で上のような設定で非特権コンテナを起動すると,コンテナ(親コンテナ)内で65536個のuid,gidが利用できます。そのコンテナで65536個すべてのIDを消費してしまいますので,ネストして子コンテナを起動しようとすると,親コンテナから割り当てるIDがありません。UbuntuデフォルトのID割り当てコンテナをネストさせて,非特権の「親コンテナ」内でさらに非特権の「子コンテナ」を起動させるには,ホストOS上では65536*2=131072個のサブIDを割り当て,コンテナでも同じように設定しておく必要があります。2段ネストで非特権コンテナを起動するIDの割り当てネストした非特権コンテナの作成と起動それでは早速コンテナを作成し,起動していきましょう。今回はホスト上にコンテナを作成し,その子どものコンテナまで作成してみましょう。先の例で示したように,ホスト上では,親コンテナ分,子コンテナ分合わせて65536*2=131072個のIDを確保しておく必要があります。ユーザに対して131072個のサブIDを使えるようにする設定を行います。/etc/sub{u,g}id/etc/subuid:ubuntu:165536:131072/etc/subgid:ubuntu:165536:131072(ホストOS上でサブIDを165536から131072個割り当てる許可)準備ができたらコンテナを作成します。ユーザ権限で起動した親コンテナですのでuser-parentと名づけました。165536から131072個使用する設定)作成できたら,上のようにネストするためにnesting.confのinclude設定と,131072個のIDのマッピングを設定します。それでは,このコンテナを起動させてLXCをインストールしましょう。LXCをインストールする時はrootで作業する必要があります。(親コンテナにLXCインストール)LXCのインストール後に,コンテナを作成するユーザに対して,サブIDを許可する設定をしておきましょう。/etc/sub{u,g}idubuntu:65536:65536ubuntu:65536:65536(親コンテナ上でサブIDを65536から65536個割り当てる許可)設定ができたら,その一般ユーザでログインします。ここでuser-parentコンテナ上で,一般ユーザでコンテナを操作する際には少し注意が必要です。一般ユーザ(ここではubuntuユーザ)になった後に,/sys/fs/cgroup以下に存在するサブシステム用のディレクトリmemoryやfreezer配下のツリーにユーザ権限のcgroupが作成されているかチェックしてください。親コンテナにopenssh-serverをインストールしてubuntuユーザでsshログインするか,lxc-consoleコマンドで親コンテナのコンソールにアクセスしubuntuユーザでログインすると,pam_cgfs経由でユーザが権限を持つcgroupが作られるので確実だと思います。筆者が試した所,lxc-attachコマンドでコンテナに入り,suコマンドでubuntuユーザにスイッチした場合はcgroupが作られずにコンテナの起動に失敗しました。:(略)cgroupが存在していることが確認できたらコンテナを作成します。user-childと名づけました。65536から65536個のIDを割り当てる設定)上のように,コンテナ作成後に65536個のIDマッピングを設定します。これで子コンテナ"user-child"が起動するはずです。ネストした非特権コンテナのcgroup前回,特権コンテナでネストさせたときに確認したのと同様に,非特権コンテナでネストした場合にcgroupツリーがどうなるかを確認しておきましょう。ホスト上からfreezerサブシステムの様子を見てみます。directoriesここで,ツリー中の(ユーザ名)/(数字)はpam_cgfsがユーザ用に作成したcgroupです。「⁠数字」はログインセッションのIDです。親コンテナからfreezerサブシステム以下を見ると,上の実行例のツリーで,user-parentより下のツリーが見えていることがわかります。namespaceが機能していることがわかります。directoriesuser-childコンテナ内から見ると,普通にホスト上でcgroupfsがマウントされたときのようにcgroupのrootだけがある状態です。filesまとめ以上のように,今回は一般ユーザによる非特権コンテナをネストさせました。今回紹介したネストでは,いずれのコンテナも一般ユーザ権限でネストさせました。一般ユーザ権限で動いているコンテナ内でさらにコンテナを起動させる場合は,今回のようなややこしい設定を行わずに,そのままroot権限で起動させても問題がないケースも多いでしょう。ネスト元のコンテナが一般ユーザ権限で動いていれば,ネスト元のコンテナの親であるホストやコンテナ上では,そのネスト元のコンテナを実行しているユーザが持つ権限しかないからです。今回紹介したような,ネストさせたコンテナを一般ユーザ権限で起動するのは,ネストしたコンテナの親のコンテナに対しても権限を制限したい場合です。このようにネストさせるケースはあまりないかもしれません。LXCではこのように柔軟に権限を設定できるのだということを頭の片隅にでも置いておいていただいて,必要になった際にこちらを参照いただければと思います。その他に,ユーザ権限でのcgroupを作るための仕組みとしてpam_cgfsを紹介しました。pam_cgfsは今の所LXCFSに含まれていますが,LXCFSに密接に結びついているモジュールではありませんので,将来的にはLXCに含まれるようになるようです。前回の記事を書いてから今回の記事を書くまでの間に,LXCの新しいバージョンである2.1が公開されました。2.1では表面的には大きな機能の追加はないものの,設定項目がかなり変化していたり,細かい改良が行われていたりします。変更点については今後この連載で紹介したいと思います。PAM著者プロフィール加藤泰文(かとうやすふみ)2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。業務を改善する情報共有の仕掛け~DevOpsの実現,RPAの導入に向けて~ソフトウェア開発の業務改善をテーマに,DevOps実現の手順やそれを助けるツールとの連携,RPAによる社内ドキュメントの管理や効率化について解説します。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。