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

提供: ArchWiki
ナビゲーションに移動 検索に移動
100行目: 100行目:
 
* ''sysctl'' 設定 {{ic|kernel.unprivileged_userns_clone}} を有効にして、通常のユーザーが特権のないコンテナを実行できるようにします。これは、root として {{ic|1=sysctl kernel.unprivileged_userns_clone=1}} を実行することで現在のセッションに対して行うことができ、また、{{man|5|sysctl.d}} を使用して永続化することもできます。
 
* ''sysctl'' 設定 {{ic|kernel.unprivileged_userns_clone}} を有効にして、通常のユーザーが特権のないコンテナを実行できるようにします。これは、root として {{ic|1=sysctl kernel.unprivileged_userns_clone=1}} を実行することで現在のセッションに対して行うことができ、また、{{man|5|sysctl.d}} を使用して永続化することもできます。
   
=== ホストネットワーク設定 ===
+
=== ホストネットワーク設定 ===
LXC は様々なタイプの仮想化ネットワークをサポートしています [https://linuxcontainers.org/lxc/manpages//man5/lxc.container.conf.5.html]。仮想ネットワークではほとんどの場合、ホスト側にブリッジデバイスが必要になります。以下で示しているブリッジの作成例に限られることはありません。例証として見て下さい。他のプログラムを使って同じようにネットワークを構築することも可能です。以下では有線と無線の例を示していますが、他のセットアップも可能です。他の方法については[[ネットワークブリッジ]]の記事を参照してください。
 
   
  +
LXC は、さまざまな仮想ネットワークタイプとデバイスをサポートします ({{man|5|lxc.container.conf}} を参照) ホスト上のブリッジデバイスは、このセクションで説明するほとんどのタイプの仮想ネットワークに必要です。
==== 有線ネットワークの例 ====
 
以下の例では [[netctl]] を使用しています。netctl のブリッジのテンプレートは {{ic|/etc/netctl/examples}} に存在します。ホストネットワークのハードウェアの仕様やホストネットワークの IP の範囲にあわせて編集するようにしてください。以下2つのブリッジの設定例を記載していますが、片方は dhcp を使っており、もう片方は固定 IP で設定しています。
 
   
  +
考慮すべき主な設定がいくつかあります。
{{hc|1=/etc/netctl/lxcbridge|2=
 
  +
# ホストブリッジ
Description="LXC bridge"
 
  +
# NAT ブリッジ
Interface=br0
 
Connection=bridge
 
BindsToInterfaces=('eno1')
 
IP=dhcp
 
SkipForwardingDelay=yes}}
 
   
  +
ホストブリッジでは、ホストのネットワークマネージャーが共有ブリッジインターフェイスを管理する必要があります。ホストとすべての lxc には、同じネットワーク内の IP アドレスが割り当てられます (たとえば、192.168.1.x) Web サーバーや VPN サーバーなど、ネットワークに公開されたサービスをコンテナ化することが目的の場合、これはより単純になる可能性があります。ユーザーは、lxc を物理 LAN 上の単なる別の PC と考えることができ、それに応じてルーター内の必要なポートを転送できます。追加されたシンプルさは、追加の脅威ベクトルと考えることもできます。WAN トラフィックが lxc に転送される場合、別の範囲で lxc を実行すると、脅威の表面が小さくなります。
{{hc|1=/etc/netctl/lxcbridge|2=
 
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')}}
 
   
ブリッジを開始する前に、ホスト側の既存のネットワークインタフェイスを[[systemd#ユニ使う|無効化]]してブリッジで置き換えようにしくださ。無効化るサはどうってネットワークを設定していたかよっ変わってきます。基本的なネットワーク設定ついては[[ネットワーク設定]]を見ください
+
NAT ブリッジでは、ホストのネットワークマネジャーがブリ管理する必要はありません。{{pkg|lxc}} には、{{ic|lxcbr0}} という NAT ブリッジを作成す {{ic|lxc-net}} が同梱されてい。NAT ブリッジは、ホストのイサネット デバイスや物理ネットワークにブリッジされいプライベート ネットワークを備えたスタンドアロンブリッジです。ホスト内プライベートサブネットとし存在します
   
  +
==== ホストブリッジの使用 ====
netctl を使ってアダプタを管理していた場合は、switch-to で切り替えて下さい:
 
# netctl switch-to lxcbridge
 
# netctl enable lxcbridge
 
   
次に進む前にホストからネットワークにちゃんと接続されているか確認してください。ping を実行することで確認できます:
+
[[ネットワークブリッジ]] を参照してください。
$ ping -c 1 www.google.com
 
   
==== 無線ネトワーク ====
+
==== NAT ブリ使用 ====
   
  +
{{pkg|dnsmasq}}、を [[インストール]] して下さい、これは {{ic|lxc-net}} の依存関係です。ブリッジを開始する前に、まずブリッジの設定ファイルを作成します:
無線ネットワークを直接ブリッジすることはできません。他の方法を使う必要があります。最初に、先の例と同じようにブリッジを作成しますが、インターフェイスは何も定義しないようにしておきます (コンテナ自身の仮想インターフェイスは自動的に定義されます)。ブリッジに固定 IP アドレスを割り当てますがゲートウェイは割り当てないようにしてください。
 
   
  +
{{hc|/etc/default/lxc-net|
iptables を使って NAT を行うようにホストを設定:
 
  +
2=# Leave USE_LXC_BRIDGE as "true" if you want to use lxcbr0 for your
  +
# containers. Set to "false" if you'll use virbr0 or another existing
  +
# bridge, or mavlan to your host's NIC.
  +
USE_LXC_BRIDGE="true"
   
  +
# If you change the LXC_BRIDGE to something other than lxcbr0, then
# iptables -t nat -A POSTROUTING -o ''wlp3s0'' -j MASQUERADE
 
  +
# you will also need to update your /etc/lxc/default.conf as well as the
  +
# configuration (/var/lib/lxc/<container>/config) for any containers
  +
# already created using the default config to reflect the new bridge
  +
# name.
  +
# If you have the dnsmasq daemon installed, you'll also have to update
  +
# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon.
  +
LXC_BRIDGE="lxcbr0"
  +
LXC_ADDR="10.0.3.1"
  +
LXC_NETMASK="255.255.255.0"
  +
LXC_NETWORK="10.0.3.0/24"
  +
LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
  +
LXC_DHCP_MAX="253"
  +
# Uncomment the next line if you'd like to use a conf-file for the lxcbr0
  +
# dnsmasq. For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have
  +
# container 'mail1' always get ip address 10.0.3.100.
  +
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
   
  +
# Uncomment the next line if you want lxcbr0's dnsmasq to resolve the .lxc
{{ic|''wlp3s0''}} は無線インターフェイスの名前に置き換えて下さい。パケット転送はデフォルトでは無効化されているので、[[インターネット共有#パケット転送の有効化|カーネルパラメータを変更]]して有効にします:
 
  +
# domain. You can then add "server=/lxc/10.0.3.1' (or your actual $LXC_ADDR)
  +
# to your system dnsmasq configuration file (normally /etc/dnsmasq.conf,
  +
# or /etc/NetworkManager/dnsmasq.d/lxc.conf on systems that use NetworkManager).
  +
# Once these changes are made, restart the lxc-net and network-manager services.
  +
# 'container1.lxc' will then resolve on your host.
  +
#LXC_DOMAIN="lxc"
  +
}}
   
  +
{{Tip|ブリッジの IP 範囲がローカルネットワークに干渉しないことを確認してください。}}
# echo 1 > /proc/sys/net/ipv4/ip_forward
 
   
  +
次に、コンテナがブリッジを使用するように LXC コンテナテンプレートを変更する必要があります。
再起動するとパラメータがリセットされてしまうので {{ic|/etc/sysctl.d}} に conf ファイルを追加するようにしてください ([[インターネット共有#パケット転送の有効化]]の警告を見て下さい)。
 
   
  +
{{hc|/etc/lxc/default.conf|
残りの作業はほとんど同じですが、コンテナ側では、ゲートウェイはホストの IP アドレスを設定するようにしてください (上記の例では、192.168.0.2 になります)。{{ic|/var/lib/lxc/''container_name''/config}} で指定することができます (下のセクションを見て下さい)。
 
  +
2=lxc.net.0.type = veth
  +
lxc.net.0.link = lxcbr0
  +
lxc.net.0.flags = up
  +
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
  +
}}
  +
  +
Optionally create a configuration file to manually define the IP address of any containers:
  +
{{hc|/etc/lxc/dnsmasq.conf|
  +
2=dhcp-host=playtime,10.0.3.100
  +
}}
  +
  +
{{ic|lxc-net.service}} を [[起動]]/[[有効化]] してブリッジ インターフェイスを作成します。
  +
  +
===== ファイアウォールの考慮事項 =====
  +
  +
ホストマシンが実行しているファイアウォールによっては、{{ic|lxcbr0}} からホストへの受信パケットと、{{ic|lxcbr0}} からの送信パケットがホストを経由して他のネットワークに到達することを許可する必要がある場合があります。これをテストするには、IP 割り当てに DHCP を使用するように設定されたコンテナを起動して、{{ic|lxc-net}} がコンテナに IP アドレスを割り当てることができるかどうかを確認してください ({{ic|lxc-ls -f}} IP が割り当てられていない場合は、ホストのポリシーを調整する必要があります。
  +
  +
{{pkg|ufw}} のユーザーは、次の [https://discuss.linuxcontainers.org/t/lxd-bridge-doesnt-work-with-ipv4-and-ufw-with-nftables/10034/17 2 行] を実行するだけです。これを有効にするには:
  +
# ufw allow in on lxcbr0
  +
# ufw route allow in on lxcbr0
  +
  +
あるいは、{{pkg|nftables}} のユーザーは、{{ic|/etc/nftables.conf}} を変更できます (そして、{{ic|nft -f /etc/nftables.conf}} で再ロードします。設定が正しいかどうかを確認してください) {{ic|nft -cf /etc/nftables.conf}} これでコンテナがインターネットにアクセスできるようになります ({{ic|"eth0"}} を、インターネットにアクセスできるシステム上のデバイスに置き換えます。 {{ic|ip link}} を使用して既存のデバイスをリストします):
  +
  +
{{hc|/etc/nftables.conf|
  +
table inet filter {
  +
chain input {
  +
...
  +
iifname "lxcbr0" accept comment "Allow lxc containers"
  +
  +
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
  +
counter
  +
}
  +
chain forward {
  +
...
  +
iifname "lxcbr0" oifname "eth0" accept comment "Allow forwarding from lxcbr0 to eth0"
  +
iifname "eth0" oifname "lxcbr0" accept comment "Allow forwarding from eth0 to lxcbr0"
  +
}
  +
}
  +
}}
  +
  +
さらに、コンテナーは 10.0.3.x サブネット上で実行されているため、ssh、httpd などのサービスへの外部アクセスは lxc にアクティブに転送される必要があります。原則として、ホスト上のファイアウォールは、コンテナ上の予期されるポートで受信トラフィックを転送する必要があります。
  +
  +
====== iptables ルールの例 ======
  +
  +
このルールの目的は、lxc への ssh トラフィックを許可することです:
  +
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2221 -j DNAT --to-destination 10.0.3.100:22
  +
  +
このルールは、ポート 2221 から発信される tcp トラフィックをポート 22 の lxc の IP アドレスに転送します。
  +
{{Note|ホスト上で 2221/tcp のトラフィックを許可し、lxc 上で 22/tcp のトラフィックを許可するようにしてください。}}
  +
  +
LAN 上の別の PC からコンテナーに ssh 接続するには、ポート 2221 でホストに ssh 接続する必要があります。その後、ホストはそのトラフィックをコンテナに転送します。
  +
  +
$ ssh -p 2221 host.lan
  +
  +
====== ufw ルールの例 ======
  +
  +
{{pkg|ufw}} を使用する場合は、これを永続化するために、{{ic|/etc/ufw/before.rules}} の最後に次の行を追加します:
  +
  +
{{hc|/etc/ufw/before.rules|
  +
  +
*nat
  +
:PREROUTING ACCEPT [0:0]
  +
-A PREROUTING -i eth0 -p tcp --dport 2221 -j DNAT --to-destination 10.0.3.100:22
  +
COMMIT
  +
}}
  +
  +
===== 非 root ユーザーとしてコンテナを実行する =====
  +
  +
非 root ユーザーとしてコンテナーを作成して起動するには、追加の構成を適用する必要があります。
  +
  +
{{ic|/etc/lxc/lxc-usernet}} にユーザーネットファイルを作成します。{{man|5|lxc-usernet}} によると、1 行あたりのエントリは次のとおりです。
  +
  +
user type bridge number
  +
  +
コンテナを作成する必要があるユーザーを使用してファイルを設定します。ブリッジは、{{ic|/etc/default/lxc-net}} で定義されているものと同じになります。
  +
  +
{{ic|/etc/lxc/default.conf}} のコピーが、非 root ユーザーのホームディレクトリに必要です。例: {{ic|~/.config/lxc/default.conf}} (ディレクトリを作成します) 必要に応じて)
  +
  +
非 root ユーザーとしてコンテナを実行するには、{{ic|~/.local/share/}} に対する {{ic|+x}} 権限が必要です。コンテナを起動する前に、[[chmod]] を使用して変更を加えます。
   
 
=== コンテナの作成 ===
 
=== コンテナの作成 ===

2024年2月2日 (金) 01:21時点における版

関連記事

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

LXD は LXC のマネージャーとして使用できます。このページでは、LXC を直接使用する方法について説明します

LXC の代わりとして systemd-nspawndocker でもコンテナを使うことができます。

特権コンテナと非特権コンテナ

LXC は特権または非特権で動作するように設定することができます。

一般的に、非特権コンテナは特権コンテナよりも安全だとされています [1]。非特権コンテナでは分離の程度が原理上増すからです。非特権コンテナではコンテナの root の UID をホストの root 以外の UID にマッピングすることで、コンテナの中からホスト環境に影響を及ぼすことを難しくします。たとえ攻撃者がコンテナから脱獄しても、ホスト側では攻撃者に権限がありません。

現在 Arch のパッケージでは特権コンテナは最初からサポートしています。非特権コンテナはカーネル設定を行わないと利用できません。Arch の linux カーネルでは通常ユーザーでユーザー名前空間が無効になっているためです。この記事では特権・非特権両方のコンテナの情報を載せていますが、非特権を使うには設定が必要です。

非特権コンテナの例

UID マッピングの能力を説明するために、非特権コンテナで以下のコマンドを実行したときの出力を考えてみましょう。ps の出力でコンテナ化されたプロセスの所有者が同じくコンテナ化された root ユーザーとなっていることが確認できます:

[root@unprivileged_container /]# ps -ef | head -n 5
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 17:49 ?        00:00:00 /sbin/init
root        14     1  0 17:49 ?        00:00:00 /usr/lib/systemd/systemd-journald
dbus        25     1  0 17:49 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
systemd+    26     1  0 17:49 ?        00:00:00 /usr/lib/systemd/systemd-networkd

ホスト側では、コンテナ化された root プロセスはマッピングされたユーザー (ID>100000) で動作します。ホストの root ユーザーではありません:

[root@host /]# lxc-info -Ssip --name sandbox
State:          RUNNING
PID:            26204
CPU use:        10.51 seconds
BlkIO use:      244.00 KiB
Memory use:     13.09 MiB
KMem use:       7.21 MiB
[root@host /]# ps -ef | grep 26204 | head -n 5
UID        PID  PPID  C STIME TTY          TIME CMD
100000   26204 26200  0 12:49 ?        00:00:00 /sbin/init
100000   26256 26204  0 12:49 ?        00:00:00 /usr/lib/systemd/systemd-journald
100081   26282 26204  0 12:49 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
100000   26284 26204  0 12:49 ?        00:00:00 /usr/lib/systemd/systemd-logind

セットアップ

必要なソフトウェア

lxcarch-install-scripts パッケージをインストールしてください。

非特権コンテナのサポートを有効化 (任意)

/etc/lxc/default.conf を変更して次の行を含めます:

lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536

言い換えると、65536 個の連続した uid の範囲をマップします。コンテナ側の uid 0 (ホストの観点からは uid 100000 になります) から、ホストが uid 165535 として認識するコンテナ側の uid 65535 までです。同じマッピングを gid に適用します。

/etc/subuid/etc/subgid の両方を作成して、コンテナを実行できる各ユーザーのコンテナ化された uid/gid ペアへのマッピングを含めます。以下の例は、単純に root ユーザー (および systemd システムユニット) を対象としています:

/etc/subuid
root:100000:65536
/etc/subgid
root:100000:65536

さらに、非特権ユーザーとして非特権コンテナを実行することは、事前に cgroup を委任した場合にのみ機能します (この制限は、liblxc ではなく cgroup2 委任モデルによって強制されます) 次の systemd コマンドを使用して cgroup を委任します (LXC - Getting started: Creating unprivileged containers as a user):

$ systemd-run --unit=myshell --user --scope -p "Delegate=yes" lxc-start container_name

これは他の lxc コマンドでも同様に機能します。

/etc/systemd/system/user@.service.d/delegate.conf
[Service]
Delegate=cpu cpuset io memory pids
linux-hardened などカスタムカーネル上の特権のないコンテナ

linux-hardened またはカスタム カーネル上で 非特権 コンテナを実行したいユーザーは、いくつかの追加のセットアップ手順を完了する必要があります。

まず、ユーザー名前空間をサポートするカーネル (CONFIG_USER_NS を備えたカーネル) が必要です。すべての Arch Linux カーネルは CONFIG_USER_NS をサポートしています。ただし、より一般的なセキュリティ上の懸念により、linux-hardened カーネルは、root ユーザーに対してのみ有効になったユーザー名前空間とともに出荷されます。そこに 非特権 コンテナを作成するには 2 つのオプションがあります:

  • 特権のないコンテナは root としてのみ起動してください。また、現在の値が 0 の場合、sysctl 設定 user.max_user_namespaces に環境に合わせて正の値を指定します (これにより、lxc info --show-log container_name で見られる Failed to clone process in new user namespace というエラーが修正されます)
  • linux-hardened および lxd 5.0.0 では、root:1000000:65536 の範囲を使用するように /etc/subuid および /etc/subgid を設定する必要がある場合があります。最初 のコンテナを特権付きで起動する必要がある場合もあります。これにより、newuidmap failed to write mapping "newuidmap: uid range [0-1000000000) -> [1000000-1001000000) not allowed" エラーが修正されます。
  • sysctl 設定 kernel.unprivileged_userns_clone を有効にして、通常のユーザーが特権のないコンテナを実行できるようにします。これは、root として sysctl kernel.unprivileged_userns_clone=1 を実行することで現在のセッションに対して行うことができ、また、sysctl.d(5) を使用して永続化することもできます。

ホストネットワーク設定

LXC は、さまざまな仮想ネットワークタイプとデバイスをサポートします (lxc.container.conf(5) を参照) ホスト上のブリッジデバイスは、このセクションで説明するほとんどのタイプの仮想ネットワークに必要です。

考慮すべき主な設定がいくつかあります。

  1. ホストブリッジ
  2. NAT ブリッジ

ホストブリッジでは、ホストのネットワークマネージャーが共有ブリッジインターフェイスを管理する必要があります。ホストとすべての lxc には、同じネットワーク内の IP アドレスが割り当てられます (たとえば、192.168.1.x) Web サーバーや VPN サーバーなど、ネットワークに公開されたサービスをコンテナ化することが目的の場合、これはより単純になる可能性があります。ユーザーは、lxc を物理 LAN 上の単なる別の PC と考えることができ、それに応じてルーター内の必要なポートを転送できます。追加されたシンプルさは、追加の脅威ベクトルと考えることもできます。WAN トラフィックが lxc に転送される場合、別の範囲で lxc を実行すると、脅威の表面が小さくなります。

NAT ブリッジでは、ホストのネットワークマネージャーがブリッジを管理する必要はありません。lxc には、lxcbr0 という NAT ブリッジを作成する lxc-net が同梱されています。NAT ブリッジは、ホストのイーサネット デバイスや物理ネットワークにブリッジされていないプライベート ネットワークを備えたスタンドアロンブリッジです。ホスト内にプライベートサブネットとして存在します。

ホストブリッジの使用

ネットワークブリッジ を参照してください。

NAT ブリッジの使用

dnsmasq、を インストール して下さい、これは lxc-net の依存関係です。ブリッジを開始する前に、まずブリッジの設定ファイルを作成します:

/etc/default/lxc-net
# Leave USE_LXC_BRIDGE as "true" if you want to use lxcbr0 for your
# containers.  Set to "false" if you'll use virbr0 or another existing
# bridge, or mavlan to your host's NIC.
USE_LXC_BRIDGE="true"

# If you change the LXC_BRIDGE to something other than lxcbr0, then
# you will also need to update your /etc/lxc/default.conf as well as the
# configuration (/var/lib/lxc/<container>/config) for any containers
# already created using the default config to reflect the new bridge
# name.
# If you have the dnsmasq daemon installed, you'll also have to update
# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon.
LXC_BRIDGE="lxcbr0"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
LXC_DHCP_MAX="253"
# Uncomment the next line if you'd like to use a conf-file for the lxcbr0
# dnsmasq.  For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have
# container 'mail1' always get ip address 10.0.3.100.
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

# Uncomment the next line if you want lxcbr0's dnsmasq to resolve the .lxc
# domain.  You can then add "server=/lxc/10.0.3.1' (or your actual $LXC_ADDR)
# to your system dnsmasq configuration file (normally /etc/dnsmasq.conf,
# or /etc/NetworkManager/dnsmasq.d/lxc.conf on systems that use NetworkManager).
# Once these changes are made, restart the lxc-net and network-manager services.
# 'container1.lxc' will then resolve on your host.
#LXC_DOMAIN="lxc"
ヒント: ブリッジの IP 範囲がローカルネットワークに干渉しないことを確認してください。

次に、コンテナがブリッジを使用するように LXC コンテナテンプレートを変更する必要があります。

/etc/lxc/default.conf
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx

Optionally create a configuration file to manually define the IP address of any containers:

/etc/lxc/dnsmasq.conf
dhcp-host=playtime,10.0.3.100

lxc-net.service起動/有効化 してブリッジ インターフェイスを作成します。

ファイアウォールの考慮事項

ホストマシンが実行しているファイアウォールによっては、lxcbr0 からホストへの受信パケットと、lxcbr0 からの送信パケットがホストを経由して他のネットワークに到達することを許可する必要がある場合があります。これをテストするには、IP 割り当てに DHCP を使用するように設定されたコンテナを起動して、lxc-net がコンテナに IP アドレスを割り当てることができるかどうかを確認してください (lxc-ls -f IP が割り当てられていない場合は、ホストのポリシーを調整する必要があります。

ufw のユーザーは、次の 2 行 を実行するだけです。これを有効にするには:

# ufw allow in on lxcbr0
# ufw route allow in on lxcbr0

あるいは、nftables のユーザーは、/etc/nftables.conf を変更できます (そして、nft -f /etc/nftables.conf で再ロードします。設定が正しいかどうかを確認してください) nft -cf /etc/nftables.conf これでコンテナがインターネットにアクセスできるようになります ("eth0" を、インターネットにアクセスできるシステム上のデバイスに置き換えます。 ip link を使用して既存のデバイスをリストします):

/etc/nftables.conf
table inet filter {
  chain input {
    ...
    iifname "lxcbr0" accept comment "Allow lxc containers"
    
    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    counter
  }
  chain forward {
    ...
    iifname "lxcbr0" oifname "eth0" accept comment "Allow forwarding from lxcbr0 to eth0"
    iifname "eth0" oifname "lxcbr0" accept comment "Allow forwarding from eth0 to lxcbr0"
  }
}

さらに、コンテナーは 10.0.3.x サブネット上で実行されているため、ssh、httpd などのサービスへの外部アクセスは lxc にアクティブに転送される必要があります。原則として、ホスト上のファイアウォールは、コンテナ上の予期されるポートで受信トラフィックを転送する必要があります。

iptables ルールの例

このルールの目的は、lxc への ssh トラフィックを許可することです:

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2221 -j DNAT --to-destination 10.0.3.100:22

このルールは、ポート 2221 から発信される tcp トラフィックをポート 22 の lxc の IP アドレスに転送します。

ノート: ホスト上で 2221/tcp のトラフィックを許可し、lxc 上で 22/tcp のトラフィックを許可するようにしてください。

LAN 上の別の PC からコンテナーに ssh 接続するには、ポート 2221 でホストに ssh 接続する必要があります。その後、ホストはそのトラフィックをコンテナに転送します。

$ ssh -p 2221 host.lan
ufw ルールの例

ufw を使用する場合は、これを永続化するために、/etc/ufw/before.rules の最後に次の行を追加します:

/etc/ufw/before.rules

*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp --dport 2221 -j DNAT --to-destination 10.0.3.100:22
COMMIT
非 root ユーザーとしてコンテナを実行する

非 root ユーザーとしてコンテナーを作成して起動するには、追加の構成を適用する必要があります。

/etc/lxc/lxc-usernet にユーザーネットファイルを作成します。lxc-usernet(5) によると、1 行あたりのエントリは次のとおりです。

user type bridge number

コンテナを作成する必要があるユーザーを使用してファイルを設定します。ブリッジは、/etc/default/lxc-net で定義されているものと同じになります。

/etc/lxc/default.conf のコピーが、非 root ユーザーのホームディレクトリに必要です。例: ~/.config/lxc/default.conf (ディレクトリを作成します) 必要に応じて)

非 root ユーザーとしてコンテナを実行するには、~/.local/share/ に対する +x 権限が必要です。コンテナを起動する前に、chmod を使用して変更を加えます。

コンテナの作成

特権コンテナの場合、/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

非特権コンテナを使いたい場合は -t download を使用してイメージを選択してください。例:

# lxc-create -n playtime -t download
ヒント:
  • haveged をインストールして haveged.service起動することで、セットアップ中にシステムエントロピーが作成されるまでシステムが停止するのを回避することができます。haveged を使用しない場合、GPG 鍵を作成するのにしばらく時間がかかるかもしれません。
  • Btrfs を使っている場合 -B btrfs を追加することでコンテナ化した rootfs を保存するための Btrfs サブボリュームを作成することができます。lxc-clone コマンドを使ってコンテナを複製するときに便利です。ZFS ユーザーは -B zfs が使えます。

コンテナの設定

以下の例は特権コンテナと非特権コンテナどちらでも同じように使えます非特権コンテナの場合、lxc.idmap = u 0 100000 65536 and the lxc.idmap = g 0 100000 65536 values optionally defined in the #非特権コンテナのサポートを有効化 (任意)セクションで定義した lxc.idmap = u 0 100000 65536lxc.idmap = g 0 100000 65536 などの値がデフォルトで存在するはずです。

ネットワークの基本設定

ノート: lxc-1:2.1.0-1 から、設定オプションの多くが変わりました。既存のコンテナはアップデートする必要があります。変更については v2.1 リリースノート を参照してください。

プロセスが /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.path = /var/lib/lxc/playtime/rootfs
lxc.uts.name = playtime
lxc.arch = x86_64
lxc.include = /usr/share/lxc/config/archlinux.common.conf

## network
lxc.net.0.type = veth
lxc.net.0.link = br0
lxc.net.0.flags = up
lxc.net.0.name = eth0
lxc.net.0.hwaddr = ee:ec:fa:e9:56:7d
# uncomment the next two lines if static IP addresses are needed
# leaving these commented will imply DHCP networking
#
#lxc.net.0.ipv4.address = 192.168.0.3/24
#lxc.net.0.ipv4.gateway = 192.168.0.1
ノート: lxc.network.hwaddr エントリは任意です。省略した場合、自動的にランダムな MAC アドレスが作成されます。コンテナの MAC アドレスを定義することで DHCP サーバーからコンテナの NIC に常に同じ IP を割り当てることが可能になります。

コンテナの中でマウント

特権コンテナの場合、ホストでディレクトリを選択してコンテナにバインドマウントすることができます。同一アーキテクチャをコンテナ化している場合にホストとコンテナで pacman のパッケージを共有するなどの使用方法が考えられます。また、共有ディレクトリとして使用することもできます。構文は以下の通りです:

lxc.mount.entry = /var/cache/pacman/pkg var/cache/pacman/pkg none bind 0 0
ノート: 非特権コンテナを使っている場合、ホスト側でファイルシステムのパーミッションを修正しないと上記の設定は機能しません。

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

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

## for xorg
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,ro
lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file

LXC のゲスト側に permission denied エラーが表示される場合、ホスト側で xhost + を実行してゲストからホストのディスプレイサーバーに接続できるようにする必要があります。このようにディスプレイサーバーを開くことはセキュリティ上問題があるので注意してください。

ノート: 上記の設定は非特権コンテナでは機能しません。

OpenVPN の設定

コンテナで OpenVPN を実行したい場合は Linux Containers で OpenVPN クライアントLinux Containers で OpenVPN サーバーの記事を読んで下さい。

コンテナの管理

基本的な使用方法

インストール済みの 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-console -n CONTAINER_NAME

ログイン時に pts/0 と lxc/tty1 が表示される場合:

# lxc-console -n CONTAINER_NAME -t 0

ログインしたら、他の linux システムと同じようにコンテナを扱って、root パスワードを設定し、ユーザーを作成、パッケージのインストールなどを行って下さい。

コンテナにアタッチ:

# lxc-attach -n CONTAINER_NAME --clear-env

lxc-console とほぼ同じですが、自動的にログインを通り越してコンテナの中の root プロンプトにアクセスします。 --clear-env フラグを指定しなかった場合、ホストは環境変数をコンテナに渡します ($PATH など、コンテナが他のディストリビューションの場合、一部のコマンドが機能しなくなる可能性があります)。

高度な使用方法

LXC の複製

同じコンテナを複数実行する必要があるときはスナップショットを使うことで管理を簡単にできます。最新状態にしておくベースコンテナをひとつだけセットアップして、それを必要に応じて複製 (スナップショットを作成) するという方法です。スナップショットは overlayfs を使用してデータの差異部分だけをディスクに書き込むためディスク容量を節約してオーバーヘッドをなくすことができます。ベースシステムは読み取り専用にしてスナップショットにのみ overlayfs で変更を加えられるようにします。

欠点としてスナップショットを作成しているときにベースの lxc を実行することはできません。

上に書いているようにコンテナをセットアップしたら "base" と名前を付けます。以下のコマンドで "base" コンテナのスナップショット ("snap1" と "snap2") を作成します:

# lxc-copy -n base -N snap1 -B overlayfs -s
# lxc-copy -n base -N snap2 -B overlayfs -s
ノート: ベースの lxc で固定 IP を使っている場合、"snap1" や "snap2" を起動する前にネットワーク設定を手動で変更する必要があります。

スナップショットは他のコンテナと同じように起動・停止できます。以下のコマンドでスナップショットを削除できます (ベースの lxc に変更は加えられません):

# lxc-destroy -n snap1 -f

pi-holeOpenVPN のスナップショットを管理する systemd ユニットとラッパースクリプトが lxc-snapshotsAUR[リンク切れ: パッケージが存在しません] パッケージでインストールできます。

特権コンテナを非特権コンテナに変換

非特権コンテナを使うようにシステムを設定したら (#非特権コンテナのサポートを有効化 (任意) を参照), nsexec-bzrAUR に含まれている uidmapshift という名前のユーティリティで既存の特権コンテナを非特権コンテナに変換できます。イメージの再ビルドは不要です。

警告:
  • ユーティリティを使用する前に既存のイメージをバックアップすることを推奨します。
  • ユーティリティは ACL の UID と GID をシフトしません。手動でシフトする必要があります。

以下のようにコマンドを実行することで変換できます:

# uidmapshift -b /var/lib/lxc/foo 0 100000 65536

利用可能なオプションは引数を付けずに uidmapshift を実行することで確認可能です。

Xorg プログラムの実行

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

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

$ DISPLAY=:0 firefox

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

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

トラブルシューティング

root ログインが失敗する

lxc-console を使ってログインしようとすると以下のエラーが表示される場合:

login: root
Login incorrect

そしてコンテナの journalctl で以下のように表示される場合:

pam_securetty(login:auth): access denied: tty 'pts/0' is not secure !

コンテナのファイルシステムにある /etc/securetty のターミナル名のリストに pts/0 を追加してください。[2] を参照。コンテナの /etc/securetty を削除することで常時 root ログインを許可することもできます。[3] を参照。

もしくは、lxc-attach に新しいユーザーを作成してシステムにログインするときに使うようにして、それから root に切り替えて下さい。

# lxc-attach -n playtime
[root@playtime]# useradd -m -Gwheel newuser
[root@playtime]# passwd newuser
[root@playtime]# passwd root
[root@playtime]# exit
# lxc-console -n playtime
[newuser@playtime]$ su

コンテナ設定の veth でネットワークに接続できない

/etc/lxc/containername/config で設定した veth ネットワークインターフェイスで LAN や WAN に接続できないことがあります。仮想インターフェイスには IP が割り当てられてネットワークに接続できるようになっている場合:

ip addr show veth0 
inet 192.168.1.111/24

固定 IP の設定を全て無効化して、起動したコンテナ OS の中から普通の方法で IP を設定してみてください。

container/config の例:

...
lxc.net.0.type = veth
lxc.net.0.name = veth0
lxc.net.0.flags = up
lxc.net.0.link = bridge
...

コンテナの中から IP を割り当てる方法はネットワーク設定#IP アドレスの設定を参照。

Error: unknown command

ホスト環境とは異なる Linux ディストリビューションのコンテナ (例えば Arch Linux ホスト環境の Debian コンテナ) に接続して基本的なコマンド (ls, cat など) を入力する発生することがあるエラーです。接続時に --clear-env 引数を使ってください:

# lxc-attach -n container_name --clear-env

Error: Failed at step KEYRING spawning...

特権のないコンテナ内のサービスが失敗し、次のメッセージが表示される場合がある

some.service: Failed to change ownership of session keyring: Permission denied
some.service: Failed to set up kernel keyring: Permission denied
some.service: Failed at step KEYRING spawning ....: Permission denied

次の内容を含むファイル /etc/lxc/unpriv.seccomp を作成します。

/etc/lxc/unpriv.seccomp
2
blacklist
[all]
keyctl errno 38

次に、次の行をコンテナ設定 lxc.idmap の後 に追加します。

lxc.seccomp.profile = /etc/lxc/unpriv.seccomp

既知の問題

lxc.init.static が欠落しているため lxc-execute が失敗する

lxc-execute はエラーメッセージ lxc.init.static を表示して失敗する場合。FS#63814 を参照してください。

lxc-start を使用してコンテナを起動すると、正常に動作します。

参照