วิธีติดตั้ง Incus system container บน VPS อย่างละเอียด
เรียนรู้วิธีติดตั้ง Incus บน VPS เพื่อรัน system container ที่มี init และผู้ใช้แยกอิสระ ครอบคลุมการตั้งค่า storage pool ระบบเครือข่าย และวิธีแก้ปัญหาเมื่อเกิดข้อผิดพลาด
Incus system container คืออะไร
Incus system container บน VPS มอบสภาพแวดล้อมเสมือนเครื่องคอมพิวเตอร์ทั้งเครื่องที่มีระบบ init และบัญชีผู้ใช้เป็นของตนเอง ไม่ใช่เพียงแค่กระบวนการเดียวที่ผูกติดกับระบบไฟล์ Container จะทำการบูต รันระบบ init เป็น PID 1 และตอบสนองต่อ systemctl โดยจะใช้ kernel ร่วมกับโฮสต์ จึงไม่ใช่ virtual machine แต่ทุกอย่างที่อยู่เหนือระดับ kernel จะทำงานเสมือนเป็นเครื่องแยกอิสระ
Incus เป็นโครงการ fork ของ LXD ที่ดูแลโดยชุมชนภายใต้โครงการ Linux Containers คำสั่งสำหรับฝั่งไคลเอนต์คือ incus นอกจากนี้ Incus ยังสามารถรัน virtual machine จริงผ่าน QEMU ได้เมื่อคุณระบุแฟล็ก --vm อย่างไรก็ตาม system container คือเหตุผลหลักที่คนส่วนใหญ่ติดตั้ง Incus และเป็นสิ่งที่คู่มือส่วนที่เหลือนี้จะกล่าวถึง
เหตุใดการเปรียบเทียบ Docker จึงทำให้ผู้คนเข้าใจผิด
Docker บรรจุเพียงหนึ่งกระบวนการ (process) ในขณะที่ Incus บรรจุหนึ่งระบบปฏิบัติการ เอกสารของ Incus ระบุความแตกต่างนี้ไว้อย่างชัดเจนว่า: "Application container (เช่นที่ Docker จัดหาให้) จะบรรจุเพียงกระบวนการหรือแอปพลิเคชันเดียว ในทางกลับกัน System container จะจำลองระบบปฏิบัติการเต็มรูปแบบคล้ายกับสิ่งที่คุณใช้งานบนโฮสต์หรือในเครื่องเสมือน (virtual machine)"
ความแตกต่างนี้เปลี่ยนวิธีการที่คุณใช้งานสิ่งเหล่านี้ในแต่ละวัน
- Docker image ไม่มีระบบ init ดังนั้น
systemctlภายในจึงทำงานล้มเหลว ในขณะที่ Incus container รันระบบ init ทำให้บริการและตัวตั้งเวลา (timer) ทำงานได้เช่นเดียวกับบนเซิร์ฟเวอร์ทั่วไป - Docker container ถูกออกแบบมาให้ทำลายและสร้างใหม่จาก Dockerfile ส่วน Incus container ถูกออกแบบมาให้คงอยู่ อัปเดตแพตช์ และทำ snapshot
- Docker image เป็นผลลัพธ์จากการ build ที่คุณต้อง push ไปยัง registry ส่วน Incus instance คือสถานะบนดิสก์ใน storage pool และคุณสามารถย้ายมันได้ด้วย
incus export - Docker แยกส่วนเฉพาะภาระงาน (workload) แต่ Incus แยกส่วนทั้งเครื่อง ดังนั้นหนึ่ง container จึงสามารถรองรับหลายภาระงานและหลายบัญชีผู้ใช้ได้
คุณสามารถรัน Docker ภายใน Incus system container ได้ แต่คุณไม่สามารถรัน Incus ภายใน Docker application container หากสิ่งที่คุณต้องการจริงๆ คือหนึ่งกระบวนการต่อหนึ่ง container พร้อมขั้นตอนการ build image Podman และ Docker บน VPS คือการเปรียบเทียบที่คุณควรอ่านเป็นอันดับแรก หากคุณต้องการ kernel แยกสำหรับแต่ละภาระงานแทนการใช้ kernel ร่วมกัน Firecracker microVMs บน VPS คือแนวทางในทิศทางตรงกันข้าม
Incus จะทำงานบน VPS ได้หรือไม่
ขึ้นอยู่กับประเภทการทำ Virtualisation ของ VPS และ Kernel ที่ใช้งาน ดังนั้นควรตรวจสอบทั้งสองอย่างก่อนเริ่มติดตั้ง อย่าเชื่อข้อมูลจากหน้าการตลาดของผู้ให้บริการเพียงอย่างเดียว ให้รันคำสั่งสี่รายการนี้บนเซิร์ฟเวอร์ของคุณ
systemd-detect-virt
uname -r
stat -fc %T /sys/fs/cgroup
cat /sys/fs/cgroup/cgroup.controllerssystemd-detect-virt หากแสดงผลเป็น kvm หรือ qemu หมายความว่า VPS ของคุณเป็น Virtual Machine ที่มี Kernel เป็นของตัวเอง ซึ่งเป็นกรณีที่จัดการได้ง่าย เพราะ Incus จะทำงานเหมือนกับรันบนฮาร์ดแวร์จริง หากแสดงผลเป็น lxc, lxc-libvirt หรือ openvz หมายความว่า VPS ของคุณเป็น Container ที่แชร์ Kernel ร่วมกับผู้ให้บริการ การรัน Incus ภายในนั้นจะเป็นการทำ Nested Container ซึ่งจะทำงานได้ก็ต่อเมื่อผู้ให้บริการเปิดใช้งานฟีเจอร์นี้ไว้ให้คุณเท่านั้น คุณไม่สามารถเปิดใช้งานเองจากภายในได้ เพราะการตั้งค่านี้อยู่ที่ฝั่ง Host ซึ่งคุณไม่มีสิทธิ์ควบคุม
stat -fc %T /sys/fs/cgroup ควรแสดงผลเป็น cgroup2fs หากเป็นค่าอื่นแสดงว่าเซิร์ฟเวอร์ใช้ cgroup (control group) v1 หรือแบบผสม ซึ่ง Incus เวอร์ชันปัจจุบันไม่รองรับ
cat /sys/fs/cgroup/cgroup.controllers จะแสดงรายการ control-group controller ที่ถูกส่งต่อมาให้คุณ Incus ระบุว่า blkio, cpuset, devices, freezer, memory และ pids เป็นสิ่งที่จำเป็น ในกรณีของ Nested VPS รายการนี้มักจะสั้นกว่าบน KVM เพราะผู้ให้บริการเป็นผู้เลือกสิ่งที่ส่งต่อมาให้ หาก controller ใดขาดหายไปจากไฟล์นี้ Incus จะไม่สามารถใช้งาน controller นั้นได้ ส่งผลให้ขีดจำกัดของ Instance ที่ต้องพึ่งพา controller ดังกล่าวไม่สามารถใช้งานได้
เวอร์ชันของ Kernel มีความสำคัญมากกว่าที่เคยเป็นมา ณ เดือนสิงหาคม 2026 เอกสารของ Incus ได้ระบุค่าขั้นต่ำที่แตกต่างกันสองค่าสำหรับสอง Branch ที่ทางต้นน้ำดูแลอยู่ Branch 6.0 LTS (long term support) ระบุว่า "เวอร์ชัน Kernel ขั้นต่ำที่รองรับคือ 5.4" ส่วน Branch Stable ปัจจุบันระบุว่า "เวอร์ชัน Kernel ขั้นต่ำที่รองรับคือ 6.12" Ubuntu 24.04 จัดเตรียมซีรีส์ 6.0 LTS ไว้ใน Repository ของตนเองและใช้คู่กับ Kernel 6.8 ซึ่งเป็นชุดที่รองรับการทำงานได้ แต่หากติดตั้ง Build Stable ปัจจุบันจาก Repository ต้นน้ำลงบน Kernel 6.8 เดียวกันนี้ จะถือว่าต่ำกว่าค่าขั้นต่ำที่ระบุไว้ ดังนั้นโปรดอ่าน uname -r ก่อนเลือก Repository
หากเป้าหมายของคุณคือการรัน Virtual Machine เต็มรูปแบบแทนที่จะเป็น Container ข้อจำกัดจะแตกต่างออกไปและทำได้ยากกว่า ดูข้อมูลเพิ่มเติมที่ การทำ nested virtualisation บน VPS เพื่อตรวจสอบว่า VPS ของคุณสามารถเปิดใช้งาน /dev/kvm ได้หรือไม่ และดูที่ Proxmox กับ VPS ที่เช่ามา สำหรับกรณีที่คุณเป็นเจ้าของฮาร์ดแวร์เอง
การติดตั้ง Incus บน Ubuntu หรือ Debian
Debian 13 และ Ubuntu 24.04 ขึ้นไปมี Incus มาให้ใน repository ของระบบเอง
sudo apt update
sudo apt install -y incusบน Debian คำสั่ง incus-base จะติดตั้งการรองรับ container โดยไม่รวมส่วนของ virtual machine สำหรับ Ubuntu ให้เพิ่ม qemu-system หากคุณต้องการใช้งาน instance แบบ --vm ด้วย
หากต้องการรุ่นที่ใหม่กว่าที่ distribution ของคุณมีให้ แพ็กเกจจากผู้พัฒนาโดยตรงจะอยู่ที่ pkgs.zabbly.com คำสั่งเหล่านี้มาจากไฟล์ README ใน repository ของโปรเจกต์โดยตรง
sudo apt update && sudo apt install -y curl
sudo mkdir -p /etc/apt/keyrings/
sudo curl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.asc
sudo sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-incus-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/incus/stable
Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.asc
EOF'
sudo apt-get update
sudo apt-get install -y incusจากนั้นให้สิทธิ์ผู้ใช้ของคุณในการเข้าถึง daemon socket
sudo usermod -aG incus-admin "$USER"
newgrp incus-admin
incus infoincus info หากแสดงการตั้งค่าของเซิร์ฟเวอร์ แสดงว่า socket ใช้งานได้ หากเกิดข้อผิดพลาดเรื่องสิทธิ์ แสดงว่าการเปลี่ยนกลุ่มยังไม่มีผลกับ shell ปัจจุบัน ซึ่ง newgrp incus-admin จะช่วยแก้ไขสำหรับ shell ปัจจุบัน และการล็อกอินใหม่จะแก้ไขได้อย่างสมบูรณ์ ให้ถือว่าการเป็นสมาชิกของ incus-admin มีสิทธิ์เทียบเท่า root บนโฮสต์ เพราะการเข้าถึง socket ดังกล่าวคือการควบคุม daemon ที่รันด้วยสิทธิ์ root อย่างเต็มรูปแบบ บาง distribution อาจสร้างกลุ่ม incus แยกต่างหากสำหรับการเข้าถึงของผู้ใช้แบบจำกัดสิทธิ์
ตอนนี้ให้เริ่มต้นการทำงานของ daemon
sudo incus admin initให้ตอบคำถามตามขั้นตอนแทนการใช้ incus admin init --minimal เส้นทางที่น้อยที่สุดคือการเลือก storage driver แบบ dir และหัวข้อถัดไปจะอธิบายว่าทำไมตัวเลือกนี้จึงส่งผลต่อการใช้งานของคุณในระยะยาว
ลองรันบริการสักอย่างเพื่อยืนยันว่าทำงานได้ปกติ
incus launch images:debian/13 web
incus list
incus exec web -- bashincus list ควรแสดง web ในสถานะ RUNNING พร้อมกับ IPv4 address บน subnet incusbr0 หากไม่มี address แสดงว่า DHCP (dynamic host configuration protocol) ทำงานไม่สำเร็จ ซึ่งหัวข้อเรื่องเครือข่ายจะอธิบายเรื่องนี้ไว้ หาก container เริ่มทำงานไม่ได้ ระบบจะแสดงสาเหตุใน incus info web --show-log และข้อผิดพลาดระดับ daemon จะถูกบันทึกไว้ใน sudo journalctl -u incus -n 50 บน VPS ที่คำสั่ง systemd-detect-virt แสดงผลเป็น lxc หรือ openvz การรันคำสั่งนี้จะเป็นการทดสอบที่ชัดเจนว่าคุณสามารถใช้งาน nesting ได้หรือไม่
เหตุผลที่ storage backend แบบเริ่มต้นมีความสำคัญ
Storage backend เป็นตัวกำหนดว่า snapshot จะทำงานได้ทันทีหรือต้องคัดลอกข้อมูลดิสก์ของ container ทั้งหมด นี่คือการตัดสินใจเพียงครั้งเดียวในขั้นตอนการติดตั้งที่คุณไม่สามารถเปลี่ยนแปลงในภายหลังได้โดยง่าย
Incus รองรับ dir, btrfs, lvm, zfs, Ceph และไดรเวอร์ระยะไกลอื่น ๆ อีกหลายตัว สำหรับ VPS ที่มีดิสก์ลูกเดียว ตัวเลือกที่แท้จริงคือระหว่าง dir และ btrfs
ไดรเวอร์ dir จะเก็บ container แต่ละตัวไว้เป็นไฟล์และไดเรกทอรีปกติภายใต้ /var/lib/incus ซึ่ง Incus ระบุไว้ในเอกสารว่าเป็นไดรเวอร์ที่ "ช้ากว่าไดรเวอร์อื่นทั้งหมดอย่างมาก" เนื่องจากต้องแตกไฟล์ image และคัดลอกข้อมูลจริงแทนที่จะใช้วิธีอ้างอิงบล็อกที่ใช้ร่วมกัน การทำ snapshot ของ container ขนาด 4 GiB จะต้องเขียนข้อมูล 4 GiB และใช้เวลานานเท่ากับที่ cp -a ใช้ Disk quota จะทำงานได้ก็ต่อเมื่อใช้ ext4 หรือ XFS ที่เปิดใช้งาน project quota ในระดับไฟล์ระบบเท่านั้น ซึ่งโดยปกติแล้ว image ของ VPS ส่วนใหญ่ไม่ได้เปิดใช้งานไว้ ดังนั้นการจำกัดขนาดดิสก์บน pool แบบ dir จึงมักไม่มีผลใด ๆ
btrfs และ zfs เป็นแบบ copy-on-write ดังนั้น snapshot จะบันทึกเฉพาะบล็อกที่มีการเปลี่ยนแปลงหลังจากนั้นเท่านั้น Incus จึงแนะนำให้ใช้ backend ทั้งสองตัวนี้ การทำ snapshot จึงทำได้เกือบจะทันที และ disk quota จะทำงานผ่านการรองรับ quota ของไฟล์ระบบเอง
แผนบริการ VPS ส่วนใหญ่ให้ดิสก์มาหนึ่งลูกโดยไม่มี partition สำรอง ดังนั้นให้วาง pool ไว้บน loop file ซึ่ง Incus จะจัดการส่วนนี้ให้คุณหากคุณไม่ได้ระบุ source=
sudo apt install -y btrfs-progs
incus storage create fast btrfs size=30GiB
incus profile device set default root pool=fast
incus launch images:debian/13 web2 -s fastหากไม่มี size= pool ที่ใช้ loop file จะกินพื้นที่ดิสก์ว่างไป 20% โดยมีค่าต่ำสุดที่ 5 GiB และสูงสุดที่ 30 GiB คุณควรตั้งค่านี้อย่างตั้งใจ Loop file เป็นไฟล์ที่อยู่บนไฟล์ระบบหลัก (root filesystem) ดังนั้น pool และ host จะใช้พื้นที่ว่างร่วมกัน ซึ่งหมายความว่าหาก pool เต็ม ดิสก์ของ host ก็จะเต็มไปด้วย
ZFS บน Debian และ Ubuntu เป็นโมดูลแบบ DKMS ไม่ใช่โมดูลที่รวมอยู่ใน kernel โดยตรง จึงต้องสร้างใหม่ทุกครั้งที่มีการอัปเกรด kernel และอาจล้มเหลวในการ build ได้หลังจากอัปเกรด สำหรับเซิร์ฟเวอร์ที่คุณไม่ได้ตรวจสอบทุกวัน btrfs จะเป็นตัวเลือกที่ต้องการการดูแลรักษาน้อยกว่าระหว่างสองตัวนี้
โหมดเครือข่ายทั้ง 3 รูปแบบ และสิ่งที่แต่ละโหมดเปิดเผยออกมา
incus admin init จะสร้าง managed bridge ที่ชื่อว่า incusbr0 และนำ instance ใหม่ทุกตัวไปไว้บนนั้น นี่เป็นหนึ่งในสามวิธีในการเชื่อมต่อคอนเทนเนอร์ ส่วนอีกสองวิธีที่เหลือมีไว้เพื่อแก้ปัญหาที่วิธีแรกซ่อนคอนเทนเนอร์ของคุณไว้หลัง NAT (network address translation)
Managed bridge. incusbr0 จะได้รับ private subnet โดยที่โฮสต์จะถือครองแอดเดรสแรกและทำหน้าที่เป็นเกตเวย์ ส่วน Incus จะรัน DHCP และ DNS (domain name system) บนนั้น และทราฟฟิกขาออกจะถูกส่งผ่าน public address ของโฮสต์โดยใช้ source NAT ไม่มีสิ่งใดจากภายนอกเข้าถึงคอนเทนเนอร์ได้จนกว่าคุณจะกำหนดค่าไว้ คุณสามารถส่งต่อพอร์ต (port forward) ได้ด้วย proxy device
incus config device add web http proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80 nat=truenat=true จะทำการส่งต่อด้วยกฎ netfilter แทนการทำ proxy ผ่านการเชื่อมต่อใน userspace แยกต่างหาก ดังนั้นแอดเดรสจริงของไคลเอนต์จะยังคงปรากฏอยู่ใน log ของคอนเทนเนอร์ Incus รองรับโหมดนี้เฉพาะในกรณีที่โฮสต์เป็นเกตเวย์ของ instance เท่านั้น ซึ่งก็คือกรณีของ incusbr0
macvlan. คอนเทนเนอร์จะได้รับ MAC (media access control) address ของตัวเองบนเครือข่ายกายภาพของโฮสต์ บนแพลตฟอร์ม VPS ส่วนใหญ่ วิธีนี้จะล้มเหลวเนื่องจากพอร์ตของ virtual switch ถูกผูกไว้กับ MAC address ของ VM ของคุณ ทำให้เฟรมจาก MAC อื่นถูกปฏิเสธ นอกจากนี้ยังมีข้อจำกัดอีกประการที่มักพบแม้ในกรณีที่ใช้งานได้ Incus ระบุไว้ว่า "อุปกรณ์ macvlan แม้จะสามารถสื่อสารระหว่างกันเองและกับภายนอกได้ แต่ไม่สามารถสื่อสารกับอุปกรณ์แม่ (parent device) ของตนเองได้ ซึ่งหมายความว่าคุณไม่สามารถใช้ macvlan ได้หากต้องการให้ instance สื่อสารกับโฮสต์โดยตรง"
Routed. นี่คือโหมดที่มักใช้งานได้บน VPS ที่มีแอดเดรสเพิ่มเติม Incus ระบุว่าอุปกรณ์นี้ "สร้างคู่ virtual device เพื่อเชื่อมต่อโฮสต์เข้ากับ instance และตั้งค่า static route รวมถึง proxy ARP/NDP entries เพื่อให้ instance เข้าร่วมเครือข่ายของ parent interface ที่กำหนดได้" ARP คือ address resolution protocol คอนเทนเนอร์จะยังคงใช้ public address โดยที่โฮสต์จะตอบรับ ARP แทน ทำให้ผู้ให้บริการยังคงเห็นเพียง MAC address ของโฮสต์เท่านั้น
incus config device add web eth0 nic nictype=routed parent=enp1s0 ipv4.address=203.0.113.20ให้ใช้ชื่อ parent interface จาก ip route show default อิมเมจปัจจุบันมักใช้ชื่ออย่าง enp1s0 หรือ ens3 และพบน้อยมากที่จะเป็น eth0 การตั้งชื่ออุปกรณ์เป็น eth0 จะเป็นการแทนที่ค่าที่โปรไฟล์ default กำหนดไว้ ทำให้คอนเทนเนอร์ไปอยู่บน routed interface แทนที่จะเป็น bridge ให้ตรวจสอบผลลัพธ์จากภายในคอนเทนเนอร์ด้วย ip a และ ip route
เหตุใดคอนเทนเนอร์จึงเข้าถึงบริการบนโฮสต์ได้
คอนเทนเนอร์บน incusbr0 มี network namespace เป็นของตนเอง แต่ไม่มีขอบเขต firewall กั้นระหว่างตัวมันกับโฮสต์ โดยโฮสต์จะทำหน้าที่เป็น gateway อยู่บน bridge นั้น ดังนั้นจากภายในคอนเทนเนอร์ โฮสต์จึงเป็นเพื่อนบ้านที่เข้าถึงได้โดยตรง และทุกบริการบนโฮสต์ที่ผูกไว้กับ 0.0.0.0 จะตอบสนองที่นั่น
คุณสามารถตรวจสอบได้ด้วยตนเอง โดยการดูรายการพอร์ตที่กำลังฟังอยู่บนโฮสต์
sudo ss -tlnpจากนั้น จากภายในคอนเทนเนอร์ ให้ลองเชื่อมต่อไปยัง gateway ที่ ip route รายงานไว้
ip route show default
nc -zv 10.0.0.1 6379หากฐานข้อมูล, metrics endpoint หรือแผงควบคุมผู้ดูแลระบบบนโฮสต์ถูกผูกไว้กับ 0.0.0.0 การตรวจสอบนั้นจะสำเร็จ โดยที่ firewall ของเครือข่ายผู้ให้บริการของคุณจะไม่เห็นแพ็กเก็ตดังกล่าวเลย เพราะแพ็กเก็ตนั้นไม่เคยออกจากเครื่อง นี่คือสาเหตุที่น่าประหลาดใจเบื้องหลังคำถามส่วนใหญ่ที่ว่า "มันเข้าถึงสิ่งนั้นได้อย่างไร": คอนเทนเนอร์ถูกแยกออกจากอินเทอร์เน็ตด้วย NAT แต่ไม่ได้ถูกแยกออกจากโฮสต์ด้วยสิ่งใดเลย
ให้ผูกบริการบนโฮสต์ไว้กับ 127.0.0.1 ทุกครั้งที่ทำได้ จากนั้นจึงค่อยกรอง bridge บนโฮสต์ สำหรับเครื่องที่ใช้ ufw นโยบาย default deny จะบล็อกการรับส่งข้อมูลจากคอนเทนเนอร์ไปยังโฮสต์อยู่แล้ว ซึ่งจะทำให้ Incus DNS และ DHCP ใช้งานไม่ได้ และวิธีแก้ไขที่เอกสารของ Incus แนะนำคือ sudo ufw allow in on incusbr0 ซึ่งคำสั่งเดียวนั้นจะเปิดพอร์ตทุกพอร์ตของโฮสต์ให้คอนเทนเนอร์ทุกตัวเข้าถึงได้ คุณควรอนุญาตเฉพาะสิ่งที่คอนเทนเนอร์จำเป็นต้องใช้จริงๆ เท่านั้น
sudo ufw allow in on incusbr0 to any port 53 proto udp
sudo ufw allow in on incusbr0 to any port 53 proto tcp
sudo ufw allow in on incusbr0 to any port 67 proto udp
sudo ufw route allow in on incusbr0
sudo ufw route allow out on incusbr0กฎ ufw route สองข้อนี้คือสิ่งที่อนุญาตให้ทราฟฟิกของ instance ผ่านโฮสต์ออกไปยังอินเทอร์เน็ตได้ หากไม่มีกฎเหล่านี้ นโยบาย routed ของ ufw จะดรอปแพ็กเก็ตที่ส่งต่อ (forwarded packets) ทำให้คอนเทนเนอร์ได้รับหมายเลข IP แต่ไม่สามารถติดต่อสื่อสารกับสิ่งใดได้เลย
Snapshots และ profiles
Snapshot คือสำเนาของ instance ณ จุดเวลาใดเวลาหนึ่งที่เก็บไว้ภายใน storage pool ของคุณ
incus snapshot create web pre-upgrade
incus info web
incus snapshot restore web pre-upgrade
incus snapshot delete web pre-upgradeincus info web ใช้สำหรับแสดงรายการ snapshot ทั้งหมดที่ instance นั้นถือครองอยู่ คุณสามารถตั้งตารางเวลาการทำ snapshot แยกตามราย instance ได้
incus config set web snapshots.schedule=@daily
incus config set web snapshots.expiry=4wSnapshot จะถูกเก็บไว้ใน pool เดียวกัน บนดิสก์ลูกเดียวกัน และบนเซิร์ฟเวอร์เครื่องเดียวกัน มันช่วยป้องกันคุณจากความผิดพลาดในการอัปเกรด แต่ไม่สามารถป้องกันคุณจากกรณีดิสก์เสียหรือการลบ instance ทิ้งได้ การสำรองข้อมูลที่แท้จริงคือ incus export ซึ่งไฟล์ข้อมูลจะต้องถูกย้ายออกจากเครื่องเซิร์ฟเวอร์นั้น
incus export web /root/web-backup.tar.gz
incus import /root/web-backup.tar.gzProfile คือชุดของ config keys และอุปกรณ์ที่ถูกตั้งชื่อไว้เพื่อนำไปปรับใช้กับ instance ต่างๆ ทุก instance จะได้รับ profile ชื่อ default เว้นแต่คุณจะกำหนดเป็นอย่างอื่น และ profile ดังกล่าวคือสิ่งที่จัดเตรียม root disk และ network interface ให้กับ instance นั้น การแก้ไข default จะส่งผลกระทบต่อทุก instance ที่ใช้งาน profile นี้ ซึ่งเป็นประโยชน์และเป็นวิธีที่ใช้ในการปลดการเชื่อมต่อเครือข่ายออกจาก container จำนวน 20 ตัวพร้อมกัน
incus profile create small
incus profile set small limits.memory=512MiB
incus profile set small limits.cpu=1
incus launch images:debian/13 api -p default -p smallProfile จะถูกนำไปปรับใช้ตามลำดับ ดังนั้นค่า key ที่ถูกกำหนดไว้ใน profile ลำดับสุดท้ายจะเป็นค่าที่มีผลใช้งานจริง คุณสามารถตรวจสอบค่าคอนฟิกูเรชันที่ instance ใช้งานอยู่จริงได้โดยใช้ incus config show api --expanded
การรัน Docker ภายใน Incus container
การรัน Docker ภายใน Incus system container จำเป็นต้องเปิดใช้งาน nesting เนื่องจาก Docker จะสร้าง namespace และ mount ของตนเองขึ้นมา ซึ่งโดยปกติแล้ว container จะไม่ได้รับอนุญาตให้ทำเช่นนั้น
incus config set web security.nesting=true
incus restart webเอกสารของ Incus ระบุว่า security.nesting คือ "การอนุญาตให้ทำ nesting ภายใน instance" โดยค่าเริ่มต้นสำหรับ container คือ false นอกจากนี้ยังมีอีกสองประเด็นที่ระบุไว้ใน FAQ ของ Incus คือ container ไม่สามารถโหลด kernel module ได้ ดังนั้น module ที่ Docker จำเป็นต้องใช้จะต้องถูกโหลดที่ฝั่ง host และระบุไว้ใน incus config set web linux.kernel_modules overlay,br_netfilter และการสร้างไฟล์ /.dockerenv ภายใน container จะช่วยให้ Docker ข้ามการตรวจสอบบางอย่างที่มักจะล้มเหลวในสภาพแวดล้อมแบบ nested
บน host ที่ใช้ Ubuntu 24.04 ข้อจำกัดเรื่อง unprivileged user namespace ของ AppArmor อาจขัดขวางการทำงานของ pivot_root ที่ runc เรียกใช้ ซึ่งจะทำให้ Docker ภายใน container แสดงข้อความ:
failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error jailing process inside rootfs: pivot_root .: permission deniedและใน dmesg ของ host จะแสดงบรรทัดที่มีข้อความ apparmor="DENIED" operation="pivotroot" class="mount" การตั้งค่าที่ผู้คนมักเลือกใช้คือ kernel.apparmor_restrict_unprivileged_userns แต่การปิดใช้งานนั้นไม่ใช่การแก้ไขที่เชื่อถือได้ โดยรายงานบั๊กของ Incus ที่เกี่ยวข้องกับกรณีนี้ระบุว่าการตั้งค่าเป็น 0 ไม่สามารถแก้ไขปัญหาได้ โปรดอ่าน dmesg เพื่อตรวจสอบการปฏิเสธการเข้าถึงก่อน เพื่อให้แน่ใจว่า AppArmor เป็นสาเหตุของปัญหาจริงก่อนที่จะเปลี่ยนค่าความปลอดภัยเริ่มต้น
หากคุณต้องการรัน container บน VPS โดยตรงเพื่อลดความซับซ้อนของเลเยอร์ การรัน Docker บน VPS จะอธิบายถึงการตั้งค่าดังกล่าวไว้โดยเฉพาะ
รูปแบบความล้มเหลวและข้อความที่คุณจะพบ
อินสแตนซ์สูญเสียการเชื่อมต่อเครือข่ายทั้งหมดหลังจากติดตั้ง Docker บนโฮสต์ เอกสารของ Incus ระบุสาเหตุไว้ว่า "Docker ตั้งค่า FORWARD policy ส่วนกลางเป็น drop ซึ่งขัดขวางไม่ให้ Incus ส่งต่อทราฟฟิก จึงทำให้อินสแตนซ์สูญเสียการเชื่อมต่อเครือข่าย" อินสแตนซ์ยังคงมีที่อยู่ IP แต่ไม่สามารถติดต่อปลายทางใดได้ ให้ตั้งค่า ip-forward-no-drop เป็น true ใน /etc/docker/daemon.json จากนั้นทำให้การส่งต่อข้อมูลคงอยู่ถาวรและอนุญาตให้ bridge ผ่าน chain ของ Docker ได้
echo "net.ipv4.conf.all.forwarding=1" | sudo tee /etc/sysctl.d/99-forwarding.conf
sudo systemctl restart systemd-sysctl
sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT
sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPTกฎ iptables เหล่านั้นจะไม่คงอยู่หลังจากการรีบูตด้วยตัวมันเอง คุณต้องทำให้มันคงอยู่ถาวร
คอนเทนเนอร์หยุดทำงานพร้อมข้อผิดพลาดเกี่ยวกับ cgroup FAQ ของ Incus ได้บันทึกปัญหานี้ไว้ ข้อความเกี่ยวกับ Failed to mount "/sys/fs/cgroup" มักหมายความว่าไคลเอ็นต์ VPN บนโฮสต์ได้ mount ตัวควบคุม net_cls cgroup v1 ทับ cgroup v2 ซึ่งเป็นสิ่งที่ Incus ใช้งานอยู่ การใช้ sudo umount /sys/fs/cgroup/net_cls จะช่วยแก้ไขปัญหานี้
อินสแตนซ์ไม่ได้รับที่อยู่ IPv4 incus list แสดงสถานะว่ากำลังทำงานอยู่แต่คอลัมน์ที่อยู่ว่างเปล่า การตอบกลับ DHCP จากโฮสต์ถูกทิ้ง ซึ่งมักเกิดจากไฟร์วอลล์ของโฮสต์ที่ไม่รู้จัก bridge ดังกล่าว หากใช้ ufw การใช้ sudo ufw allow in on incusbr0 to any port 67 proto udp จะช่วยกู้คืนการทำงานได้ ให้ตรวจสอบการมาถึงของคำขอด้วย sudo tcpdump -ni incusbr0 port 67
อินสแตนซ์ปฏิเสธที่จะเริ่มทำงานบน VPS แบบ nested โปรดอ่าน incus info <name> --show-log ก่อน แล้วตามด้วย sudo journalctl -u incus -n 50 หาก systemd-detect-virt แจ้งว่า lxc หรือ openvz แสดงว่าส่วนที่ขาดหายไปอยู่ที่ฝั่งผู้ให้บริการ และไม่มีการตั้งค่าใดภายใน VPS ของคุณที่จะเปลี่ยนแปลงสิ่งนี้ได้
Snapshot ทำงานช้าและดิสก์เต็มอยู่ตลอด คุณกำลังใช้งาน pool แบบ dir อยู่ คำสั่ง incus storage list จะแสดงไดรเวอร์สำหรับแต่ละ pool การย้ายไปยัง pool แบบ copy-on-write หมายถึงการสร้าง pool ใหม่ คัดลอกอินสแตนซ์เข้าไปด้วย incus copy web web-new -s fast จากนั้นจึงลบข้อมูลต้นฉบับทิ้งหลังจากที่คุณตรวจสอบแล้วว่าสำเนาสามารถเริ่มทำงานได้ตามปกติ
FAQ
Incus container เหมือนกับ Docker container หรือไม่?
ไม่เหมือนกัน Docker บรรจุเพียงกระบวนการเดียวหรือแอปพลิเคชันเดียว แต่ Incus system container จำลองระบบปฏิบัติการเต็มรูปแบบ ซึ่งมี init, ผู้ใช้, บริการ และตัวจัดการแพ็กเกจของตนเอง คุณต้องดูแลและแพตช์ Incus container เหมือนกับเซิร์ฟเวอร์ทั่วไป ในขณะที่ Docker container นั้นถูกออกแบบมาให้ลบทิ้งและสร้างใหม่จากอิมเมจ คุณสามารถรัน Docker ภายใน Incus container ได้โดยตั้งค่า security.nesting=true บน container นั้น แต่ไม่สามารถทำในทางกลับกันได้
ฉันสามารถรัน Incus บน VPS ได้หรือไม่?
หากเป็น KVM VPS สามารถทำได้ หาก systemd-detect-virt แสดงผลเป็น kvm หรือ qemu แสดงว่าคุณมี kernel ของตนเองและ Incus จะทำงานได้เหมือนบนฮาร์ดแวร์จริง แต่ถ้าแสดงผลเป็น lxc, lxc-libvirt หรือ openvz แสดงว่า VPS ของคุณเป็น container อยู่แล้ว ดังนั้น Incus container ที่อยู่ภายในจะเป็นการซ้อนทับ (nested) ซึ่งจะทำงานได้ก็ต่อเมื่อผู้ให้บริการเปิดใช้งานฟีเจอร์ nesting ไว้ให้คุณเท่านั้น นอกจากนี้ควรตรวจสอบ uname -r ด้วย เนื่องจาก ณ เดือนสิงหาคม 2026 สาขา stable ของ Incus ปัจจุบันระบุความต้องการ kernel ขั้นต่ำไว้ที่ 6.12 ในขณะที่สาขา 6.0 LTS ระบุไว้ที่ 5.4
ฉันควรเลือก storage backend ใดสำหรับ Incus บน VPS?
ควรเลือก btrfs บนไฟล์ loop เว้นแต่คุณจะมี block device สำรองไว้ใช้งาน ไดรเวอร์ dir มีเอกสารระบุว่าทำงานช้ากว่าตัวเลือกอื่นมาก เนื่องจากใช้วิธีคัดลอกไฟล์แทนการใช้ copy-on-write ทำให้ทุกการทำ snapshot จะต้องเขียนข้อมูล container ใหม่ทั้งหมด incus admin init --minimal จะเลือก dir ให้โดยอัตโนมัติ ซึ่งเป็นเหตุผลว่าทำไมการตอบคำถามในโหมด interactive จึงคุ้มค่ากับเวลาที่เสียไปเพียงสองนาที คุณสามารถสร้าง pool ได้ด้วยคำสั่ง incus storage create fast btrfs size=30GiB
ทำไม Incus container ของฉันถึงเข้าถึงบริการที่รันอยู่บนโฮสต์ได้?
เพราะ bridge แบบ incusbr0 ที่เป็นค่าเริ่มต้นจะวางโฮสต์ไว้ใน subnet เดียวกับ container ที่ตำแหน่ง gateway และไม่มีการกรองแพ็กเก็ตระหว่างกัน บริการใดๆ บนโฮสต์ที่ผูกไว้กับ 0.0.0.0 จะตอบรับคำขอเหล่านั้น และ firewall ของผู้ให้บริการจะไม่เห็นแพ็กเก็ตเหล่านี้เพราะมันไม่ได้ออกจากเครื่อง คุณควรผูกบริการบนโฮสต์ไว้กับ 127.0.0.1 และหากใช้ ufw บนโฮสต์ ให้ยอมรับเฉพาะ DNS และ DHCP บน incusbr0 แทนการเปิดกว้างด้วย sudo ufw allow in on incusbr0
ฉันจะสำรองข้อมูล Incus container ได้อย่างไร?
incus export web /root/web-backup.tar.gz จะเขียนข้อมูล instance และ snapshot ลงในไฟล์เดียว และ incus import จะใช้สำหรับกู้คืนข้อมูลบนเซิร์ฟเวอร์เดิมหรือเซิร์ฟเวอร์ใหม่ การทำ snapshot ด้วย incus snapshot create ไม่ถือเป็นการสำรองข้อมูล เพราะมันถูกเก็บอยู่ใน storage pool เดียวกันบนดิสก์ลูกเดียวกัน จึงช่วยป้องกันได้เพียงความผิดพลาดจากการอัปเกรด แต่ไม่สามารถป้องกันกรณีเซิร์ฟเวอร์เสียหายได้ คุณควรตั้งเวลาสำรองข้อมูลด้วย incus config set web snapshots.schedule=@daily และคัดลอกไฟล์ที่ export ออกไปเก็บไว้นอกเครื่องเสมอ