Ubuntu 22.04 で発生。
Ubuntu 24.04 では次の対応をしなくても最初から Canonical のリモートサーバーが追加されている模様。
lxc remote add canonical https://images.lxd.canonical.com --protocol=simplestreams
lxc remote list
lxc image list canonical:
lxc launch canonical:rockylinux/8/amd64 rocky8
lxc image alias create <alias> <fingerprint>
lxc image alias create canonical-ol8.10 9fe68be23287
lxc launch canonical-ol8.10 oracle8.10
alias を作成していない場合は、fingerprint を指定して作成するとことも可能
lxc launch 9fe68be23287 oracle8.10
(参考) https://qiita.com/d-ebi/items/eb8f84f230029ef0e2c5
(images.linuxcontainers.org 閉鎖の案内) https://discuss.linuxcontainers.org/t/important-notice-for-lxd-users-image-server/18479
sudo apt update
sudo apt upgrade
sudo gpasswd -a $USER lxd
getent group lxd
「LXC 5.0 でコンテナから lxdbr0 を通じてインターネットに出れない」も済ませておく。
lxd init
lxc remote list
lxc image alias list images:
lxc image list
lxc network show lxdbr0
lxc config show --expanded <コンテナ名>
lxc profile list
lxc profile show default
lxc profile assign <コンテナ名> <プロファイル名>
lxc list
lxc info <コンテナ名>
lxc launch images:centos/7/amd64 <コンテナ名>
lxc image list images:
lxc start <コンテナ名>
lxc stop <コンテナ名>
lxc delete <コンテナ名>
lxc exec <コンテナ名> bash
lxc --version
lxd --version
lxc snapshot <コンテナ名> <スナップショット名>
lxc snapshot <コンテナ名> <スナップショット名> --reuse
lxc info <コンテナ名>
export EDITOR=vim
lxc config edit <コンテナ名>/<スナップショット名>
lxc restore <コンテナ名> <スナップショット名>
lxc delete <コンテナ名>/<スナップショット名>
lxc exec <コンテナ名> bash
lxc exec <コンテナ名> -- ls -l
lxc exec <コンテナ名> -- bash -c "lsof | grep deleted"
lxc exec <コンテナ名> -- sh -c "lsof | vi -R -"
lxc config device add <コンテナ名> <デバイス名> disk source=<ホスト側マウント元ディレクトリ> path=<コンテナディレクトリ>
lxc config device add linuxcontainer vagrant disk source=/vagrant/ path=/vagrant/
lxc config device remove <コンテナ名> <デバイス名>
lxc 3.x
lxc copy --instance-only <コピー元コンテナ> <コピー先コンテナ>
※–instance-only: スナップショットはコピーしない
lxc 2.x
lxc copy --container-only <コピー元コンテナ> <コピー先コンテナ>
lxc rename <変更前> <変更後>
rename はスナップショット名の変更にも使用可能
lxc file push /localdir/hoge.txt <コンテナ名>/remotedir/
lxc file push -r /localdir <コンテナ名>/remotedir/
lxc file pull <コンテナ名>/remotedir/hoge.txt /localdir/
lxc file push -r <コンテナ名>/remotedir /localdir/
lxc snapshot hoge
lxc info --verbose hoge
lxc publish hoge/snap0 --alias hoge_exp
lxc image export hoge_exp
for C in cntname; do echo ${C}; lxc snapshot ${C} exp; lxc info --verbose ${C}; lxc publish ${C}/exp --alias ${C}_exp; lxc image export ${C}_exp ${C}; lxc image delete ${C}_exp; lxc delete ${C}/exp; done
「exp」という名前のスナップショットを作成してエクスポート
for C in cntname; do echo ${C}; lxc image import ${C}.tar.gz --alias ${C}_exp; lxc init ${C}_exp ${C}; lxc image delete ${C}_exp; done
vi /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=dhcp
ONBOOT=yes
HOSTNAME=mymchine
NM_CONTROLLED=no
TYPE=Ethernet
MTU=
DHCP_HOSTNAME=`hostname`
PEERDNS=no
lxc exec <コンテナ名> bash
で接続した時に読み込まれる設定# vi ~/.bashrc
export LANG=ja_JP.UTF-8
=> /etc/bashrc の末尾にでも記述しておくと全ユーザーに反映する。
vagrant 上の Linux で実行しているコンテナから、ホスト側(例: VirtualBox の共有フォルダ)に書き込めるようにする
(例) コンテナの uid 3000, gid 3000 のユーザーを、ホストの uid 1000, gid 1000 にマッピングして、ホスト側のフォルダに書き込めるようにする。
(注) idmap は security.privileged が true に設定されていると効かない。
sudo groupadd -g 3000 hoge
sudo useradd -g hoge -u 3000 -m hoge
config.vm.synced_folder "./share", "/share", owner: "hoge", group: "hoge"
lxc config set containername raw.idmap 'both 3000 3000'
lxc start containername
lxc exec containername bash
su - hoge
ls -l /share
groupadd -g 3000 hoge
useradd -g hoge -u 3000 -m hoge
root:3000:1
※ 結果的に subuid と subgid は特に設定してなくてもうまく参照できている模様。
lxc config set <コンテナ名> raw.idmap 'both 1000 3000'
lxc restart <コンテナ名>
cd ~/vagrant/vmxxx
mkdir share2
Vagrant.configure("2") do |config|
から end
の間に次の設定を追加して、vagrant(vm) を起動。
config.vm.synced_folder "./share2", "/share2", owner: "fuga"
vagrant ssh
groupadd -g 3000 fuga
useradd -g fuga -u 3000 -m fuga -s /bin/bash
lxc start container-name
lxc exec container-name bash
groupadd -g 5000 fuga
useradd -g fuga -u 5000 -m fuga -s /bin/bash
lxc config set container-name raw.idmap 'uid 1000-3000 3000-5000'
lxc restart container-name
lxc config device add <コンテナ名> <転送設定に付ける名前> proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80 bind=host
設定確認
lxc config device show <コンテナ名>
設定削除
lxc config device remove <コンテナ名> <転送設定に付けた名前>
sudo iptables -t nat -A PREROUTING -p tcp -i eth1 --dport 8080 -j DNAT --to-destination 192.168.1.1:80
sudo route add <目的のIP/サブネット> <ルーターIP>
sudo route add 172.16.1.0/24 192.168.1.254
sudo ip r add <目的のIP/サブネット> via <NATアダプター側のGWアドレス>
sudo ip r add 172.16.1.0/24 via 10.1.2.1
ip r add 192.168.1.0/24 via <lxdbr0のIP>
以下、確認した内容。
sudo ip l set eth1 down
ps ax | grep dhclient
sudo kill xxx
sudo dhclient eth0
ip r
(例) default via 172.16.1.1 dev eth0
と表示された場合
ps ax | grep dhclient
sudo kill xxx
sudo dhclient eth0 eth1
ip r add 192.168.1.0/24 via 172.16.1.1
今回は root で実行
[main]
keepcache=0
exactarch=1
obsoletes=1
gpgcheck=0
plugins=1
[base]
name=CentOS-7.5 - Base
baseurl=http://ftp.jaist.ac.jp/pub/Linux/CentOS-vault/7.5.1804/os/x86_64/
[update]
name=CentOS-7.5 - Update
baseurl=http://ftp.jaist.ac.jp/pub/Linux/CentOS-vault/7.5.1804/updates/x86_64/
date +%s
{
"architecture": "x86_64",
"creation_date": 1556402782,
"properties": {
"architecture": "x86_64",
"description": "Centos 7.5(x86_64)",
"name": "centos-7.5-x86_64",
"os": "centos",
"release": "7.5",
"variant": "default"
}
}
cd /tmp/centos75
chroot rootfs/
echo "export LANG=C" >> /root/.bashrc
echo "export LANG=C" >> /etc/locale.conf
exit
tar zcvf /tmp/centos75.tgz metadata.yaml rootfs
lxc image import centos75.tgz --alias centos7.5
※alias を付け忘れた場合は、次のようにしてインポート済みのイメージに alias を設定。
lxc image alias create centos7.5 <fingerprint>
あとは alias を指定してコンテナを作成。
lxc launch centos7.5 c75
rm -rf centos75
rm: cannot remove 'centos75/rootfs/var/lib/machines': Operation not permitted
btrfs コマンドで machines を削除してから、rm コマンドで全体を削除。
btrfs subvolume delete centos75/rootfs/var/lib/machines/
Delete subvolume (no-commit): '/tmp/centos75/rootfs/var/lib/machines'
rm -rf centos75/rootfs/var/lib/
root で実行
次のように docker で実行
docker run -it --rm -v /vagrant:/vagrant --name lxcbuild oraclelinux:8.4 /bin/bash
[main]
keepcache=0
exactarch=1
obsoletes=1
gpgcheck=0
plugins=1
[ol8_baseos]
name=Oracle Linux 8 BaseOS Latest ($basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/4/baseos/base/x86_64/
[ol8_appstream]
name=Oracle Linux 8 Application Stream ($basearch)
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/appstream/x86_64/
mkdir -p /tmp/ol84/rootfs
yum -c /tmp/ol84.conf --disablerepo="*" --enablerepo="ol8_baseos,ol8_appstream" --installroot=/tmp/ol84/rootfs -y groupinstall Core
yum -c /tmp/ol84.conf --disablerepo="*" --enablerepo="ol8_baseos,ol8_appstream" --installroot=/tmp/ol84/rootfs -y install dhclient
yum -c /tmp/ol84.conf --disablerepo="*" --enablerepo="ol8_baseos,ol8_appstream" -y install tar
date +%s
{
"architecture": "x86_64",
"creation_date": 1619875931,
"properties": {
"architecture": "x86_64",
"description": "Oralce Linux 8.4(x86_64)",
"name": "oraclelinux-8.4-x86_64",
"os": "oraclelinux",
"release": "8.4",
"variant": "default"
}
}
cd /tmp/ol84
chroot rootfs/
echo "export LANG=C" >> /root/.bashrc
echo "export LANG=C" >> /etc/locale.conf
vi /etc/rc.local
#!/bin/bash
touch /var/lock/subsys/local
chmod 755 /etc/rc.local
exit
tar zcvf /vagrant/lxc/ol84.tgz metadata.yaml rootfs
ホスト側で実行
lxc image import /vagrant/lxc/ol84.tgz --alias oraclelinux8.4
lxc launch oraclelinux8.4 ol84
(注意)
eth0, eth1(lxc network attach eth0 <コンテナ名> eth1 で追加後) に DHCP アドレスを割り当てがうまくいかない現象の対応コンテナ名>
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
HOSTNAME=`cat /proc/sys/kernel/hostname`
TYPE=Ethernet
MTU=
DHCP_HOSTNAME=`cat /proc/sys/kernel/hostname`
dhclient eth0 eth1
After=network.target remote-fs.target nss-lookup.target rc-local.service
chmod 755 /etc/rc.local
chmod 755 /etc/rc.d/rc.local
lxc restart <コンテナ名>
⬇︎ この方法はうまくいかなかった
eth0 に DHCP アドレスを割り当てるため、Oracle Linux 8.4 のコンテナ起動後、次のコマンド実行が必要?
nmcli c modify eth0 ipv4.method auto
それでもだめな場合は、起動時にコマンド実行して固定IP を割り当てる。
ip a add 192.168.1.1/24 dev eth0
ip r add default via 192.168.1.254
chmod 755 /etc/rc.d/rc.local
nameserver 192.168.1.254
sudo mount -rt iso9660 OracleLinux-R8-U10-x86_64-dvd.iso /mnt
docker run -it --rm -v /vagrant:/vagrant -v /mnt:/ol810iso --name lxcbuild oraclelinux:8.10 /bin/bash
[main]
keepcache=0
exactarch=1
obsoletes=1
gpgcheck=0
plugins=1
[ol810_baseos]
name=Oracle Linux 8 BaseOS Latest ($basearch)
baseurl=file:///ol810iso/BaseOS/
[ol810_appstream]
name=Oracle Linux 8 Application Stream ($basearch)
baseurl=file:///ol810iso/AppStream/
mkdir -p /tmp/ol810/rootfs
yum -c /tmp/ol810.conf --disablerepo="*" --enablerepo="ol810_baseos,ol810_appstream" --installroot=/tmp/ol810/rootfs -y groupinstall Core
さらに dhclient もインストール。
yum -c /tmp/ol810.conf --disablerepo="*" --enablerepo="ol810_baseos,ol810_appstream" --installroot=/tmp/ol810/rootfs -y install dhclient
yum -c /tmp/ol810.conf --disablerepo="*" --enablerepo="ol810_baseos,ol810_appstream" -y install tar
date +%s
{
"architecture": "x86_64",
"creation_date": 1740104480,
"properties": {
"architecture": "x86_64",
"description": "Oralce Linux 8.10(x86_64)",
"name": "oraclelinux-8.10-x86_64",
"os": "oraclelinux",
"release": "8.10",
"variant": "default"
}
}
cd /tmp/ol810
chroot rootfs/
echo "export LANG=C" >> /root/.bashrc
echo "export LANG=C" >> /etc/locale.conf
Oracle Linux 8.10 では rc.local が存在するのでこれも不要そう。
vi /etc/rc.local
#!/bin/bash
touch /var/lock/subsys/local
chmod 755 /etc/rc.d/rc.local
exit
tar zcvf /vagrant/ol810.tgz metadata.yaml rootfs
Docker を抜ける
exit
ホスト側で実行
lxc image import /vagrant/ol810.tgz --alias oraclelinux8.10
lxc launch oraclelinux8.10 ol810
# zfspool がインストールされていない場合
sudo apt install zfsutils-linux
# プールの使用状況を確認
lxc storage info default
info:
(略)
space used: 5.41GiB
total space: 5.59GiB
# ストレージプールを 10GB 拡張
sudo truncate -s +10G /var/snap/lxd/common/lxd/disks/default.img
sudo zpool set autoexpand=on default
sudo zpool online -e default /var/snap/lxd/common/lxd/disks/default.img
sudo zpool set autoexpand=off default
# btrfs の使用状況を確認
$ lxc storage info default
info:
(略)
space used: 5.41GiB
total space: 5.59GiB
# btrfsイメージファイルのパスとデバイス名を確認
$ losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
(略)
/dev/loop4 0 0 1 0 /var/snap/lxd/common/lxd/disks/default.img 1 512
$ sudo truncate -s +10G /var/snap/lxd/common/lxd/disks/default.img
$ sudo losetup -c /dev/loop4
$ sudo mount /dev/loop4 /mnt
$ sudo btrfs filesystem resize max /mnt
Resize device id 1 (/dev/loop4) from 5.59GiB to max
$ sudo btrfs filesystem show
Label: 'default' uuid: 20355e24-9d32-4424-ab34-1ac359613a9a
Total devices 1 FS bytes used 5.24GiB
devid 1 size 15.59GiB used 6.59GiB path /dev/loop4
$ lxc storage info default
info:
space used: 5.41GiB
total space: 15.59GiB
$ df -h
(略)
/dev/loop2 34G 33G 24M 100% /var/lib/lxd/storage-pools/default
$ sudo truncate -s +15G /var/lib/lxd/disks/default.img
$ sudo losetup -c /dev/loop2
$ sudo btrfs filesystem resize max /var/lib/lxd/storage-pools/default/
$ df -h
(略)
/dev/loop2 49G 33G 16G 69% /var/lib/lxd/storage-pools/default
sudo mv /var/lib/lxd/images /data/
sudo ln -s /data/images /var/lib/lxd/
vi ~/.vimrc
:set encoding=utf-8
:set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
:set fileformats=unix,dos,mac
[LXC 5.0]
sudo ln -s /snap/lxd/current/etc/bash_completion.d/snap.lxd.lxc /etc/bash_completion.d/lxc
(参考) [LXD 4.7] Autocompletion on ubuntu 20.04
[LXC 3.0]
sudo cp -p /usr/share/bash-completion/completions/lxc /etc/bash_completion.d/
この状態で . /etc/bash_completion.d/lxc
すると「-bash: _have: command not found」というエラーが発生する。
sudo apt install bash-completion
するのが正しそう
そこで sudo vi /etc/bash_completion.d/lxc して、先頭に次の行を追加して回避。
_have()
{
# Completions for system administrator commands are installed as well in
# case completion is attempted via `sudo command ...'.
PATH=$PATH:/usr/sbin:/sbin:/usr/local/sbin type $1 &>/dev/null
}
(参考) v1.3.6 installed via Homebrew on macOS causes Bash _have
error #500
Ubuntu 22.04 では、フォワードチェーンがデフォルトで無効になっているため、有効にする。
#!/bin/sh
/usr/sbin/iptables -P FORWARD ACCEPT
(参考)
次のコマンドで確認すると、nftables でパケットがドロップされているという話。
sudo nft list ruleset
(補足)
Ubuntu 20.04 あたりから /etc/network/if-up.d/ 配下のスクリプトが実行されなくなっている模様。
代わりに /etc/networkd-dispatcher/routable.d/ 配下にスクリプトファイルを置く。
(参考) Ubuntu Server 20.04 で VXLAN を構成する
LXC 5.0 ではデフォルトで CGroupV2 が使われるが、この現象を回避するためには(モダンなホストで古いコンテナを動かす場合は)CGroupV1 を使う。
具体的にはカーネルブートパラメーターに「systemd.unified_cgroup_hierarchy=false」を追加。
GRUB_CMDLINE_LINUX_DEFAULT="systemd.unified_cgroup_hierarchy=false"
sudo update-grub
cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-5.15.0-48-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro net.ifnames=0 biosdevname=0 systemd.unified_cgroup_hierarchy=false
(参考) Error: The image used by this instance requires a CGroupV1 host system when using clustering
lxc config set <コンテナ名> security.privileged true
lxc config show <コンテナ名>
(例) Vagrantfile に次の設定を追加すると
config.vm.synced_folder "./share", "/share", owner: "hoge", group: "hoge"
次のメッセージが表示される。
Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem “vboxsf” is not available. This filesystem is made available via the VirtualBox Guest Additions and kernel module.
確認1: mount.vboxsf のシンボリックリンクが正しいか確認。
ls -l /usr/sbin/mount.vboxsf
解決: vagrant-vbguest をインストール
vagrant plugin install vagrant-vbguest
Installing the ‘vagrant-vbguest’ plugin. This can take a few minutes…
Fetching micromachine-3.0.0.gem
Fetching vagrant-vbguest-0.32.0.gem
Installed the plugin ‘vagrant-vbguest (0.32.0)’!
次のメッセージが表示される。
Got different reports about installed GuestAdditions version:
Virtualbox on your host claims: 6.0.0
VBoxService inside the vm claims: 7.0.20
Going on, assuming VBoxService is correct…
[default] GuestAdditions 7.0.20 running — OK.
(解決策) Vagrantfile に次の設定を追加。
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
(参考) stackoverflow: vagrant up: Got different reports about installed GuestAdditions version
lxc launch images:centos/7/amd64 <コンテナ名>
lxc stop <コンテナ名>
lxc network attach lxdbr0 <コンテナ名> eth0
# DHCPで割り当てられるIPアドレスが変わらないようにする
lxc config device set <コンテナ名> eth0 ipv4.address 192.168.xxx.xxx
# 外部からの接続が必要な場合だけ NIC を追加
------------------------------------------------------------
lxc network attach eth1 <コンテナ名> eth1
------------------------------------------------------------
# 特定の MACアドレスを割り当てる場合
lxc config set <コンテナ名> volatile.eth0.hwaddr 12:34:56:78:90:ab
# 共有フォルダの uid/gid を合わせる
lxc config set <コンテナ名> raw.idmap 'both 3000 3000'
# ホストの 1000(vagrant) をコンテナの root(0) も追加でマッピングして、root から /vagrant フォルダに書き込めるようにする場合
echo -e "both 1000 0\nboth 3000 3000" | lxc config set <コンテナ名> raw.idmap -
lxc config device add <コンテナ名> vagrant disk source=/vagrant path=/vagrant
lxc start <コンテナ名>
lxc exec <コンテナ名> bash
timedatectl set-timezone Asia/Tokyo
localectl set-locale LANG=ja_JP.utf8
# 外部からの接続が必要な場合だけ NIC を設定
cp -p /etc/sysconfig/network-scripts/ifcfg-eth{0,1}
# Wi-Fi 接続時など、eth1 経由で外に出ていけない場合は、eth0 をデフォルトゲートウェイに設定する。
vi /etc/sysconfig/network
------------------------------------------------------------
# eth0 側のデフォルトゲートウェイを指定
GATEWAY=xxx.xxx.xxx.xxx
------------------------------------------------------------
# eth1 の DHCP 設定を作成
vi /etc/sysconfig/network-scripts/ifcfg-eth1
------------------------------------------------------------
DEVICE=eth1
BOOTPROTO=dhcp
ONBOOT=yes
HOSTNAME=<コンテナ名>
NM_CONTROLLED=no
TYPE=Ethernet
MTU=
DHCP_HOSTNAME=<コンテナ名>
# DHCP で resolv.conf を更新させたくない場合は、この設定を有効にする。
#PEERDNS=no
------------------------------------------------------------
Wi-Fi 経由でインターネットに接続する場合は、さらに lxdbr0 のネットワークをデフォルトゲートウェイに設定する
(例) lxdbr0 のネットワークが 172.16.0.0/16 の場合
[とりあえず]
ip r del default
ip r add default via 172.16.0.1
[設定]
/etc/sysconfig/network-scripts/ifcfg-eth0
GATEWAY=172.16.0.1
さらに /etc/resolv.conf に DNS を設定(eth1 経由で DHCP で取得した DNS の IP ではなく)
exit
# DHCP 設定を反映させるためにいったん停止して起動
lxc stop <コンテナ名>
lxc start <コンテナ名>
lxc exec <コンテナ名> bash
# IPアドレス割り当てを確認(eth1 は DHCPアドレス取得に少し時間がかかることがある)
ip a
#!/bin/sh
/sbin/ip link set eth1 promisc on
#!/bin/sh
/usr/sbin/iptables -P FORWARD ACCEPT
:set encoding=utf-8
:set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
:set fileformats=unix,dos,mac