LXC คืออะไรต่างจาก Docker ยังไง
ผมใช้ LXC มาตั้งแต่ปี 2013 ก่อนที่ Docker จะมาแรงและจนถึงวันนี้ผมยังใช้ LXC อยู่สำหรับหลายๆงานเพราะมันตอบโจทย์ที่ Docker ทำไม่ได้หรือทำได้ไม่ดีคำถามที่ผมถูกถามบ่อยที่สุดคือ "LXC ต่างจาก Docker ยังไง" คำตอบสั้นๆคือ LXC เป็น System Container ที่รัน OS เต็มรูปแบบ (init system, services, processes หลายตัว) เหมือน VM แต่ไม่มี overhead ของ hypervisor ส่วน Docker เป็น Application Container ที่รัน process เดียวออกแบบมาสำหรับ microservices
ให้ลองคิดแบบนี้ถ้าคุณต้องการรัน Nginx + PHP-FPM + Cron + Syslog ทั้งหมดใน container เดียว LXC ทำได้เลยเพราะมี systemd จัดการทุก service ส่วน Docker จะแนะนำให้แยก container ต่อ process ซึ่งก็ดีสำหรับ microservices แต่ถ้าคุณต้องการ container ที่ทำตัวเหมือน server จริงๆ LXC เหมาะกว่ามาก
LXC vs LXD vs Incus — สรุปให้ชัด
LXC คือ low-level container runtime ที่ใช้ Linux kernel features (namespaces, cgroups) ใช้ command line tools เช่น lxc-create, lxc-start LXD คือ system container manager ที่สร้างทับ LXC อีกชั้นมี REST API, CLI ที่ใช้ง่ายกว่า, Clustering, Storage pools พัฒนาโดย Canonical Incus คือ fork ของ LXD โดย Linux Containers community หลังจาก Canonical เปลี่ยน license ของ LXD ในปี 2023 สำหรับปี 2026 ผมแนะนำใช้ Incus เพราะเป็น community-driven และได้รับการ support จากหลาย distro
ติดตั้ง Incus
# Ubuntu 24.04+ มี Incus ใน official repo
apt install incus
# หรือติดตั้งจาก Zabbly repo (แนะนำ เพราะ version ใหม่กว่า)
curl -fsSL https://pkgs.zabbly.com/key.asc | gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg
cat > /etc/apt/sources.list.d/zabbly-incus-stable.list << 'EOF'
deb [signed-by=/etc/apt/keyrings/zabbly.gpg] https://pkgs.zabbly.com/incus/stable $(lsb_release -cs) main
EOF
apt update && apt install incus
# เพิ่ม user เข้ากลุ่ม incus-admin
usermod -aG incus-admin $USER
newgrp incus-admin
# Initialize
incus admin init
# คำถามสำคัญ:
# - Storage backend: zfs (แนะนำ) หรือ dir (ง่ายสุด)
# - Network: สร้าง bridge ใหม่ (incusbr0)
# - Cluster: no (สำหรับ single node)
ตัวอย่าง incus admin init
$ incus admin init
Would you like to use clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (dir, zfs) [default=zfs]: zfs
Create a new ZFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing empty block device? (yes/no) [default=no]: no
Size in GiB of the new loop device (1GiB minimum) [default=30GiB]: 100
Would you like to connect to a MAAS server? (yes/no) [default=no]: no
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
What should the new bridge be called? [default=incusbr0]: incusbr0
What IPv4 address should be used? (CIDR subnet notation) [default=auto]: 10.10.100.1/24
What IPv6 address should be used? [default=auto]: none
Would you like the server to be available over the network? (yes/no) [default=no]: no
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: yes
Would you like a YAML "init" preseed to be printed? (yes/no) [default=no]: yes
สร้าง Container แรก
# ดู images ที่มี
incus image list images: | grep ubuntu
incus image list images: | grep debian
incus image list images: | grep rocky
# สร้าง container Ubuntu 24.04
incus launch images:ubuntu/24.04 web-server
# สร้าง container Debian 12
incus launch images:debian/12 db-server
# สร้าง VM แทน container (ใช้ QEMU)
incus launch images:ubuntu/24.04 my-vm --vm
# ดู containers ทั้งหมด
incus list
# +------------+---------+----------------------+------+-----------+
# | NAME | STATE | IPV4 | TYPE | SNAPSHOTS |
# +------------+---------+----------------------+------+-----------+
# | web-server | RUNNING | 10.10.100.101 (eth0) | CT | 0 |
# | db-server | RUNNING | 10.10.100.102 (eth0) | CT | 0 |
# +------------+---------+----------------------+------+-----------+
จัดการ Container
# เข้า shell ของ container
incus exec web-server -- bash
# รัน command ใน container
incus exec web-server -- apt update
incus exec web-server -- apt install nginx -y
incus exec web-server -- systemctl status nginx
# หยุด / เริ่ม / restart
incus stop web-server
incus start web-server
incus restart web-server
# ดู info
incus info web-server
# Push file เข้า container
incus file push /local/path/config.conf web-server/etc/nginx/conf.d/
# Pull file ออกจาก container
incus file pull web-server/var/log/nginx/access.log ./
# ลบ container
incus delete web-server --force
Cloud-Init สำหรับ Automated Setup
# สร้าง container พร้อม cloud-init config
cat > cloud-init.yml << 'EOF'
#cloud-config
packages:
- nginx
- php-fpm
- certbot
runcmd:
- systemctl enable --now nginx
- systemctl enable --now php8.3-fpm
write_files:
- path: /var/www/html/index.html
content: |
EOF
incus launch images:ubuntu/24.04 web-auto --config=user.user-data="$(cat cloud-init.yml)"
Default Bridge Network
เมื่อ init Incus จะสร้าง bridge network (incusbr0) ที่ทำหน้าที่เป็น NAT gateway สำหรับ containers ทุก container จะได้ IP จาก DHCP ของ bridge นี้และเข้าถึง internet ได้ผ่าน NAT
Macvlan — ให้ Container ได้ IP จาก Physical Network
# สร้าง macvlan profile
incus network create macvlan-net --type=macvlan parent=eth0
# สร้าง profile ที่ใช้ macvlan
incus profile create macvlan-profile
incus profile device add macvlan-profile eth0 nic nictype=macvlan parent=eth0
# สร้าง container ด้วย macvlan profile
incus launch images:ubuntu/24.04 exposed-server --profile default --profile macvlan-profile
# Container จะได้ IP จาก DHCP ของ physical network
# เข้าถึงได้จากภายนอกโดยตรง
Port Forwarding
# Forward port 80 จาก host ไปยัง container
incus config device add web-server http proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
# Forward port 443
incus config device add web-server https proxy listen=tcp:0.0.0.0:443 connect=tcp:127.0.0.1:443
# ดู devices ทั้งหมด
incus config device list web-server
# ลบ port forwarding
incus config device remove web-server http
Storage Pools และ Volumes
Incus รองรับ storage backends หลายแบบ ZFS เป็นตัวที่ผมแนะนำมากที่สุดเพราะมี snapshot, compression และ deduplication ในตัวสำหรับรายละเอียดเกี่ยวกับ ZFS ดูบทความ ZFS Storage Linux ของผม
จัดการ Storage Pools
# ดู storage pools
incus storage list
incus storage info default
# สร้าง storage pool ใหม่ (ZFS)
incus storage create fast-pool zfs source=/dev/nvme0n1
# สร้าง storage pool แบบ directory (ง่ายสุด)
incus storage create simple-pool dir source=/mnt/containers
Custom Volumes
# สร้าง volume สำหรับ data
incus storage volume create default web-data
# Attach volume เข้า container
incus storage volume attach default web-data web-server /var/www/html
# ดู volumes
incus storage volume list default
# Detach volume
incus storage volume detach default web-data web-server
# ย้าย volume ไป pool อื่น
incus storage volume copy default/web-data fast-pool/web-data
Snapshots
# สร้าง snapshot
incus snapshot create web-server before-upgrade
# ดู snapshots
incus info web-server | grep -A5 Snapshots
# Restore snapshot
incus snapshot restore web-server before-upgrade
# ลบ snapshot
incus snapshot delete web-server before-upgrade
# Scheduled snapshots
incus config set web-server snapshots.schedule "0 2 * * *"
incus config set web-server snapshots.expiry 7d
incus config set web-server snapshots.pattern "auto-%d"
Backup และ Migration
# Export container เป็น tarball
incus export web-server /backup/web-server-20260228.tar.gz
# Import container
incus import /backup/web-server-20260228.tar.gz web-server-restored
# Copy container ไปยัง remote server
# ต้อง setup remote ก่อน
incus remote add production https://10.10.10.20:8443
incus copy web-server production:web-server
# Move container (ย้ายทั้งตัว)
incus move web-server production:web-server
# Live migration (ย้ายโดยไม่ downtime)
incus move web-server production:web-server --stateful
จำกัด CPU, Memory, Disk
# จำกัด CPU
incus config set web-server limits.cpu 2 # 2 cores
incus config set web-server limits.cpu.allowance 50% # 50% of assigned CPUs
# จำกัด Memory
incus config set web-server limits.memory 2GB
incus config set web-server limits.memory.swap false
# จำกัด Disk I/O
incus config set web-server limits.disk.priority 5 # 0-10, 10 = highest
# จำกัด Network
incus config device set web-server eth0 limits.ingress 100Mbit
incus config device set web-server eth0 limits.egress 50Mbit
Profiles — Template สำหรับ Container
# สร้าง profile สำหรับ web server
incus profile create web-profile
incus profile set web-profile limits.cpu 2
incus profile set web-profile limits.memory 2GB
incus profile device add web-profile root disk pool=default path=/ size=20GB
incus profile set web-profile user.user-data - << 'EOF'
#cloud-config
packages: [nginx, php-fpm, certbot]
runcmd:
- systemctl enable --now nginx
EOF
# สร้าง container ด้วย profile
incus launch images:ubuntu/24.04 web1 --profile web-profile
incus launch images:ubuntu/24.04 web2 --profile web-profile
incus launch images:ubuntu/24.04 web3 --profile web-profile
# ดู profile
incus profile show web-profile
LXC บน Proxmox VE
ถ้าใช้ Proxmox VE อยู่แล้วสามารถสร้าง LXC containers ผ่าน Proxmox UI ได้เลยโดยไม่ต้องติดตั้ง Incus แยก Proxmox ใช้ LXC เป็น backend ของ container feature และมี template images ให้ download ได้จาก Proxmox repository
LXC container กับ Docker container ใช้พร้อมกันได้ไหม?
ได้ครับผมรัน Docker ข้างใน LXC container เป็นประจำต้องตั้งค่า security.nesting=true ให้ container และอาจต้อง security.syscalls.intercept.mknod=true สำหรับบาง workload วิธีนี้เหมาะสำหรับแยก Docker environments ออกจากกันเช่น dev container กับ staging container ต่างคนต่างมี Docker daemon ของตัวเอง
# เปิด nesting สำหรับรัน Docker ใน LXC
incus config set my-container security.nesting true
incus config set my-container security.syscalls.intercept.mknod true
incus config set my-container security.syscalls.intercept.setxattr true
incus restart my-container
LXC ปลอดภัยแค่ไหนเทียบกับ VM?
LXC containers แชร์ kernel กับ host ดังนั้น isolation ไม่ดีเท่า VM ที่มี hypervisor แยก kernel อย่างไรก็ตาม Incus ใช้ unprivileged containers เป็น default ซึ่งปลอดภัยพอสมควร processes ใน container รันด้วย UID ที่ map ไปยังช่วง UID ที่ไม่มีสิทธิ์บน host สำหรับ workload ที่ต้องการ security สูงสุดใช้ VM (Incus รองรับ VM ด้วย) หรือใช้ LXC ร่วมกับ AppArmor/SELinux profiles
LXC container กิน resource เยอะแค่ไหน?
น้อยมากครับเพราะไม่มี hypervisor overhead LXC container ที่รัน Ubuntu 24.04 กิน RAM แค่ 30-50 MB (เทียบกับ VM ที่กิน 200-500 MB) Boot เร็วมาก 1-2 วินาที (VM ใช้ 30-60 วินาที) disk footprint ก็น้อยกว่าเพราะใช้ shared base image ทำให้รัน containers จำนวนมากบน hardware เดียวได้
ควรใช้ LXC หรือ Docker สำหรับ production?
ขึ้นอยู่กับ use case ครับถ้าต้องการรัน microservices ที่แต่ละ service เป็น process เดียวใช้ Docker ถ้าต้องการ container ที่ทำตัวเหมือน server เต็มรูปแบบ (รัน multiple services, systemd, cron) ใช้ LXC ผมใช้ทั้งคู่ LXC สำหรับ development environments และ legacy applications ที่ต้องการ init system ส่วน Docker สำหรับ modern microservices
สรุป
LXC/Incus เป็น system container technology ที่ทรงพลังมากให้ isolation แบบ VM แต่ performance แบบ bare metal ไม่มี overhead จาก hypervisor เหมาะสำหรับ development environments, multi-tenant hosting, legacy application migration และงานที่ต้องการ full OS environment ใน container
สำหรับปี 2026 ผมแนะนำให้ใช้ Incus แทน LXD เพราะเป็น community-driven ไม่ผูกกับ vendor เดียวและได้รับ updates บ่อยกว่าถ้าใช้ Proxmox VE อยู่แล้วก็ใช้ LXC containers ผ่าน Proxmox ได้เลยไม่ต้องติดตั้งอะไรเพิ่มครับ
อ่านเพิ่มเติม: สอนเทรด Forex | XM Signal | IT Hardware | อาชีพ IT