「Linux コンテナ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
7行目: 7行目:
 
{{Related|Cgroups}}
 
{{Related|Cgroups}}
 
{{Related|Docker}}
 
{{Related|Docker}}
{{Related4|OpenVPN}}
+
{{Related|OpenVPN}}
 
{{Related4|OpenVPN in Linux containers}}
 
{{Related4|OpenVPN in Linux containers}}
  +
{{Related|PeerGuardian Linux}}
 
{{Related|systemd-nspawn}}
 
{{Related|systemd-nspawn}}
 
{{Related articles end}}
 
{{Related articles end}}
24行目: 25行目:
   
 
=== ホストネットワークの設定 ===
 
=== ホストネットワークの設定 ===
LXC は様々なタイプの仮想化ネットワークをサポートしています。仮想ネットワークではほとんどの場合、ホスト側にブリッジデバイスが必要になります。以下で示しているブリッジの作成例に限られることはありません。例証として見て下さい。他のプログラムを使って同じようにネットワークを構築することも可能です。
+
LXC は様々なタイプの仮想化ネットワークをサポートしています。仮想ネットワークではほとんどの場合、ホスト側にブリッジデバイスが必要になります。以下で示しているブリッジの作成例に限られることはありません。例証として見て下さい。他のプログラムを使って同じようにネットワークを構築することも可能です。以下では有線と無線の例を示していますが、他のセットアップも可能です。他の方法については[[ネットワークブリッジ]]の記事を参照してください
   
  +
==== 有線ネットワークの例 ====
{{Note|Select only '''one''' of the methods below to implement the bridge on the host!}}
 
 
==== netctl だけを使用する例 ====
 
 
{{Pkg|netctl}} は[[公式リポジトリ]]からインストールすることができます。ブリッジのテンプレートは {{ic|/etc/netctl/examples}} に存在します。ホストネットワークのハードウェアの仕様やホストネットワークの IP の範囲にあわせて編集するようにしてください。以下2つのブリッジの設定例を記載していますが、片方は dhcp を使っており、もう片方は固定 IP で設定しています。
 
{{Pkg|netctl}} は[[公式リポジトリ]]からインストールすることができます。ブリッジのテンプレートは {{ic|/etc/netctl/examples}} に存在します。ホストネットワークのハードウェアの仕様やホストネットワークの IP の範囲にあわせて編集するようにしてください。以下2つのブリッジの設定例を記載していますが、片方は dhcp を使っており、もう片方は固定 IP で設定しています。
   
57行目: 56行目:
 
次に進む前にホストからネットワークにちゃんと接続されているか確認してください。ping を実行することで確認できます:
 
次に進む前にホストからネットワークにちゃんと接続されているか確認してください。ping を実行することで確認できます:
 
$ ping -c 1 www.google.com
 
$ ping -c 1 www.google.com
 
==== bridge-utils だけを使用する例 ====
 
Placeholder for someone using this setup.
 
   
 
==== 無線ネットワークの例 ====
 
==== 無線ネットワークの例 ====
67行目: 63行目:
 
iptables を使って NAT を行うようにホストを設定:
 
iptables を使って NAT を行うようにホストを設定:
   
# iptables -A POSTROUTING -o <var>wlp3s0</var> -j MASQUERADE
+
# iptables -t nat -A POSTROUTING -o ''wlp3s0'' -j MASQUERADE
   
{{ic|<var>wlp3s0</var>}} は無線インターフェイスの名前に置き換えて下さい。パケット転送はデフォルトでは無効化されているので、[[インターネット共有#パケット転送の有効化|カーネルパラメータを変更]]して有効にします:
+
{{ic|''wlp3s0''}} は無線インターフェイスの名前に置き換えて下さい。パケット転送はデフォルトでは無効化されているので、[[インターネット共有#パケット転送の有効化|カーネルパラメータを変更]]して有効にします:
   
 
# echo 1 > /proc/sys/net/ipv4/ip_forward
 
# echo 1 > /proc/sys/net/ipv4/ip_forward
88行目: 84行目:
   
 
{{Tip|[[Btrfs]] を使っている場合 {{ic|-B btrfs}} を追加することでコンテナ化した rootfs を保存するための Btrfs サブボリュームを作成することができます。{{ic|lxc-clone}} コマンドを使ってコンテナを複製するときに便利です。}}
 
{{Tip|[[Btrfs]] を使っている場合 {{ic|-B btrfs}} を追加することでコンテナ化した rootfs を保存するための Btrfs サブボリュームを作成することができます。{{ic|lxc-clone}} コマンドを使ってコンテナを複製するときに便利です。}}
  +
  +
{{Tip|2015年7月現在、{{ic|-t none}} を使って空のコンテナを作成することはできません。[https://bugs.launchpad.net/bugs/1466458 バグレポート] を参照してください。代わりに {{ic|-t /bin/true}} を使って下さい。}}
   
 
=== コンテナの設定 ===
 
=== コンテナの設定 ===
 
==== ネットワークの基本設定 ====
 
==== ネットワークの基本設定 ====
  +
プロセスが {{ic|/var/lib/lxc/CONTAINER_NAME/config}} に定義されたコンテナを使う場合、システムリソースは仮想化され分離されます。デフォルトでは、作成プロセスはネットワークサポートを省いた最小限のセットアップを作成します。以下はネットワークを設定する例です:
System resources to be virtualized / isolated when a process is using the container are defined in {{ic|/var/lib/lxc/CONTAINER_NAME/config}}. By default, the creation process will make a minimum setup without networking support. Below is an example config with networking:
 
   
 
{{hc|/var/lib/lxc/playtime/config|<nowiki>
 
{{hc|/var/lib/lxc/playtime/config|<nowiki>
122行目: 120行目:
 
</nowiki>}}
 
</nowiki>}}
   
==== Systemd considerations (required) ====
+
==== Systemd の設定 (必須) ====
  +
以下のセクションでは対処する必要がある問題を説明しています。小さな bash スクリプトを作成する必要があります:
The following sections explain some quirks that should be addressed. A small bash script is required for this to work which users should create:
 
 
{{hc|/var/lib/lxc/playtime/autodev|<nowiki>
 
{{hc|/var/lib/lxc/playtime/autodev|<nowiki>
 
#!/bin/bash
 
#!/bin/bash
132行目: 130行目:
 
</nowiki>}}
 
</nowiki>}}
   
  +
スクリプトに実行可能属性を付与:
Make it executable:
 
 
# chmod +x /var/lib/lxc/playtime/autodev
 
# chmod +x /var/lib/lxc/playtime/autodev
   
Next, modify {{ic|/var/lib/lxc/playtime/config}} to contain this new section:
+
次に、{{ic|/var/lib/lxc/playtime/config}} を編集して以下のセクションを記述してください:
 
## systemd within the lxc
 
## systemd within the lxc
 
lxc.autodev = 1
 
lxc.autodev = 1
142行目: 140行目:
 
lxc.hook.autodev=/var/lib/lxc/playtime/autodev
 
lxc.hook.autodev=/var/lib/lxc/playtime/autodev
   
===== Systemd conflicts in the /dev tree =====
+
===== Systemd /dev ツリーで衝突する =====
  +
systemd と lxc が {{ic|/dev}} ツリーで衝突しないように、''autodev'' モードを有効にすることが強く推奨されています。このモードを有効にすると LXC はデバイスツリーを別個に作成するようになります。また、{{ic|/dev}} が LXC によってマウントされるようになるので、コンテナの rootfs の {{ic|/dev}} ツリー内にデバイスノードを手動で作成する伝統的な方法は使えなくなります。
To avoid conflicts of systemd and lxc in the /dev tree. It is '''highly recommended''' to enable the 'autodev' mode. This will cause LXC to create its own device tree but this also means that the traditional way of manually creating device nodes in the container rootfs /dev tree will not work because /dev is overmounted by LXC.
 
   
 
{{Warning|Any device nodes required that are not created by LXC by default must be created by the ''autodev hook'' script!}}
 
{{Warning|Any device nodes required that are not created by LXC by default must be created by the ''autodev hook'' script!}}
   
  +
コンテナ内でサポートされないサービスは無効化するようにしてください。使用する LXC にアタッチするか、コンテナの rootfs に [[chroot]] して、以下のサービスをマスクしてください:
It is also important to disable services that are not supported inside a container. Either attach to the running LXC or [[chroot]] into the container rootfs and mask those services:
 
 
 
ln -s /dev/null /etc/systemd/system/systemd-udevd.service
+
# ln -s /dev/null /etc/systemd/system/systemd-udevd.service
ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket
+
# ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket
ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket
+
# ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket
ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount
+
# ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount
   
This disables udev and mounting of {{ic|/proc/sys/fs/binfmt_misc}}.
+
上記のコマンドで udev {{ic|/proc/sys/fs/binfmt_misc}} のマウントが無効になります。
   
===== Maintain devpts consistency =====
+
===== devpts の一貫性の保持 =====
  +
さらに LXC コンテナでは pty を宣言するようにしてください。LXC が新しいインスタンスとして devpts をマウントするようになります。これがないと、コンテナはホストの devpts を使うため、問題が発生します。
Additionally ensure a pty declaration in the LXC container because the presence of this causes LXC to mount devpts as a new instance. Without this the container gets the host's devpts and that is not a good thing - more strange things will happen!
 
 
lxc.pts = 1024
 
lxc.pts = 1024
   
{{Note|There is no need to explicitly mount system devices (either via the container config or via its own /etc/fstab) and this should not be done because systemd (or LXC in the case of /dev...) takes care of it.}}
+
{{Note|There is no need to explicitly mount system devices (either via the container config or via its own /etc/fstab), and this should not be done because systemd (or LXC in the case of /dev...) takes care of it.}}
   
===== Prevent excess journald activity =====
+
===== journald の活動の抑制 =====
   
  +
デフォルトで、lxc は {{ic|/dev/kmsg}} から {{ic|/dev/console}} にシンボリックリンクを作成します。このシンボリックリンクがあると journald の CPU 消費量が 100% で張り付いてしまいます。シンボリックリンクを作成しないようにするには、次を使って下さい:
By default lxc symlinks /dev/kmsg to /dev/console, this leads to journald running 100% cpu usage all the time. To prevent the symlink, use:
 
 
lxc.kmsg = 0
 
lxc.kmsg = 0
   
==== Xorg program considerations (optional) ====
+
==== Xorg プログラムの設定 (任意) ====
  +
ホストのディスプレイでプログラムを動かしたい場合、コンテナ化されたプログラムがホストのリソースにアクセスできるようにバインドマウントを定義する必要があります。{{ic|/var/lib/lxc/playtime/config}} に以下のセクションを追加してください:
In order to run programs on the host's display, some bind mounts need to be defined so the containerized programs can access the host's resources. Add the following section to {{ic|/var/lib/lxc/playtime/config}}:
 
 
## for xorg
 
## for xorg
 
## fix overmounting see: https://github.com/lxc/lxc/issues/434
 
## fix overmounting see: https://github.com/lxc/lxc/issues/434
177行目: 175行目:
 
lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file
 
lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file
   
==== OpenVPN considerations ====
+
==== OpenVPN の設定 ====
   
 
コンテナで [[OpenVPN]] を実行したい場合は [[en2:OpenVPN in Linux containers|OpenVPN in Linux containers]] の記事を読んで下さい。
 
コンテナで [[OpenVPN]] を実行したい場合は [[en2:OpenVPN in Linux containers|OpenVPN in Linux containers]] の記事を読んで下さい。
200行目: 198行目:
   
 
== Xorg プログラムの実行 ==
 
== Xorg プログラムの実行 ==
  +
対象のコンテナにアタッチまたは [[SSH]] でログインしてホストの X セッションの DISPLAY ID をプログラムを呼び出すときに指定します。ほとんどの場合、ディスプレイは常時 0 です。
Either attach to or ssh into the target container and prefix the call to the program with the DISPLAY id of the host's X session. For most simple setups, the display is always 0. Example running firefox from the container in the host's display:
 
  +
  +
ホストのディスプレイでコンテナから Firefox を起動する例:
 
$ DISPLAY=:0 firefox
 
$ DISPLAY=:0 firefox
   
  +
もしくは、直接コンテナにアタッチしたり接続する代わりに、以下のコマンドを使って自動的にホストにディスプレイを設定することもできます:
Alternatively, to avoid directly attaching to or connecting to the container, the following can be used on the host to automate the process:
 
 
# lxc-attach -n playtime --clear-env -- sudo -u YOURUSER env DISPLAY=0.0 firefox
 
# lxc-attach -n playtime --clear-env -- sudo -u YOURUSER env DISPLAY=0.0 firefox
   

2015年8月9日 (日) 13:12時点における版

関連記事

LinuX Containers (LXC) はオペレーティングシステムレベルの仮想化手法であり、一つのコントロールホスト (LXC ホスト) で独立した Linux システム (コンテナ) を複数動作させることができます。仮想マシンではありませんが、CPU やメモリ、ブロック I/O、ネットワークなどが個別に用意された仮想環境として使えます。LXC は LXC ホストの Linux カーネルによる cgroups 機能によって賄われています。chroot に似ていますが、より強力な分離を実現します。

セットアップ

必要なソフトウェア

公式リポジトリから lxcarch-install-scripts をインストールしてください。

使用中のカーネルがコンテナを実行できるように正しく設定されているか確認:

$ lxc-checkconfig

セキュリティに配慮して、デフォルトの Arch カーネルでは、非特権ユーザーではコンテナを実行できないようになっています。そのため、上記のコマンドを実行すると "User namespaces" の状態が missing になっているのが確認できます。詳しくは FS#36969 を見て下さい。

ホストネットワークの設定

LXC は様々なタイプの仮想化ネットワークをサポートしています。仮想ネットワークではほとんどの場合、ホスト側にブリッジデバイスが必要になります。以下で示しているブリッジの作成例に限られることはありません。例証として見て下さい。他のプログラムを使って同じようにネットワークを構築することも可能です。以下では有線と無線の例を示していますが、他のセットアップも可能です。他の方法についてはネットワークブリッジの記事を参照してください。

有線ネットワークの例

netctl公式リポジトリからインストールすることができます。ブリッジのテンプレートは /etc/netctl/examples に存在します。ホストネットワークのハードウェアの仕様やホストネットワークの IP の範囲にあわせて編集するようにしてください。以下2つのブリッジの設定例を記載していますが、片方は dhcp を使っており、もう片方は固定 IP で設定しています。

/etc/netctl/lxcbridge
Description="LXC bridge"
Interface=br0
Connection=bridge
BindsToInterfaces=('eno1')
IP=dhcp
SkipForwardingDelay=yes
/etc/netctl/lxcbridge
Description="LXC bridge"
Interface=br0
Connection=bridge
BindsToInterfaces=('eno1')
IP=static
Address=192.168.0.2/24
Gateway='192.168.0.1'
DNS=('192.168.0.1')

ブリッジを開始する前に、ホスト側の既存のネットワークインターフェイスを無効化してブリッジで置き換えるようにしてください。無効化するサービスはどうやってネットワークを設定していたかによって変わってきます。基本的なネットワーク設定についてはビギナーズガイド#ネットワークの設定に例があります。

netctl を使ってアダプタを管理していた場合は、switch-to で切り替えて下さい:

# netctl switch-to lxcbridge
# netctl enable lxcbridge

次に進む前にホストからネットワークにちゃんと接続されているか確認してください。ping を実行することで確認できます:

$ ping -c 1 www.google.com

無線ネットワークの例

無線ネットワークを直接ブリッジすることはできません。他の方法を使う必要があります。最初に、先の例と同じようにブリッジを作成しますが、インターフェイスは何も定義しないようにしておきます (コンテナ自身の仮想インターフェイスは自動的に定義されます)。ブリッジに固定 IP アドレスを割り当てますがゲートウェイは割り当てないようにしてください。

iptables を使って NAT を行うようにホストを設定:

# iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE

wlp3s0 は無線インターフェイスの名前に置き換えて下さい。パケット転送はデフォルトでは無効化されているので、カーネルパラメータを変更して有効にします:

# echo 1 > /proc/sys/net/ipv4/ip_forward

再起動するとパラメータがリセットされてしまうので /etc/sysctl.d に conf ファイルを追加するようにしてください (インターネット共有#パケット転送の有効化の警告を見て下さい)。

残りの作業はほとんど同じですが、コンテナ側では、ゲートウェイはホストの IP アドレスを設定するようにしてください (上記の例では、192.168.0.2 になります)。/var/lib/lxc/container_name/config で指定することができます (下のセクションを見て下さい)。

コンテナの作成

/usr/share/lxc/templates からコンテナ化するディストロに合わせてテンプレートを選択してください。Arch 以外のディストロをコンテナに入れたい場合、ディストロによってホストにパッケージを追加でインストールする必要があります:

lxc-create を実行してコンテナを作成します。デフォルトでは LXC の root ファイルシステムは /var/lib/lxc/CONTAINER_NAME/rootfs にインストールされます。例えば "playtime" という名前の Arch Linux LXC を作成:

# lxc-create -n playtime -t /usr/share/lxc/templates/lxc-archlinux
ヒント: haveged をインストールして haveged.service起動することで、セットアップ中にシステムエントロピーが作成されるまでシステムが停止するのを回避することができます。haveged を使用しない場合、GPG 鍵を作成するのにしばらく時間がかかるかもしれません。
ヒント: Btrfs を使っている場合 -B btrfs を追加することでコンテナ化した rootfs を保存するための Btrfs サブボリュームを作成することができます。lxc-clone コマンドを使ってコンテナを複製するときに便利です。
ヒント: 2015年7月現在、-t none を使って空のコンテナを作成することはできません。バグレポート を参照してください。代わりに -t /bin/true を使って下さい。

コンテナの設定

ネットワークの基本設定

プロセスが /var/lib/lxc/CONTAINER_NAME/config に定義されたコンテナを使う場合、システムリソースは仮想化され分離されます。デフォルトでは、作成プロセスはネットワークサポートを省いた最小限のセットアップを作成します。以下はネットワークを設定する例です:

/var/lib/lxc/playtime/config
# Template used to create this container: /usr/share/lxc/templates/lxc-archlinux
# Parameters passed to the template:
# For additional config options, please look at lxc.container.conf(5)

## default values
lxc.rootfs = /var/lib/lxc/playtime/rootfs
lxc.utsname = playtime
lxc.arch = x86_64
lxc.include = /usr/share/lxc/config/archlinux.common.conf

## network
lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
lxc.network.ipv4 = 192.168.0.3/24
lxc.network.ipv4.gateway = 192.168.0.1
lxc.network.name = eth0

## mounts
## specify shared filesystem paths in the format below
## make sure that the mount point exists on the lxc
#lxc.mount.entry = /mnt/data/share mnt/data none bind 0 0
#
# if running the same Arch linux on the same architecture it may be
# adventitious to share the package cache directory
#lxc.mount.entry = /var/cache/pacman/pkg var/cache/pacman/pkg none bind 0 0

Systemd の設定 (必須)

以下のセクションでは対処する必要がある問題を説明しています。小さな bash スクリプトを作成する必要があります:

/var/lib/lxc/playtime/autodev
#!/bin/bash
cd ${LXC_ROOTFS_MOUNT}/dev
mkdir net
mknod net/tun c 10 200
chmod 0666 net/tun

スクリプトに実行可能属性を付与:

# chmod +x /var/lib/lxc/playtime/autodev

次に、/var/lib/lxc/playtime/config を編集して以下のセクションを記述してください:

## systemd within the lxc
lxc.autodev = 1
lxc.pts = 1024
lxc.kmsg = 0
lxc.hook.autodev=/var/lib/lxc/playtime/autodev
Systemd が /dev ツリーで衝突する

systemd と lxc が /dev ツリーで衝突しないように、autodev モードを有効にすることが強く推奨されています。このモードを有効にすると LXC はデバイスツリーを別個に作成するようになります。また、/dev が LXC によってマウントされるようになるので、コンテナの rootfs の /dev ツリー内にデバイスノードを手動で作成する伝統的な方法は使えなくなります。

警告: Any device nodes required that are not created by LXC by default must be created by the autodev hook script!

コンテナ内でサポートされないサービスは無効化するようにしてください。使用する LXC にアタッチするか、コンテナの rootfs に chroot して、以下のサービスをマスクしてください:

# ln -s /dev/null /etc/systemd/system/systemd-udevd.service
# ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket
# ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket
# ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount

上記のコマンドで udev と /proc/sys/fs/binfmt_misc のマウントが無効になります。

devpts の一貫性の保持

さらに LXC コンテナでは pty を宣言するようにしてください。LXC が新しいインスタンスとして devpts をマウントするようになります。これがないと、コンテナはホストの devpts を使うため、問題が発生します。

lxc.pts = 1024
ノート: There is no need to explicitly mount system devices (either via the container config or via its own /etc/fstab), and this should not be done because systemd (or LXC in the case of /dev...) takes care of it.
journald の活動の抑制

デフォルトで、lxc は /dev/kmsg から /dev/console にシンボリックリンクを作成します。このシンボリックリンクがあると journald の CPU 消費量が 100% で張り付いてしまいます。シンボリックリンクを作成しないようにするには、次を使って下さい:

lxc.kmsg = 0

Xorg プログラムの設定 (任意)

ホストのディスプレイでプログラムを動かしたい場合、コンテナ化されたプログラムがホストのリソースにアクセスできるようにバインドマウントを定義する必要があります。/var/lib/lxc/playtime/config に以下のセクションを追加してください:

## for xorg
## fix overmounting see: https://github.com/lxc/lxc/issues/434
lxc.mount.entry = tmpfs tmp tmpfs defaults
lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry = /dev/snd dev/snd none bind,optional,create=dir
lxc.mount.entry = /tmp/.X11-unix tmp/.X11-unix none bind,optional,create=dir
lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file

OpenVPN の設定

コンテナで OpenVPN を実行したい場合は OpenVPN in Linux containers の記事を読んで下さい。

コンテナの管理

インストール済みの LXC コンテナを確認するには:

# lxc-ls -f

Systemd で lxc@CONTAINER_NAME.service を使うことで LXC を起動したり停止することができます。lxc@CONTAINER_NAME.service有効化するとホストシステムの起動時に LXC が立ち上がるようになります。

systemd を使わずに LXC を起動・停止することも可能です。コンテナを起動:

# lxc-start -n CONTAINER_NAME

コンテナを停止:

# lxc-stop -n CONTAINER_NAME

コンテナにアタッチ:

# lxc-attach -n CONTAINER_NAME

アタッチしたら、他の linux システム用にコンテナを扱って、root パスワードを設定し、ユーザーを作成、パッケージのインストールなどを行って下さい。

Xorg プログラムの実行

対象のコンテナにアタッチまたは SSH でログインしてホストの X セッションの DISPLAY ID をプログラムを呼び出すときに指定します。ほとんどの場合、ディスプレイは常時 0 です。

ホストのディスプレイでコンテナから Firefox を起動する例:

$ DISPLAY=:0 firefox

もしくは、直接コンテナにアタッチしたり接続する代わりに、以下のコマンドを使って自動的にホストにディスプレイを設定することもできます:

# lxc-attach -n playtime --clear-env -- sudo -u YOURUSER env DISPLAY=0.0 firefox

参照