ニュースのトップページに戻る

LXC 2.1 リリースのお知らせ

2017/09/05

LXC チームは LXC 2.1 のリリースをお知らせすることを誇りに思います。
このリリースには LXC 2.0 以降に追加されたたくさんの機能が含まれています。

このリリースは LTS リリースではないことに注意してください。LTS リリースではありませんので、LXC 2.1 のサポートは 1 年間のみです。長い期間のサポートが必要なプロダクション環境では 2021 年 6 月までサポートされる LXC 2.0 を使い続けてください。

新機能

リソース制限のサポート

cgroupを使った制限を指定するのと同じように、コンテナの設定ファイル内で、制限名に "lxc.prlimit." というプレフィックスをつけて、カーネルが対応しているすべてのリソースの制限を設定できます。例えば、プロセス数の制限を設定し、同時に nice 値を指定するには、コンテナの設定ファイルで次のように指定します:

lxc.prlimit.nproc = unlimited
lxc.prlimit.nice = 4

非特権での Open vSwitch ネットワークのサポート

非特権ユーザで次のように openvswitch ネットワークを定義できるようになりました:

lxc.net.0.type = veth
lxc.net.0.link = ovsbr0
lxc.net.0.flags = up
lxc.net.0.name = eth0

LXC 2.1 は、シャットダウン時に openvswitch からホスト側の veth デバイスを適切に削除する処理を行います。

新たな設定項目 lxc.cgroup.dir

lxc.cgroup.dir を設定することで、コンテナ用の cgroup を作成する親となる cgroup 名を指定できるようになりました。lxc.cgroup.dir はシステムワイドの設定である lxc.cgroup.pattern を上書きします。

例えば、lxc.uts.name = c1 と設定されたコンテナに lxc.cgroup.dir = mycontainers と設定すると、LXC は cgroup 階層内のすべてのコントローラで、mycontainers/c1 という cgroup を作ります。

hybrid cgroup レイアウトのサポート

cgroup v2 が導入されてから、一部の init システムでは cgroup v1 のコントローラごとの階層と、空の cgroup v2 階層を同時に使える hybrid モードが使えるようになりました。hybrid モードを使うシステムは、通常は次と同じような cgroup レイアウトになります:

  /sys/fs/cgroup/blkio
  /sys/fs/cgroup/devices
  /sys/fs/cgroup/memory
  /sys/fs/cgroup/unified

マウントポイント /sys/fs/cgroup/unified は、通常は cgroup v2 階層の存在を示します。これは findmnt | grep cgroup2 が一致する行を返すかどうかをテストすることで確認できます。LXC 2.1 はこの hybrid モードをサポートします。

コンテナが割り当てることができる pty の数を制限する

lxc.pty.max を設定すると、LXC は、使える pty の数に指定した制限を設定した上で、コンテナの devpts をマウントします。例えば、lxc.pty.max = 10 と設定すると、コンテナは 10 個の pty だけしか割り当てられません。デフォルト値は 1024 です。

bool lxc_config_item_is_supported(const char *key) API 拡張

この関数は、特定の設定項目がライブラリでサポートされているかどうかをユーザが問い合わせるための関数です。この関数は、標準的な liblxc ライブラリや、新しい設定項目がバックポートされた liblxc よりもはるかに少ない設定オプションを持つ liblxc のバージョンを実行する組み込みユーザに特に役に立つでしょう。

新しいログ API 拡張

struct lxc_log {
    const char *name;
    const char *lxcpath;
    const char *file;
    const char *level;
    const char *prefix;
    bool quiet;
};

/*!
 *\brief Initialize the log
 *
 *\param log lxc log configuration.
 */
int lxc_log_init(struct lxc_log *log);

/*!
 * \brief Close log file.
 */
void lxc_log_close(void);

上記の構造体や関数は、ユーザが LXC のロギングを初期化できるようにするためのものです。liblxc の API を直接使うユーザには役に立つでしょう。

lxc-monitord が廃止予定に

LXC 2.1 から lxc-monitord バイナリは廃止予定になりました。デーモン化されたコンテナの起動には lxc-monitord はもう不要です。代わりに、LXC 2.1 では abstract unix ドメインソケットペアを使った実装に切り替えました。これは、LXD のような高度にスレッド化されたコンテナの起動において、起動するプロセスがひとつ少なくなるという利点があります。

また、重い負荷で行った新しい実装のテストで、このソリューションがより堅牢で信頼性が高いことがわかりました。

lxc-copytmpfs 上にスナップショットを作ります

-e オプションを付けて起動した一時的 (ephemeral) なコンテナは tmpfs 上に置かれます。
tmpfs 上にコンテナを置きながらデータの保存は要求できません。そして、バッキングストアとして overlay か aufs を使わなければならず、オリジナルのコンテナは directory でなくてはいけません。

overlay もしくは aufs ファイルシステムを使った一時的なスナップショットのために、ユーザの要求に応じて新しい tmpfs がコンテナディレクトリ上にマウントされます。これは最も簡単なオプションです。それ以外の場合は、現在の overlay と aufs スナップショットのマウントレイアウトを変更する必要があります。標準では overlay と aufs のスナップショットクローンのレイアウトは次のようになります:

        /var/lib/lxc/CLONE_SNAPSHOT/delta0      <-- upperdir
        /var/lib/lxc/CLONE_SNAPSHOT/rootfs
        /var/lib/lxc/CLONE_SNAPSHOT/olwork
        /var/lib/lxc/CLONE_SNAPSHOT/olwork/work <-- workdir

with the lowerdir being

        /var/lib/lxc/CLONE_PARENT/rootfs

upperdir と workdir がコンテナディレクトリ以下の共通のサブディレクトリ内に置かれていないということは、新しい tmpfs を単純に upperdir と workdir の下にマウントできないということになります。なぜなら overlayfs はこのふたつが同じファイルシステム上にあることを期待しているからです。

コンテナディレクトリ上に新しい tmpfs をマウントするので、upperdir (現在はデフォルトで "delta0" という名前) 内にクローン中に作成される、更新された /etc/hostname ファイルが隠されてしまいます。

したがって、ユーザが古い名前をクローンで保存しないように要求した場合は、このファイルを tmpfs 上に再作成します。
これで、通常のクローン処理での正確な動作をリストアするために必要なことすべてのはずです。
注: もしコンテナを再起動した場合、すべての変更は失われます。リブートごとに rootfs が再度マウントされますので、これを防ぐのは容易ではありません。

設定項目名の変更

コンテナの設定がより一貫性を持って行えるように、多数の設定項目の名前が変わりました。
LXC 2.1 では、すべての設定項目が "." で分けられた適切なネームスペースから構成されるサブキーを持つようになりました。

ネットワーク設定

ネットワークの設定で、新しいプレフィックスを導入しました。いくつかの項目はリネームされました。
LXC 2.1 からは、(以前の) "lxc.network" を使ったネットワークの設定項目は廃止予定という扱いになります。
これは "lxc.net" プレフィックスを使った設定に置き換えられます。
さらにインデックスを使わないネットワーク定義は廃止予定とマークされます。次のようなネットワーク設定は legacy なネットワーク設定であるとみなされます:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.name = wlp2s0

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxcbr0
lxc.network.name = eno1

上の設定は 2 つの異なったネットワークを定義しています。LXC 2.1 以降は、次のように置き換えてください:

lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = lxcbr0
lxc.net.0.name = wlp2s0

lxc.net.1.type = veth
lxc.net.1.flags = up
lxc.net.1.link = lxcbr0
lxc.net.1.name = eno1

この方法だけで定義を行うと、定義する順序には依存しない、一貫性のある定義になる利点があります。
つまり、次のような 2 つのネットワークの設定と同等となります:

lxc.net.1.link = lxcbr0
lxc.net.0.name = wlp2s0
lxc.net.0.type = veth

lxc.net.1.type = veth
lxc.net.1.flags = up
lxc.net.0.flags = up
lxc.net.0.link = lxcbr0
lxc.net.1.name = eno1

同じインデックスの同じ設定が複数ある場合は、LXC は最後の設定を採用することに注意が必要です。これはこれまでのバージョンの LXC と同じ動作です。例えば:

lxc.net.2.link = lxcbr0
lxc.net.2.link = lxdbr0
lxc.net.2.link = br0
lxc.net.2.link = virbr0

上のような設定では、LXC は、最後の設定が virbr0 に設定されているため、ネットワークは virbr0 に関連付けられます。

変更された設定項目一覧

次の表は左の列に以前の設定項目 ("Legacy Key") を、右の列に変更後の設定項目 ("New Key") を一覧したものです。完全に削除された項目は、"New Key" に "-" と表記し、"Comments" 欄に "removed" と書いています。

Legacy Key                           | New Key                       | Comments
-------------------------------------|-------------------------------|---------
lxc.aa_profile                       | lxc.apparmor.profile          |
lxc.aa_allow_incomplete              | lxc.apparmor.allow_incomplete |
lxc.console                          | lxc.console.path              |
lxc.devttydir                        | lxc.tty.dir                   |
lxc.haltsignal                       | lxc.signal.halt               |
lxc.id_map                           | lxc.idmap                     |
lxc.init_cmd                         | lxc.init.cmd                  |
lxc.init_gid                         | lxc.init.gid                  |
lxc.init_uid                         | lxc.init.uid                  |
lxc.kmsg                             | -                             | removed
lxc.limit                            | lxc.prlimit                   |
lxc.logfile                          | lxc.log.file                  |
lxc.loglevel                         | lxc.log.level                 |
lxc.mount                            | lxc.mount.fstab               |
lxc.network                          | lxc.net                       |
lxc.network.                         | lxc.net.[i].                  |
lxc.network.flags                    | lxc.net.[i].flags             |
lxc.network.hwaddr                   | lxc.net.[i].hwaddr            |
lxc.network.ipv4                     | lxc.net.[i].ipv4.address      |
lxc.network.ipv4.gateway             | lxc.net.[i].ipv4.gateway      |
lxc.network.ipv6                     | lxc.net.[i].ipv6.address      |
lxc.network.ipv6.gateway             | lxc.net.[i].ipv6.gateway      |
lxc.network.link                     | lxc.net.[i].link              |
lxc.network.macvlan.mode             | lxc.net.[i].macvlan.mode      |
lxc.network.mtu                      | lxc.net.[i].mtu               |
lxc.network.name                     | lxc.net.[i].name              |
lxc.network.script.down              | lxc.net.[i].script.down       |
lxc.network.script.up                | lxc.net.[i].script.up         |
lxc.network.type                     | lxc.net.[i].type              |
lxc.network.veth.pair                | lxc.net.[i].veth.pair         |
lxc.network.vlan.id                  | lxc.net.[i].vlan.id           |
lxc.pivotdir                         | -                             | removed
lxc.pts                              | lxc.pty.max                   |
lxc.rebootsignal                     | lxc.signal.reboot             |
lxc.rootfs                           | lxc.rootfs.path               |
lxc.se_context                       | lxc.selinux.context           |
lxc.seccomp                          | lxc.seccomp.profile           |
lxc.stopsignal                       | lxc.signal.stop               |
lxc.syslog                           | lxc.log.syslog                |
lxc.tty                              | lxc.tty.max                   |
lxc.utsname                          | lxc.uts.name                  |

lxc-update-config スクリプト

LXC 2.1 には新しく lxc-update-config スクリプトが付属します。これは、以前の設定項目名を LXC 2.1 で有効な設定にアップグレードするのに使えます。次のように実行します

lxc-update-config -c /path/to/config

このスクリプトは、最初に現在の設定ファイルのバックアップを取得します。
バックアップファイルの名前は `.backup です。
バックアップファイルは、万が一、アップグレードで生成した設定ファイルが LXC 2.1 で使えないのに備えて作成します。
バックアップを生成したあと、スクリプトが以前の設定が新しい設定に置き換えます。

廃止予定の警告

LXC 2.1 は 2.1 より前の設定ファイルとの完全な下位互換性を持っています。
つまり、いかなる廃止予定の設定であっても、コンテナが使えなくなるようにはなりません。しかし、LXC 2.1 は廃止予定の設定があると警告を行います。コンテナの起動時に、LXC 2.1 は 一度だけ 次のような警告メッセージを出力します:

The configuration file contains legacy configuration keys.
Please update your configuration file.

すべてのユーザは、前述の lxc-update-config スクリプトを使って、設定ファイルを更新することをおすすめします。
コンテナでロギングが有効な場合、ログには検出された以前の設定項目に関する警告が含まれます。ログを使えば、手動で設定ファイルを更新するほうが好きなユーザの役に立つでしょう。

変更点

  • コア :

    • af unix: ソケット名を最大長まで指定できるようになりました (訳注: Abstract unix ソケットの名前)
    • af_unix: いくつかの関数で同時に複数の fd を送受信できるようにしました
    • android: 32bit の prlimit の実装を追加しました
    • API: lxc_log_init を API として公開しました
    • API: lxc_config_item_is_supported() 関数を追加しました
    • caps: lxc_{proc,file}_cap_is_set() 関数を追加しました
    • cgroups: hybrid cgroup レイアウトを扱えるようになりました
    • commands: EINTR を扱うようになりました
    • commands: lxc_cmd_state_server() 関数を追加しました
    • commands: API を新しいコールバックシステムへ切り替えました
    • conf: リソース制限を実装しました
    • conf: new{g,u}idmap で必要な特権を持っているかチェックするようになりました
    • conf: /dev/ptmx でバインドマウントを使うようになりました
    • conf: マウントオプションに MS_LAZYTIME を追加しました
    • conf: 設定されていない場合は tty を送らないようになりました
    • conf: tty を 2 つ同時に送るようにしました
    • conf: lxc-user-nic の出力をログするようにしました
    • conf: ネットワークの削除を再構築しました
    • conf: コア関数を書き直しました
    • conf: lxc_map_ids() 関数を改良しました (訳注: コマンドの権限と存在のチェックを追加)
    • conf: uid,gidのマッピングは最小限だけ使うようにしました
    • conf: euid != 0 でも uid マッピングが書き込めるようになりました (訳注: 非特権ユーザが自身の id だけをマップできるようになりました)
    • conf: /dev/console 上のすべてのマウントをアンマウントするようになりました
    • conf{,ile}: 以前の設定項目の場合、ユーザに一度だけ警告するようになりました
    • confile: lxc_get_idmaps() 関数を追加しました (訳注: コンテナが定義したidmapを取得する)
    • confile: コールバックシステムを作りなおして拡張しました
    • confile: パフォーマンスの調整を行いました
    • confile: "lxc.cgroup.dir" を追加しました
    • confile: namespace内の設定項目を一覧できる関数を追加しました (訳注: "lxc.net"のようにキーを与えると、そのnamespaceに属する設定項目を一覧する)
    • confile: lxc_getconfig() -> lxc_get_config()
    • confile: get_network_config_ops() 関数を改良しました
    • confile: lxc_list_net() のファイル内での位置を移動しました
    • confile: lxc_listconfigs -> lxc_list_config_items
    • confile: lxc_list_net() を作りなおしました
    • confile: lxc.seccomp --> lxc.seccomp.profile
    • confile: lxc.pts --> lxc.pty.max
    • confile: lxc.tty --> lxc.tty.max
    • confile: lxc.net.ipv6 --> lxc.net.ipv6.address
    • confile: lxc.net.ipv4 --> lxc.net.ipv4.address
    • confile: lxc.mount --> lxc.mount.fstab
    • confile: lxc.console --> lxc.console.path
    • confile: lxc.rootfs --> lxc.rootfs.path
    • confile: lxc.rootfs.backend は廃止予定になりました (訳注: lxc.rootfs.pathでパスと同時に設定するようになった。例: lxc.rootfs.path = btrfs:/path/to/root)
    • confile: lxc.utsname --> lxc.uts.name
    • confile: lxc.devttydir --> lxc.tty.dir
    • confile: シグナル用の namespace である lxc.signal を新設しました
    • confile: ログ用の namespace である lxc.log を新設しました
    • confile: コンテナの init 用の namespace である lxc.inet を新設しました
    • confile: lxc.limit --> lxc.prlimit
    • confile: lxc.pivotdir を廃止しました
    • confile: lxc.kmsg を廃止しました
    • confile: セキュリティ関連の namespace を適切に設定しました (訳注: lxc.apparmorlxc.selinux)
    • doc: 新しい設定項目に書き換えました
    • devpts: マウント時に max= を使うようになりました
    • lsm/AppArmor: コンテナが AppArmor namespace 内で起動できるようになりました
    • lxccontainer: インデックスで指定されたネットワークをすべてクリアするようになりました
    • lxccontainer: 新しいコールバックシステムに API を切り替えました
    • lxc-init: exec*() の失敗を報告するようになりました
    • lxc-user-nic: 指定したユーザやリンク以外の行を削除しないようにしました
    • lxc-user-nic: データベースにエントリを追加する際の問題を修正しました
    • lxc-user-nic: 消去する前にデータベースをチェックするようにしました
    • lxc-user-nic: delete コマンドを実行する際にネットワーク名前空間上で必要な権限があるかどうかチェックするようにしました
    • lxc-user-nic: ネットデバイスをリネームする処理を書き換えました
    • lxc-user-nic: 新たに create と delete というサブコマンドを追加しました
    • monitor: abstract ソケットのロジックを簡素化しました
    • network: 作成していないネットワークデバイスを削除しないようにしました
    • network: lxc_mkifname() を使う場面ではメモリを確保しないようにしました
    • network: netpipe の使用を削除しました
    • network: 正しいネットワークデバイス名を使うようになりました
    • network: 保存した物理ネットデバイスの記録を止めました
    • network: 正しいネットワークデバイス名とインターフェースインデックスを取得するようになりました
    • network: ネットデバイス名にはサイズを静的に割り当てた変数を使うようになりました
    • network: ホスト側の veth デバイスのインターフェースインデックスを取得するようになりました
    • network: ネットワーク作成部分を作り直しました
    • network: 非特権ネットワークのための Open vSwitch を削除しました
    • network: インターフェースインデックスをログに記録するようにしました
    • network: 非特権ネットワークでインターフェースインデックスを使うようにしました
    • network: レガシーネットワークではマイナス値を返すようにしました
    • network: 新しいネットワーク設定パーサをテストするようにしました
    • network: 新しいネットワークパーサを追加しました
    • network: 下位互換性を確保するようにしました
    • network: 設定アイテムのテストスイートを追加しました
    • openvswitch: ポートをインテリジェントに削除するようにしました
    • README: CII Best Practices のバッヂを追加しました
    • seccomp: 利用出来る場合は SCMP_FLTATR_ATL_TSKIP をセットするようにしました
    • start: lxc_check_inherited() を一般化しました
    • start: デーモンとして起動する場合は分離したソケットを使うようにしました
    • start: SOCK_DGRAM から SOCK_STREAM へ切り替えました
    • start: data_sock を使っている側が fd を close しないようにしました (訳注: fd を作成していない関数内で閉じないようにした)
    • start: cgroup が確実にクリーンアップされるようにしました
    • start: utmp をウォッチするのをやめました
    • start: unshare(CLONE_NEWCGROUP) のあとで lxc_setup() するようにしました
    • start: pty スレーブに std{in,out,err} を複製するようにしました
    • start: lxc_init_handler() を追加しました
    • start: lxc_free_handler() を追加しました
    • start: 特権の場合に rootfs を pin するようにしました
    • storage: lxc_storage_get_path() 関数を追加しました (訳注: コンテナディレクトリのパスを返す)
    • storage: storage_utils.{c.h} を追加しました
    • storage: "overlay" という名前も有効なバックエンド名として受け付けるようにしました
    • storage: ストレージ関係のファイル名やディレクトリ名に付いていた "bdev" という文字列を "storage" に変更しました。
    • storage/aufs: 廃止予定になりました
    • storage/btrfs: btrfs ストレージドライバを作りなおしました
    • storage/loop: loop ストレージドライバを作りなおしました
    • storage/lvm: lvm バックエンドを作りなおしました
    • storage/overlay: overlay ストレージドライバを作りなおしました
    • storage/overlay: スナップショットから正しくリストアされるようにしました
    • storage/overlay: 依存のトラッキングが正しく扱われるようにしました
    • storage/rbd: rbd ストレージドライバを作りなおしました
    • storage/zfs: zfs ストレージドライバを作りなおしました
    • tests: lxc.cgroup.dir のテストを追加しました
    • test: サブキーを取得するテストを追加しました
    • tests: idmap パーサのユニットテストを追加しました
    • tests: すべての設定項目に対してすべてメソッドが実装されているかのチェックを追加しました
    • tree-wide: struct bdev -> struct lxc_storage
    • utils: lxc_nic_exists() 関数を追加しました
    • utils: ファイルシステムタイプを判別する部分は has_fs_type() を使うように変更しました
    • utils: has_fs_type() + is_fs_type() を追加しました
    • utils: lxc_deslashify() 関数を作りなおしました
    • utils: lxc_make_abstract_socket_name() 関数を追加しました
    • utils: lxc_safe_ulong() 関数を追加しました (訳注: 数値の文字列を unsigned long に変換)
    • utils: lxc_unstack_mountpoint() 関数を追加しました (訳注: 与えたパスのマウントをすべてアンマウントする)
  • テンプレート:

    • templates/Alpine: ppc64le のサポートを追加しました
    • templates/Alpine: ランダムにミラーを選ぶのではなく dl-cdn.a.o をデフォルトのミラーとして使うようになりました
    • templates/Alpine: デフォルトリポジトリにコミュニティリポジトリを追加しました
    • templates/CentOS: i386 と x86_64 以外のアーキの CentOS では AltArch ミラーを使うようになりました
    • templates/CentOS: デフォルトを CentOS 7 にしました
    • templates/debian: デフォルトの Debian ミラーとして deb.debian.org を使うようになりました
    • templates/debian: buster を有効なリリースとして追加しました
    • templates/opensuse: leap 42.3 をサポートしました
    • templates/opensuse: Tumbleweed でのソフトウェアの選択の問題を修正しました
    • templates/opensuse: Tumbleweed をサポートするリリースに追加しました
    • templates/ubuntu: 新しいリリースではデフォルトで netplan をサポートするようになりました
    • templates/ubuntu: upstart の ssh ジョブは現在オプショナルなので、条件付きで mv するようにしました。
    • userns.conf: 必要がなくなった bind マウントは削除しました
  • ツール:

    • lxc-execute: 失敗時にエラーメッセージを表示するようにしました
    • lxc-update-config: レガシーなネットワークを変換できるようになりました
    • tools: 追加の cgroup のチェックを行うようになりました
    • tools: lxc-update-config を追加しました
    • tools/lxc-attach: /dev/tty がない環境でもアタッチできるようになりました
    • tools/lxc-checkconfig: CONFIG_NETFILTER_XT_MATCH_COMMENT を追加しました
    • tools/lxc-checkconfig: new[ug]idmap が setuid-root されているかを確認するようになりました
    • tools/lxc-ls: デフォルトではすべてのコンテナを返しますが、新しいフィルタとして定義済みのコンテナのみリストできるようになりました

ダウンロード

このリリースの tarball は ダウンロードページ から取得できます。そして、各ディストリビューションがすぐに LXC 2.1 のパッケージをリリースするでしょう。

個々の変更点に興味がある場合、そして開発の履歴を見たい場合、stable ブランチが GitHub にあります。