ติดตั้งและใช้งาน LXC/LXD บน VPS สร้าง Container แบบ Lightweight
LXC (Linux Containers) และ LXD (Linux Daemon) คือเทคโนโลยี container ระดับ OS ที่ให้ประสบการณ์คล้าย Virtual Machine แต่ใช้ resource น้อยกว่ามาก เหมาะสำหรับการรันหลาย environment แยกกันบน VPS เดียว เช่น dev/staging/production หรือแยก project แต่ละตัว LXD เป็น daemon ที่ห่อหุ้ม LXC อีกชั้นพร้อม REST API และ CLI ที่ใช้งานง่าย ต่างจาก Docker ที่เน้น microservice แบบ immutable, LXC/LXD ให้ full system container ที่มี init process, systemd และ full OS เหมือนกับการมี VPS เล็กๆ อยู่ภายใน VPS ของคุณ
LXD vs Docker — ใช้อะไรดี?
| ด้าน | LXD | Docker |
|---|---|---|
| แนวคิด | Full system container (เหมือน VM เบา) | Application container (1 process) |
| Init system | มี systemd เต็ม | ไม่มี (ต้องใช้ s6/supervisor) |
| SSH เข้าได้ | ใช่ (ssh หรือ lxc exec) | ต้องตั้งค่าเพิ่ม |
| Network | มี IP ของตัวเอง | bridge network / port mapping |
| เหมาะกับ | multi-service, legacy apps, dev env | microservice, CI/CD, packaging |
ติดตั้ง LXD บน Ubuntu VPS
LXD มาพร้อม Ubuntu 22.04/24.04 ผ่าน snap package:
# อัพเดท package list
sudo apt update && sudo apt upgrade -y
# ติดตั้ง LXD ผ่าน snap (เวอร์ชันล่าสุดแนะนำ)
sudo snap install lxd
# หรือติดตั้งเวอร์ชัน LTS
sudo snap install lxd --channel=5.21/stable
# ตรวจสอบเวอร์ชัน
lxd --version
lxc --version
snap install lxd --channel=5.21/stable สำหรับ production เพื่อความเสถียร ส่วน latest/stable จะ upgrade อัตโนมัติเมื่อมี version ใหม่
เพิ่ม User เข้า lxd group
# เพิ่ม user ปัจจุบันเข้า group lxd
sudo usermod -aG lxd $USER
# รีโหลด group โดยไม่ต้อง logout
newgrp lxd
# ตรวจสอบว่า user อยู่ใน group แล้ว
groups $USER
ตั้งค่า LXD ครั้งแรก (lxd init)
รันคำสั่ง lxd init เพื่อตั้งค่าเริ่มต้น — ใช้ค่า default ทั้งหมดก็เพียงพอสำหรับ VPS ทั่วไป:
# ตั้งค่าแบบ auto (ใช้ค่า default ทั้งหมด)
lxd init --auto
# หรือตั้งค่าแบบ interactive (แนะนำสำหรับ production)
lxd init
ถ้าเลือก interactive mode จะถามคำถามเหล่านี้:
Would you like to use LXD 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 (btrfs, dir, lvm, zfs, ceph) [default=zfs]: dir
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=lxdbr0]: lxdbr0
What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]: auto
Would you like the LXD 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 "lxd init" preseed to be printed? (yes/no) [default=no]: no
dir backend แทน zfs เพราะไม่ต้องใช้ partition แยก ส่วน zfs เหมาะกับ VPS ที่มี disk ว่างหลาย GB และต้องการ snapshot feature
สร้าง Container แรก
# ดู image ที่มีให้ใช้ (Ubuntu, Debian, Alpine, CentOS, Arch ฯลฯ)
lxc image list images: | grep -E "ubuntu|debian" | grep amd64 | head -10
# สร้าง container จาก Ubuntu 24.04
lxc launch ubuntu:24.04 mycontainer
# สร้าง container จาก Debian 12
lxc launch images:debian/12 mydebian
# ดูรายการ container ทั้งหมด
lxc list
# ดูสถานะ container
lxc info mycontainer
เข้าใช้งาน Container
# เข้า shell ใน container
lxc exec mycontainer -- bash
# รัน command เดียวใน container
lxc exec mycontainer -- apt update
# เข้าในฐานะ user เฉพาะ
lxc exec mycontainer -- su - ubuntu
# ดู logs ของ container
lxc console mycontainer --show-log
จัดการ Container — Start, Stop, Delete
# หยุด container
lxc stop mycontainer
# เริ่ม container
lxc start mycontainer
# รีสตาร์ท container
lxc restart mycontainer
# ลบ container (ต้อง stop ก่อน)
lxc stop mycontainer
lxc delete mycontainer
# ลบแบบ force (ไม่ต้อง stop ก่อน)
lxc delete mycontainer --force
ตั้งค่า Resource Limits (CPU/RAM)
จำกัด resource ของแต่ละ container เพื่อป้องกัน VPS host โดนกิน resource หมด:
# จำกัด RAM ไว้ที่ 512MB
lxc config set mycontainer limits.memory 512MB
# จำกัด CPU ไว้ที่ 1 core
lxc config set mycontainer limits.cpu 1
# ดูค่า config ที่ตั้งไว้
lxc config show mycontainer
# ตั้งค่าตอนสร้าง container (inline)
lxc launch ubuntu:24.04 webserver \
-c limits.memory=1GB \
-c limits.cpu=2
Port Forwarding — เข้าถึง Service จากภายนอก
แต่ละ container มี IP ภายใน (172.x.x.x) ต้องตั้ง port forwarding ให้ traffic ภายนอกเข้าถึงได้:
# ดู IP ของ container
lxc list
# Proxy port 80 ของ host → port 80 ของ container
lxc config device add mycontainer http proxy \
listen=tcp:0.0.0.0:80 \
connect=tcp:127.0.0.1:80
# Proxy port 443 ของ host → port 443 ของ container
lxc config device add mycontainer https proxy \
listen=tcp:0.0.0.0:443 \
connect=tcp:127.0.0.1:443
# ดู device ที่ attached
lxc config device list mycontainer
# ลบ proxy device
lxc config device remove mycontainer http
Snapshot — สำรองสถานะ Container
# สร้าง snapshot ก่อน upgrade/เปลี่ยนแปลงสำคัญ
lxc snapshot mycontainer snap0
# ดูรายการ snapshot
lxc info mycontainer | grep Snapshots -A 20
# Restore กลับไปยัง snapshot
lxc restore mycontainer snap0
# ลบ snapshot ที่ไม่ต้องการ
lxc delete mycontainer/snap0
Mount โฟลเดอร์จาก Host เข้า Container
# Mount /home/ubuntu/data จาก host เข้าไปใน /data ของ container
lxc config device add mycontainer datadir disk \
source=/home/ubuntu/data \
path=/data
# ตรวจสอบว่า mount ทำงาน
lxc exec mycontainer -- ls /data
# ลบ device
lxc config device remove mycontainer datadir
ตรวจสอบว่า LXD ทำงานถูกต้อง
# ตรวจสอบ service status ของ LXD
sudo systemctl status snap.lxd.daemon.service
# ดูรายการ container ทั้งหมดพร้อม IP
lxc list
# ตรวจสอบ network bridge ของ LXD
ip addr show lxdbr0
# ตรวจสอบ storage pool
lxc storage list
lxc storage info default
# ping จาก host ไปยัง container IP
lxc list
ping -c 3 10.x.x.x
lxc list แสดง state เป็น RUNNING แต่ไม่มี IP ให้ตรวจสอบว่า lxd-agent ทำงานอยู่ใน container ด้วย lxc exec <name> -- systemctl status lxd-agent
แก้ปัญหาที่พบบ่อย
Error: "dial unix /var/snap/lxd/common/lxd/unix.socket: connect: permission denied"
User ยังไม่ได้อยู่ใน group lxd หรือต้อง logout/login ใหม่หลังเพิ่ม group
# ตรวจสอบว่าอยู่ใน group lxd แล้วหรือยัง
groups $USER
# ถ้ายังไม่มี lxd — เพิ่มใหม่
sudo usermod -aG lxd $USER
# รีโหลด group โดยไม่ต้อง logout
newgrp lxd
Error: "Failed to create container: The container already exists"
มี container ชื่อเดิมอยู่แล้ว ต้องลบหรือเปลี่ยนชื่อก่อน
# ดูรายการ container ทั้งหมด
lxc list
# ลบ container เก่าก่อน
lxc delete oldcontainer --force
# หรือใช้ชื่อใหม่
lxc launch ubuntu:24.04 mycontainer2
Error: "Failed to pull image: context deadline exceeded"
Network timeout ขณะดาวน์โหลด image อาจเกิดจาก DNS หรือ firewall ของ VPS
# ทดสอบ DNS
nslookup cloud-images.ubuntu.com
# ลอง pull image ใหม่อีกครั้ง
lxc image copy ubuntu:24.04 local: --alias ubuntu-24
# ใช้ image cache ที่ download ไว้แล้ว
lxc image list
lxc launch local:ubuntu-24 mycontainer
Error: "Container has no valid IP address" หลัง launch
Network bridge lxdbr0 อาจมีปัญหา หรือ DHCP ใน container ไม่ทำงาน
# ตรวจสอบ bridge
ip link show lxdbr0
# รีสตาร์ท network ใน container
lxc exec mycontainer -- systemctl restart systemd-networkd
# รีสตาร์ท container
lxc restart mycontainer
# รีสตาร์ท LXD daemon
sudo systemctl restart snap.lxd.daemon.service
Error: "Failed to run: lxc" เมื่อตั้ง proxy device
Port ที่ต้องการ forward อาจถูกใช้งานอยู่แล้วบน host หรือ container ยัง stop อยู่
# ตรวจสอบว่า port ถูกใช้อยู่หรือไม่
sudo ss -tuln | grep :80
# ต้อง start container ก่อน แล้วค่อยเพิ่ม proxy
lxc start mycontainer
lxc config device add mycontainer http proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
คำถามที่พบบ่อย
LXD ต่างจาก Docker อย่างไร และควรเลือกใช้อะไร?
LXD เป็น system container ที่จำลอง full OS — มี systemd, init process, และ SSH เหมือน VM แต่เบากว่า เหมาะกับงานที่ต้องรัน multiple service ใน environment เดียว เช่น ทดสอบ legacy software หรือแยก project dev/production บน VPS เดียว ส่วน Docker เหมาะกับ application packaging, microservice และ CI/CD pipeline ที่ต้องการ immutable container ในทางปฏิบัติสามารถใช้ทั้งสองพร้อมกันได้ — LXD สำหรับ environment isolation, Docker ข้างในแต่ละ LXD container
LXD ใช้ทรัพยากรมากแค่ไหนเมื่อเทียบกับ VM?
LXD container ที่ idle ใช้ RAM น้อยมาก โดยทั่วไปประมาณ 20–50 MB ต่อ container เทียบกับ KVM VM ที่ต้องใช้ RAM ขั้นต่ำหลายร้อย MB เพราะแชร์ kernel กับ host ไม่ต้องโหลด OS แยก ดังนั้น VPS ขนาด 2GB RAM สามารถรัน LXD container ได้ 10–20 ตัวพร้อมกัน ขึ้นอยู่กับ service ที่รันใน container
สามารถรัน Docker ภายใน LXD container ได้ไหม?
ได้ แต่ต้องเปิดใช้ nested containers ก่อน ด้วยการ set security.nesting=true บน container ที่ต้องการ
# เปิด nested containers
lxc config set mycontainer security.nesting true
# รีสตาร์ท container
lxc restart mycontainer
# ติดตั้ง Docker ข้างใน
lxc exec mycontainer -- bash
# แล้วรัน: curl -fsSL https://get.docker.com | sh