#author("2026-03-02T22:38:33+00:00","default:sysosa","sysosa") #author("2026-03-03T15:15:11+00:00","default:sysosa","sysosa") ドキュメント [[https://linuxcontainers.org/>+https://linuxcontainers.org/]] の中の [[https://linuxcontainers.org/incus/introduction/>+https://linuxcontainers.org/incus/introduction/]] github [[https://github.com/lxc/incus>+https://github.com/lxc/incus]] incusでcs[[Incus/cryoSPARC]] LXDのフォーク. コンテナ技術なのですが、Docker は「軽量なアプリ実行」、Incus は「軽量な VM 代替」という立ち位置のご様子. ここでは Incus を簡単に導入してみる. #code(nonumber){{ [root@incus ~]# cat /etc/redhat-release Rocky Linux release 9.6 (Blue Onyx) [root@incus ~]# dnf copr enable neil/incus [root@incus ~]# dnf install epel-release [root@incus ~]# dnf config-manager --enable crb [root@incus ~]# dnf install incus incus-tools }} ここで新しいgroupが作られます #code(nonumber){{ [root@incus ~]# cat /etc/group : incus-admin:x:995: incus:x:994: [root@incus ~]# }} っでincusの daemon を起動させます. #code(nonumber){{ [root@incus ~]# systemctl enable incus --now [root@incus ~]# systemctl status incus ● incus.service - Incus - Daemon Loaded: loaded (/usr/lib/systemd/system/incus.service; indirect; preset: disabled) Active: active (running) since Tue 2026-03-03 07:02:41 JST; 2min 24s ago TriggeredBy: ● incus.socket Docs: man:incusd(1) Process: 3960 ExecStartPost=/usr/libexec/incus/incusd waitready --timeout=600 (code=exited, status=0/SUCCESS) Main PID: 3959 (incusd) Tasks: 16 Memory: 35.8M (peak: 57.6M) CPU: 217ms CGroup: /system.slice/incus.service mq3959 /usr/libexec/incus/incusd --group incus-admin Mar 03 07:02:40 incus systemd[1]: Starting Incus - Daemon... Mar 03 07:02:40 incus incusd[3959]: time="2026-03-03T07:02:40+09:00" level=error msg="Unable to parse system idmap" err="No map found for user" Mar 03 07:02:40 incus incusd[3959]: time="2026-03-03T07:02:40+09:00" level=warning msg="AppArmor support has been disabled because of lack of kernel > Mar 03 07:02:40 incus incusd[3959]: time="2026-03-03T07:02:40+09:00" level=warning msg=" - AppArmor support has been disabled, Disabled because of la> Mar 03 07:02:40 incus incusd[3959]: time="2026-03-03T07:02:40+09:00" level=warning msg="Instance type not operational" driver=qemu err="QEMU command > Mar 03 07:02:41 incus systemd[1]: Started Incus - Daemon. [root@incus ~]# [root@incus ~]# incus version Client version: 6.8 Server version: 6.8 [root@incus ~]# }} incusのストレージプールを用意します。 ここではフィルシステムをそのまま使います. zfsとかbtrfsの方が高速なのですが、面倒なので。 #code(nonumber){{ parted /dev/sdb (parted) mklabel gpt (parted) mkpart primary 0% 100% (parted) quit mkfs.ext4 -m 0 /dev/sdb1 e2label /dev/sdb1 incus echo "LALABEL=incus /incus ext4 defaults 0 0" >> /etc/fstab mkdir /incus systemctl daemon-reload mount -a }} っで構築開始 #code(nonumber){{ [root@incus ~]# mkdir /incus/default -p [root@incus ~]# incus admin init }} 以降下記のような設問が出てきます。ここでは下記のようにしてみました。 |BGCOLOR(YELLOW):質問|BGCOLOR(YELLOW):解答|BGCOLOR(YELLOW):備考| |Would you like to use clustering? (yes/no) [default=no]:|no|clusterは作らないので| |Do you want to configure a new storage pool? (yes/no) [default=yes]:|yes|ストレージプールを今作るので。後で作るならno| |Name of the new storage pool [default=default]:|default|ストレージプールの名称| |Name of the storage backend to use (dir, zfs, lvm, ceph, btrfs) [default=zfs]:|dir|zfs,lvm2,cephらのモジュール、ライブラリがあれば問われる. なければdirでこの設問は表示されない| |Where should this storage pool store its data? [default=/var/lib/incus/storage-pools/default]:|/incus/default|dirでのストレージプールの場所| |Would you like to create a new local network bridge? (yes/no) [default=yes]:|no|作成するコンテナは今あるネットワークに直に接続させたいので| |Would you like to use an existing bridge or host interface? (yes/no) [default=no]:|no|複数のコンテナを作りたいので、あとで作成します| |Would you like the server to be available over the network? (yes/no) [default=no]:|no|incusの管理サービスに外部からアクセスするならyes| |Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:|no|コンテナを作る際に使用するイメージ(iso)を更新するかどうか. コンテナは更新されない| |Would you like a YAML "init" preseed to be printed? (yes/no) [default=no]:|no|設定記録はいらないや| 構築が完了すると /incus/default は下記のようになります #code(nonumber){{ [root@incus ~]# ls -l /incus/default/ drwx--x--x. 2 root root 6 Mar 3 07:06 buckets drwx--x--x. 2 root root 6 Mar 3 07:06 containers drwx--x--x. 2 root root 6 Mar 3 07:06 containers-snapshots drwx--x--x. 2 root root 6 Mar 3 07:06 custom drwx--x--x. 2 root root 6 Mar 3 07:06 custom-snapshots drwx--x--x. 2 root root 6 Mar 3 07:06 images drwx--x--x. 2 root root 6 Mar 3 07:06 virtual-machines drwx--x--x. 2 root root 6 Mar 3 07:06 virtual-machines-snapshots [root@incus ~]# }} ***ネットワークの準備 [#d777a55e] #code(nonumber){{ [root@incus ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp6s18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether bc:24:11:c5:d2:99 brd ff:ff:ff:ff:ff:ff [root@incus ~]# modprobe macvlan [root@incus ~]# incus network create pubnet --type=macvlan parent=enp6s18 [root@incus ~]# incus network list +---------+----------+---------+------+------+-------------+---------+---------+ | NAME | TYPE | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY | STATE | +---------+----------+---------+------+------+-------------+---------+---------+ | enp6s18 | physical | NO | | | | 1 | | +---------+----------+---------+------+------+-------------+---------+---------+ | lo | loopback | NO | | | | 0 | | +---------+----------+---------+------+------+-------------+---------+---------+ | pubnet | macvlan | YES | | | | 0 | CREATED | +---------+----------+---------+------+------+-------------+---------+---------+ [root@incus ~]# }} あと再起動時にmacvlanをロードさせるために #code(nonumber){{ [root@incus ~]# echo macvlan | tee /etc/modules-load.d/macvlan.conf }} とします ***incus管理者アカウントを作成します [#nd325b1d] 複数の管理者アカウントを用意しても構いません. ここでは1つ作ります. 管理作業が必要ならこのアカウントにsuすればいいかなと. #code(nonumber){{ useradd -s /bin/bash incus-supervisor }} ローカルでユーザを作成するとUID/GIDマッピングが自動で作れれますが、修正します。rootにも用意することが大事みたい. #code(nonumber){{ [root@incus ~]# cat /etc/subuid root:1000000:65536 incus-supervisor:1100000:65536 [root@incus ~]# cat /etc/subgid root:1000000:65536 incus-supervisor:1100000:65536 [root@incus ~]# }} 一端incusを再起動させて、次に作った管理者アカウント「incus-supervisor」をグループ「incus-admin」に加えます #code(nonumber){{ [root@incus ~]# systemctl restart incus [root@incus ~]# usermod -aG incus-admin incus-supervisor [root@incus ~]# grep incus-admin /etc/group incus-admin:x:995:incus-supervisor [root@incus ~]# }} ***コンテナ作成 [#q209e896] 作成した管理者アカウント「incus-supervisor」でコンテナ作成と化します 現在のコンテナの状態は「incus list」で得られます #code(nonumber){{ [incus-supervisor@incus ~]$ incus list To start your first container, try: incus launch images:ubuntu/22.04 Or for a virtual machine: incus launch images:ubuntu/22.04 --vm +------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+ [incus-supervisor@incus ~]$ }} っでコンテナを作ります #code(nonumber){{ [incus-supervisor@incus ~]$ incus launch images:rockylinux/9 myapp1 --network pubnet Launching myapp1 [incus-supervisor@incus ~]$ [incus-supervisor@incus ~]$ incus list +--------+---------+------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+------+------+-----------+-----------+ | myapp1 | RUNNING | | | CONTAINER | 0 | +--------+---------+------+------+-----------+-----------+ [incus-supervisor@incus ~]$ }} 残念なことに「IPV4」の値がないので、このコンテナは外部との接続ができないです。 原因は使用したrockylinux9のイメージが超軽量級で用意されているためみたい. っで #code(nonumber){{ [incus-supervisor@incus ~]$ incus exec myapp1 -- ip link set eth0 up [incus-supervisor@incus ~]$ incus exec myapp1 -- dhclient eth0 }} っとすればdhcp経由になりますが、ipが付与される。 そして「incus list」とすると #code(nonumber){{ [incus-supervisor@incus ~]$ incus list +--------+---------+----------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+----------------------+------+-----------+-----------+ | myapp1 | RUNNING | 192.168.0.222 (eth0) | | CONTAINER | 0 | +--------+---------+----------------------+------+-----------+-----------+ [incus-supervisor@incus ~]$ }} っが「incus restart myapp1」とコンテナを再起動すると再度ipが付与されず上がります。 それを防ぐには「incus exec myapp1 -- bash」でマシンに入って root の crontab に 「@reboot /usr/sbin/dhclient」を追記します。これで再起動後もあがるそうな. ***コンテナ操作 [#m1ea018c] #code(nonumber){{ [incus-supervisor@incus ~]$ incus stop myapp1 *強制停止は「incus stop myapp1 --force」 [incus-supervisor@incus ~]$ incus start myapp1 [incus-supervisor@incus ~]$ incus restart myapp1 [incus-supervisor@incus ~]$ incus snapshot create myapp1 myapp1-orig *スナップショット [incus-supervisor@incus ~]$ incus snapshot list myapp1 *myapp1のスナップショット一覧 +-------------+----------------------+------------+----------+ | NAME | TAKEN AT | EXPIRES AT | STATEFUL | +-------------+----------------------+------------+----------+ | myapp1-orig | 2025/09/23 03:48 JST | | NO | +-------------+----------------------+------------+----------+ [incus-supervisor@incus ~]$ incus snapshot restore myapp1 myapp1-orig *スナップショットのリストア [incus-supervisor@incus ~]$ incus snapshot delete myapp1 myapp1-orig *スナップショットの削除 [incus-supervisor@incus ~]$ incus snapshot list myapp1 +------+----------+------------+----------+ | NAME | TAKEN AT | EXPIRES AT | STATEFUL | +------+----------+------------+----------+ [incus-supervisor@incus ~]$ incus export myapp1 ./myapp1-backup.tar.gz --instance-only *スナップショットなしでバックアップ [incus-supervisor@incus ~]$ ls -hl ./myapp1-backup.tar.gz -rw-r--r--. 1 incus-supervisor incus-supervisor 152M Sep 23 03:53 ./myapp1-backup.tar.gz [incus-supervisor@incus ~]$ incus delete myapp1 [incus-supervisor@incus ~]$ incus list +------+-------+------+------+------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+-------+------+------+------+-----------+ [incus-supervisor@incus ~]$ incus import ./myapp1-backup.tar.gz myapp1-backup *バックアップからのインポート [incus-supervisor@incus ~]$ incus list +---------------+---------+------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +---------------+---------+------+------+-----------+-----------+ | myapp1-backup | STOPPED | | | CONTAINER | 0 | +---------------+---------+------+------+-----------+-----------+ [incus-supervisor@incus ~]$ incus rename myapp1-backup myapp1 *コンテナ名称変更 [incus-supervisor@incus ~]$ incus copy myapp1 myapp2 *コンテナのクローン作製 [incus-supervisor@incus ~]$ incus list +--------+---------+------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+------+------+-----------+-----------+ | myapp1 | STOPPED | | | CONTAINER | 0 | +--------+---------+------+------+-----------+-----------+ | myapp2 | STOPPED | | | CONTAINER | 0 | +--------+---------+------+------+-----------+-----------+ }} ***もしbridgeデバイスがあるなら [#qe007642] #code(nonumber){{ 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp6s18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master nm-bridge state UP mode DEFAULT group default qlen 1000 link/ether bc:24:11:c5:d2:99 brd ff:ff:ff:ff:ff:ff 3: nm-bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether bc:24:11:c5:d2:99 brd ff:ff:ff:ff:ff:ff }} なら「incus network list」の値は下記になります #code(nonumber){{ [incus-supervisor@incus ~]$ incus network list +-----------+----------+---------+------+------+-------------+---------+-------+ | NAME | TYPE | MANAGED | IPV4 | IPV6 | DESCRIPTION | USED BY | STATE | +-----------+----------+---------+------+------+-------------+---------+-------+ | enp6s18 | physical | NO | | | | 0 | | +-----------+----------+---------+------+------+-------------+---------+-------+ | lo | loopback | NO | | | | 0 | | +-----------+----------+---------+------+------+-------------+---------+-------+ | nm-bridge | bridge | NO | | | | 0 | | +-----------+----------+---------+------+------+-------------+---------+-------+ [root@incus ~]# }} プロファイルを作成 #code(nonumber){{ [incus-supervisor@incus ~]$ incus profile create app-profile [incus-supervisor@incus ~]$ incus profile edit app-profile config: {} description: cryoSAPRC master node devices: root: path: / pool: default type: disk name: app-profile [incus-supervisor@incus ~]$ (コンテナ作成) [incus-supervisor@incus ~]$ incus launch images:rockylinux/9 myapp1 --profile app-profile (nic付与) [incus-supervisor@incus ~]$ incus config device add myapp1 eth0 nic nictype=bridged parent=nm-bridge }} として構築します ***コンテナ内でのnfs-mount [#h56f8d70] コンテナを特権モードで動かせば、コンテナ内でも直接mountできるみたい でも、ここでは「ホスト」でrootがnfs-mountした場所を使うようにしてみた #code(nonumber){{ [root@incus ~]# dnf install nfs-utils -y [root@incus ~]# mkdir /Public [root@incus ~]# mount qnap:/Public /Public [root@incus ~]# df -ThF nfs4 Filesystem Type Size Used Avail Use% Mounted on qnap:/Public nfs4 15T 13T 2.2T 86% /Public [root@incus ~]# }} 管理者アカウントになって nfs を張る #code(nonumber){{ [root@incus ~]# su - incus-supervisor [incus-supervisor@incus ~]$ incus start myapp1 [incus-supervisor@incus ~]$ incus list +--------+---------+----------------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +--------+---------+----------------------+------+-----------+-----------+ | myapp1 | RUNNING | 192.168.0.222 (eth0) | | CONTAINER | 0 | +--------+---------+----------------------+------+-----------+-----------+ | myapp2 | STOPPED | | | CONTAINER | 0 | +--------+---------+----------------------+------+-----------+-----------+ [incus-supervisor@incus ~]$ [incus-supervisor@incus ~]$ incus config device add myapp1 mynfs disk source=/Public path=/mnt/nfs *ホストの/Publicをコンテナの /mnt/nfs に繋げる [incus-supervisor@incus ~]$ incus exec myapp1 -- bash [root@myapp1 ~]# df -ThF nfs4 Filesystem Type Size Used Avail Use% Mounted on qnap:/Public nfs4 15T 13T 2.2T 86% /mnt/nfs [root@myapp1 ~]# }} ***コンテナへssh接続 [#n8de99a4] rockylinux9イメージでは最小構成なので初めから openssh-server は入ってなくサービスもない。なのでコンテナ内にインストールします #code(nonumber){{ [incus-supervisor@incus ~]$ incus exec myapp1 -- bash [root@myapp1 ~]# dnf install openssh-server [root@myapp1 ~]# vi /etc/ssh/sshd_config : PermitRootLogin yes : [root@myapp1 ~]# [root@myapp1 ~]# systemctl restart sshd [root@myapp1 ~]# passwd <-- ここではrootで入れるようにしてます }} っでホストではない別のマシンから入ってみた #code(nonumber){{ [root@rockylinux9 ~]# ssh -l root 192.168.0.222 The authenticity of host '192.168.0.222 (192.168.0.222)' can't be established. ED25519 key fingerprint is SHA256:VpXNDwbOSjLgvaxLi8hB1TET0peyiXb3e77o6YWIxEk. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.0.222' (ED25519) to the list of known hosts. root@192.168.0.222's password: Last login: Tue Sep 23 03:07:10 2025 from 192.168.0.3 [root@myapp1 ~]# }} と行けた。 だが、コンテナを主催するホストから接続を試みると #code(nonumber){{ [incus-supervisor@incus ~]$ ssh -l root 192.168.0.222 ssh: connect to host 192.168.0.222 port 22: No route to host You can find some explanations for typical errors at this link: https://red.ht/support_rhel_ssh [incus-supervisor@incus ~]$ }} と弾かれます。 それへの対処としてはホストの特定ポートに特定のホストの22を割り当てるようにします。proxyデバイスの付与って言われるみたい. #code(nonumber){{ incus config device add myapp1 sshproxy proxy \ listen=tcp:0.0.0.0:2222 \ connect=tcp:127.0.0.1:22 incus config device add myapp2 sshproxy proxy \ listen=tcp:0.0.0.0:2223 \ connect=tcp:127.0.0.1:22 }} コンテナ myapp1 には localhost:2222 が コンテナの22にアサイン。 コンテナ myapp2 には localhost:2223 が コンテナの22にアサイン。 って感じにします。 #code(nonumber){{ [incus-supervisor@incus ~]$ incus config device add myapp1 sshproxy proxy \ listen=tcp:0.0.0.0:2222 \ connect=tcp:127.0.0.1:22 Device sshproxy added to myapp1 [incus-supervisor@incus ~]$ (確認) [incus-supervisor@incus ~]$ incus config device list myapp1 eth0 mynfs sshproxy [incus-supervisor@incus ~]$ }} っで接続してみる #code(nonumber){{ [incus-supervisor@incus ~]$ ssh -l root -p 2222 localhost root@localhost's password: Last login: Tue Sep 23 11:42:35 2025 from 127.0.0.1 [root@myapp1 ~]# }} となる。 ***コンテナのサイズ [#e1c92065] ここでは「dir」とファイルシステムをそのまま使っていますが、ストレージプールのサイズがコンテナのsystem disk容量となるみたい. そして「dir」だと容量制限が付けられないようで、zfs, btrfs, lvmでストレージプールを作ったら制限ができるそうな. ***メモ [#f280cee2] 動作は極めて良好。再起動も滅茶苦茶はやい