Ubuntu Weekly Recipe

第479回 LXDコンテナとホストの間でファイルを共有する方法

この記事を読むのに必要な時間:およそ 4 分

LXDを使っていると非特権コンテナであってもホストとコンテナ間で気軽にファイルを共有したいことがよくあります。今回はその手順をまとめておきましょう。

LXDと非特権コンテナ

LXDはかんたんにシステムコンテナを構築できるツールです。⁠コンテナ型仮想化」と言えばDockerが有名ですが,これは主に「1コンテナ1サービス」というアプリコンテナとしての使われ方が主流です。それに対してLXDは「普通のLinuxシステム」をひとつのコンテナの中に構築します。どちらかと言うとKVMやVirtualBox,VMWareの代わりに使うタイプのソフトウェアです。

用途の違いからDockerとLXDは排他的ではなく,適材適所に使い分けることができます。もちろんLXDの上でDockerを動かすことも可能です。DockerとLXDの違いについては第459回にまとめていますので,そちらも参照してください。

LXDでは原則として「非特権コンテナ」を構築します。非特権コンテナではユーザー名前空間を用いて,コンテナとホストの間でUIDやGIDのマッピングを行います※1)⁠このためコンテナ上のroot(UID=0)はホスト上ではUID=0以外のUID,つまりは一般ユーザーとして見えるのです。またそれ以外のコンテナの一般ユーザーはIDは別の値にマッピングされてシステムが起動することになります。

※1
LXDでも用いているコンテナ機能については本サイトで連載されているLXCで学ぶコンテナ入門が参考になります。続き,期待しています。
コンテナ上でのプロセス
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun08 ?        00:00:12 /sbin/init
root        47     1  0 Jun08 ?        00:00:02 /lib/systemd/systemd-udevd
root        48     1  0 Jun08 ?        00:00:09 /lib/systemd/systemd-journald

ubuntu   29285     1  0 17:52 ?        00:00:00 /lib/systemd/systemd --user
ubuntu   29286 29285  0 17:52 ?        00:00:00 (sd-pam)
ubuntu   29334 29283  0 17:52 ?        00:00:00 sshd: ubuntu@pts/0

ホスト上でのプロセス
UID        PID  PPID  C STIME TTY          TIME CMD
165536    4288  4226  0 Jun08 ?        00:00:12 /sbin/init
165536    4496  4288  0 Jun08 ?        00:00:02 /lib/systemd/systemd-udevd
165536    4498  4288  0 Jun08 ?        00:00:09 /lib/systemd/systemd-journald

166536   12123  4288  0 17:52 ?        00:00:00 /lib/systemd/systemd --user
166536   12127 12123  0 17:52 ?        00:00:00 (sd-pam)
166536   12177 12120  0 17:52 ?        00:00:00 sshd: ubuntu@pts/0

ホスト上では,root(UID=0)がUID=165536,ubuntu(UID=1000)がUID=166536になっていることがわかります。また,プロセス名前空間も使っているためPIDもコンテナとホストでずれていることがわかりますね。このようにコンテナの内部のrootを含めたユーザーはホストから隔離されています※2)⁠

※2
より厳密には他の名前空間の機能やAppArmor,seccompeなども用いて特権が必要な機能をホストから隔離もしくは制限しています。

実際にどの値にマッピングされるかは,デスクトップ版にあとからLXDをインストールするか,最初からLXDがインストールされているサーバー版を使うかで微妙に異なります。

  • デスクトップ版:コンテナ内部のUID/GIDの0から65535は,ホスト上では165536から231071にマッピングされる
  • サーバー版:コンテナ内部のUID/GIDの0から65535は,ホスト上では100000から165535にマッピングされる

本連載でも第475回第416回などで,ソースコードが明らかでないデスクトップ向けアプリのバイナリを隔離環境で動かす際に利用していました。ただしこのままだとコンテナ内部のアプリが作ったデータをホストに移動するのは大変ですし,逆も同じです。特に一般ユーザーのUIDとGIDが異なるため,単純に移動してもそのままでは変更できないことがあります。そこで今回はホストとゲストでシームレスにファイルのやり取りが行える仕組みを考えます。

LXDコンテナ環境の準備

まずはLXD環境を構築しましょう。LXDはUbuntu 16.04 LTS以降であれば簡単に構築できます。Ubuntu 16.04 LTSの公式リポジトリであれば2.0系,それより新しいリリースであればより新しいLXD 2.xがリポジトリに用意されているからです。また16.04のバックポートリポジトリから最新版をインストールできます。2.xのほうがいろいろと機能追加されていて便利なのですが,バージョンも頻繁にアップデートされるため,Ubuntuのサポートの範囲内で安定的に運用するなら2.0を使うことをおすすめします。今回の記事に関しては,2.0でも2.x系のUbuntuリポジトリ上の最新版である2.14でも動くように記述しています。

最初にLXDをインストールします。サーバー版のUbuntu 16.04 LTSであれば,最初からインストールされているはずです。明示的にインストールする場合は,次のコマンドを実行してください。

$ sudo apt install lxd

インストールと同時にlxdグループが作成され,sudoを実行できるユーザーは自動的にlxdグループに所属します。グループの変更を反映するために,一度ログインしなおしましょう。lxdグループに所属すると,sudoなしにlxcコマンドを実行できるようになります。

次にLXDの初期設定を行います。LXDはsudo lxd initによって,全体的な初期設定を行えます。設定するのはストレージのバックエンド(コンテナのルートファイルシステムをどのように保存するのか)とコンテナのネットワーク設定です。というわけで,インストール直後に一回だけ実行します。

$ sudo lxd init

基本的に既定の設定をそのままOKしていくだけです。詳しいことはUbuntu Weekly Recipeの第459回の2ページ目を参照してください。

次にUbuntu 16.04 LTSベースのコンテナ(コンテナ名:sample)を作ります。

$ lxc init ubuntu:16.04 sample
sample を作成中
$ lxc start sample
$ lxc exec sample -- sudo -iu ubuntu ssh-import-id lp:(Launchpadのアカウント)
$ lxc list
+---------+---------+--------------------------------+----------------------------------------------+------------+-----------+
|  NAME   |  STATE  |              IPV4              |                     IPV6                     |    TYPE    | SNAPSHOTS |
+---------+---------+--------------------------------+----------------------------------------------+------------+-----------+
| sample  | RUNNING | 10.101.57.183 (eth0)           | fd2f:cd:157d:2362:216:3eff:fe5e:6952 (eth0)  | PERSISTENT | 0         |
+---------+---------+--------------------------------+----------------------------------------------+------------+-----------+

これでコンテナは完成です。Ubuntuコンテナは最初からOpenSSHサーバーが動いています。ただしubuntuユーザーのパスワードがロックされているためそのままではログインできません。そこでssh-import-idコマンドで,コンテナ内部のubuntuユーザーのホームディレクトリにLaunchpadから公開鍵をダウンロードしています。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入