Ubuntu Weekly Recipe

第521回 入門システムコンテナマネージャーLXD 3.0

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

LXDの基本的な使い方

コンテナのライフサイクルから,LXDの基本的な使い方を見ていきましょう。

インスタンスの作成と起動

まずコンテナのイメージからインスタンスを作成・起動する方法です。

$ lxc launch ubuntu:18.04 bionic
bionic を作成中
bionic を起動中

上記コマンドを実行することによりリモートイメージーサーバーであるubuntuから,イメージ名18.04をダウンロードし,bionicという名前でコンテナを作成かつ起動します。

LXDにはベースイメージファイルを公開するイメージサーバーという概念があります。ローカルのLXDサービス自身もイメージサーバーになるので,任意のイメージをインターネットに公開することも可能です。LXDには最初からいくつかのリモートイメージサーバーが登録されています。

$ lxc remote list
+-----------------+------------------------------------------+---------------+-----------+--------+--------+
|      NAME       |                   URL                    |   PROTOCOL    | AUTH TYPE | PUBLIC | STATIC |
+-----------------+------------------------------------------+---------------+-----------+--------+--------+
| images          | https://images.linuxcontainers.org       | simplestreams |           | YES    | NO     |
+-----------------+------------------------------------------+---------------+-----------+--------+--------+
| local (default) | unix://                                  | lxd           | tls       | NO     | YES    |
+-----------------+------------------------------------------+---------------+-----------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases | simplestreams |           | YES    | YES    |
+-----------------+------------------------------------------+---------------+-----------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily    | simplestreams |           | YES    | YES    |
+-----------------+------------------------------------------+---------------+-----------+--------+--------+

NAMEフィールドで指定された名前をイメージ名の前のコロンの前に追加することで,リモートイメージサーバーを指定できます。

URLとPROTOCOLのフィールドは提供元のURLとそのイメージの提供方法です。

AUTH TYPEフィールドはイメージサーバーとして利用するにあたって認証が必要かどうか,PUBLICフィールドはネットワーク上の他のマシンに公開されているかどうか,STATICはlxc remoteで設定変更可能かどうかを示します。

イメージサーバーからダウンロードするイメージは,原則として最新版です。特にubuntuイメージの場合,cloud-imageとして定期的にアップデートが適用されたイメージを公開していますので,インストーラーイメージとは違いほとんどすべてのパッケージの更新が適用済みの状態となります。ダウンロードしたイメージは次のコマンドで確認できます。

$ lxc image list
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
| ALIAS | FINGERPRINT  | PUBLIC |                 DESCRIPTION                 |  ARCH  |   SIZE   |         UPLOAD DATE          |
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
|       | 9879a79ac2b2 | no     | ubuntu 18.04 LTS amd64 (release) (20180522) | x86_64 | 172.97MB | May 27, 2018 at 9:10am (UTC) |
+-------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+

初回はダウンロードに時間がかかりますが,一度ダウンロードしたイメージファイルはキャッシュに保存されるため,次回からはすぐに作成できます。なお,LXDサービスがバックグラウンドでダウンロードしたイメージの更新作業も行います。

lxc launchコマンドは,実際には次の2つのコマンドを1つにまとめたものです。

$ lxc init ubuntu:18.04 bionic
$ lxc start bionic

もし作成したコンテナを起動する前に設定を行いたい場合は,lxc launchではなくこちらのコマンドを使うと良いでしょう。

コンテナの操作

作成したコンテナはlxc listコマンドで確認できます。

$ lxc list
+--------+---------+--------------------+-----------------------------------------------+------------+-----------+
|  NAME  |  STATE  |        IPV4        |                     IPV6                      |    TYPE    | SNAPSHOTS |
+--------+---------+--------------------+-----------------------------------------------+------------+-----------+
| bionic | RUNNING | 10.41.184.9 (eth0) | fd42:dbb6:9ea0:3ab0:216:3eff:fed7:124e (eth0) | PERSISTENT | 0         |
+--------+---------+--------------------+-----------------------------------------------+------------+-----------+

起動中のコンテナはSTATEフィールドがRUNNINGになります。IPアドレスが割り当てられているので,コンテナ内部でSSHサーバーが動いていたらそのままログインできます。

また,lxc infoコマンドでコンテナインスタンスの詳細を確認できます。

$ lxc info bionic
コンテナ名: bionic
リモート名: unix://
アーキテクチャ: x86_64
作成日時: 2018/05/27 09:10 UTC
状態: Running
タイプ: persistent
プロファイル: default
Pid: 2311
IPアドレス:
  eth0: inet    10.41.184.9     veth4335QT
  eth0: inet6   fd42:dbb6:9ea0:3ab0:216:3eff:fed7:124e  veth4335QT
  eth0: inet6   fe80::216:3eff:fed7:124e        veth4335QT
  lo:   inet    127.0.0.1
  lo:   inet6   ::1
リソース:
  プロセス数: 36
  CPU使用量:
    CPU使用量(秒): 6
  メモリ消費量:
    メモリ (現在値): 132.04MB
    メモリ (ピーク): 215.07MB
  ネットワーク使用状況:
    eth0:
      受信バイト数: 306.69kB
      送信バイト数: 12.77kB
      受信パケット: 331
      送信パケット: 158
    lo:
      受信バイト数: 892B
      送信バイト数: 892B
      受信パケット: 12
      送信パケット: 12

Ubuntuのcloud-imageの場合,SSHサーバーは起動しますし,⁠ubuntu」アカウントが自動的に作成されますが,パスワードが無効化されています。しかしながらcloud-initを使用しない限り,SSH公開鍵は設定されません。つまりリモートログインする方法がありません。プロダクション用途での正しい対応はcloud-initを利用して,コンテナ内部の初期設定を行うことですが,ここではad-hocに解決してみましょう。

lxc execコマンドを使うと,特定のコンテナに対して特定のコマンドを実行可能です。コマンドとしてbashを指定すると,コンテナ内部のrootアカウントとして「ログイン」できます※3)⁠

※3
実際はログインシェルとして動作するわけではなく,ログインしているように見えるというだけです。コンテナにローカルでログインするのであればlxc consoleが使えますが,ubuntuアカウントのパスワードが未設定である以上,こちらも利用できません。
$ lxc exec bionic bash
root@bionic:~#

たとえばGitHubに登録しているSSHの公開鍵を,ubuntuアカウントの~/.ssh/authorized_keysに追加したい場合は,ssh-import-idを使うと良いでしょう。

root@bionic:~# sudo -i -u ubuntu ssh-import-id gh:(GitHubのアカウント名)

コンテナ内部とファイルのやりとり

先程実行したbashのプロセスをコンテナの中から見てみましょう。

root@bionic:~# ps -f $$
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
root       321     0  0 09:49 ?        Ss     0:00 bash

コンテナの中のプロセスIDは321で,UIDはroot(UID=0)であることがわかります。しかしながらホスト上でps -fe | grep "321.*bash"しても該当するプロセスは見つかりません。これはプロセス名前空間を使って,コンテナ上のプロセスIDはホスト上のそれから分離されているためです。ホスト上の該当するプロセスは,プロセスのstatusファイルのNSpidフィールドで確認できます。

$ grep NSpid.*321$ /proc/*/status
/proc/22494/status:NSpid:       22494   321
$ ps -f 22494
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
165536   22494 22485  0 18:49 pts/5    Ss+    0:00 bash

これによりホスト上のプロセスIDは22494になっていることがわかります。さらにUIDも1665536になっています。これはコンテナ上のrootアカウントは,ホスト上から見るとrootではないということです。LXDでは特に設定しなければ非特権コンテナとして作成します。これによりコンテナ上で特権を取得できたとしても,かんたんにはホスト上の特権を取得できません。何か危険な動作をするかもしれないコードを環境を隔離して実行する際にもLXDは有効なのです。

ユーザー名前空間を用いたUID/GIDをホストから分離する仕組みは,root以外にも適用されます。プロセスもユーザー名も隔離されているため,コンテナとファイルのやり取りは何かと不便です。そこでLXDにはlxc fileを用いたファイルの管理方法が存在しています。

コンテナからファイルを取得する
$ lxc file pull コンテナ名/フルパス 保存先

コンテナにファイルを渡す
$ lxc file push ファイル コンテナ名/フルパス

コンテナ上のファイルを削除する
$ lxc file delete コンテナ名/フルパス

コンテナ上のファイルを編集する
$ lxc file edit コンテナ名/フルパス

気をつけなければいけないのは,コンテナ側のファイル名は「コンテナ名/フルパス」の書式であるということです。sampleコンテナの/etc/environmentならsample/etc/environmentになります。-⁠rオプションをつけると,再帰的に受け渡しします。またcpコマンドなどと同じく送信元のファイル(=最後の引数を除いたファイル)は複数指定可能です。その場合,保存先はディレクトリになります。⁠⁠-p」オプションを付けることで保存先のパスに合わせてディレクトリを作成します。

またlxc file pushの場合は,⁠--uid」⁠⁠--gid」⁠⁠--mode」オプションによって保存先のファイルオーナーやモードを変更できます。

単にファイルをやり取りするのであれば,SSH経由でも可能です。lxc fileを使う一番のメリットはコンテナ間でも同じインターフェースを使えることでしょう。特に別のホスト上にあるLXDサービスのコンテナに対してもlxc fileを用いてファイルを送受信することが可能です。

lxc file editで編集時に使用するテキストエディターは,環境変数VISUAL,環境変数EDITOR,editorコマンドの順番で評価されます。Ubuntuをインストールした直後の環境であれば,第518回でも紹介したGNU nanoが起動することでしょう。

コンテナを停止・終了する

lxc stopでコンテナを停止できます。

$ lxc stop bionic

もしうまく停止できないようなら--forceオプションを付けてみましょう。また,コンテナ内部でshutdownコマンドやhaltコマンド使っても停止できます。

一度停止したコンテナはlxc startで起動できます。また,lxc restartでコンテナを再起動できます。

startやstop,restartサブコマンドは--allを付けることで作成済みのすべてのコンテナに適用可能です。

コンテナを削除する

使わなくなったコンテナインスタンスはlxc deleteで削除できます。

$ lxc delete bionic

一度削除したコンテナインスタンスは復旧できませんので注意してください。

LXDでコンテナ生活を

このようにLXDを使うと,お手軽に隔離環境を構築できます。

今回は紹介しませんでしたが,Ubuntuの別のリリースはもちろんのこと,imagesリモートサーバーには他のディストリビューションイメージが用意されていますので,一台のマシンで複数のディストリビューションをテストできます。コンテナ機能を利用しているため,仮想マシンに比べるとほとんどリソースを消費しません。ノートPCで数十台のインスタンスを立ち上げることも可能なのです。

単に決まったサービスを立ち上げるだけであればDockerを始めとするOCI準拠なあれやこれやを使うほうがシンプルですし,ドキュメントやノウハウも豊富です。しかしながら本当に欲しいのはサービスではなく,サービスを動かすためのホストから隔離された環境であれば,LXDを試してみませんか?

著者プロフィール

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

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

コメント

コメントの記入