ใช้ Claude อัป Proxmox 8 ขึ้น 9 แล้วสร้าง Windows VM ใหม่ทั้งคลัสเตอร์
เคสจริงที่ผมไม่ได้ ssh เข้าเครื่อง Proxmox เองเลยสักครั้ง สั่งผ่าน VS Code + Claude ล้วน ๆ ตั้งแต่อัป PVE 8 ขึ้น 9, รวม cluster, ทำ ZFS, ทำ Windows golden image ยัน clone เป็น VDI ทั้งคลัสเตอร์ บทความนี้คือคำสั่งกับสคริปต์ที่ Claude สร้างระหว่างทำงานจริง ถอดออกมาให้อ่านแล้วทำซ้ำได้
พอดีผมต้องอัป Proxmox ทั้ง cluster จาก 8 ขึ้น 9 แล้วล้างสร้าง Windows VM ใหม่ทั้งหมดสำหรับงาน VDI แต่สิ่งที่อยากบอกก่อนเลยคือ จริง ๆ แล้วทั้งหมดนี้ ผมไม่ได้ ssh เข้าไปที่เครื่อง Proxmox เองเลยสักครั้งเดียว ผมสั่งผ่าน VS Code + Claude ล้วน ๆ Claude เป็นคนเขียน script แล้วยิงเข้า node ให้ ผมแค่นั่งคุมทิศแล้วสั่งทีละขั้น
บทความนี้ผมเลยถอดคำสั่งกับสคริปต์ที่ Claude สร้างระหว่างทำงานจริงออกมาเรียงเป็นขั้น ๆ ใครจะอ่านเองก็ได้ หรือจะให้ AI อ่านบทความนี้แล้วเอาคำสั่งไปสั่งทำจริงบนเครื่องตัวเองก็ได้เหมือนกัน เพราะ flow มันซ้ำได้ ส่วนหลักการคุม Linux server ด้วย AI ให้ปลอดภัยไม่เผลอพังระบบ ผมเขียนแยกไว้แล้วที่ คุม Linux server ด้วย AI ผ่าน SSH ให้ปลอดภัย อันนี้เป็นเคสจริงเต็ม ๆ
สคริปต์ทุกตัวยกมาจากของจริงบน node ตัดเฉพาะรหัสผ่านออก (cluster อยู่วงภายในล้วน เลขเครื่องกับ IP เลยเก็บไว้ตามจริง) และผ่าน syntax check + dry-run ดู logic มาแล้วก่อนลง
Claude เก็บ script แต่ละตัวไว้ที่ /root/*.sh บน node แล้วยิงผ่าน plink/pscp ของ PuTTY ให้ ไม่พิมพ์ inline ยาว ๆ ผ่าน PowerShell ตรง ๆ เพราะ CRLF กับ quote มันพังประจำ — เขียนเป็นไฟล์ แล้ว pscp ขึ้นไป จากนั้น sed -i 's/\r//g' ก่อน bash เสมอ (SSH ใช้ port มาตรฐาน 22) ตรงนี้แหละที่ AI อ่านบทความแล้วทำตามได้เลย เพราะมันเป็นไฟล์ + ขั้นตอนตายตัว
1. โครงที่วางไว้ ก่อนเริ่ม
cluster ผมมี 3 node คือ po001 (172.22.22.51, zpool ss1t01), po002 (172.22.22.52, เป็น controller, zpool ss1t02) และ po003 (172.22.22.53, zpool ss500g03) ทั้งหมดอยู่วงภายใน (172.22.22.x เป็น private) web :8006 ปกติ
หัวใจคือตั้งชื่อให้เป็นระบบ จะได้ไม่งงตอน clone เยอะ ๆ กฎที่ผมยึด
- VMID = VLAN tag = slot ของเครื่องนั้น · clone ตั้งชื่อ
win-c<VMID>· master ตั้งwin-master-poXXX - master ต่อ node =
900<NN>(9001/9002/9003) · ZFS-template ต่อ node =950<NN>(9501/9502/9503) - mgmt IP เรียงตาม VMID =
10.77.<เลข node>.<VMID%100>· ตัว host เป็น.254 - net0 = bridge งานจริง (tag = VMID แยก VLAN ต่อเครื่อง) · net1 = bridge mgmt (RDP/SSH ไม่มี gateway)
รหัสผ่าน root กับ Windows ทั้งหมดในบทความแทนด้วย <ROOT-PW> / <PW> ส่วน IP/hostname เก็บไว้เพราะเป็นวงภายในเครื่อง local ใครเอาไปใช้จริงเปลี่ยนเป็นของตัวเองให้หมด
2. อัป PVE 8.4 -> 9 แบบ in-place (เก็บ VM ครบ)
PVE 8 ไป 9 จริง ๆ คือ Debian 12 (bookworm) ขึ้น 13 (trixie) ของใหญ่ ผมทำทีละ node แล้ว pilot ที่ node ที่ VM น้อยสุดก่อน (po003) พังก็เสียหายน้อย VM ไม่ต้องลบ แค่ปิดก่อน reboot
ตอนอัป NIC อาจถูก rename จน SSH เข้าไม่ได้ ต้องมี console/IPMI/จอจริงสำรองไว้ก่อนเริ่มเสมอ แล้วค่อย backup config + จดชื่อ NIC ปัจจุบันไว้เทียบ ไม่งั้นถ้า SSH หลุดคือต้องเดินไปหน้าเครื่องอย่างเดียว
# มี console สำรองก่อนเริ่ม (NIC อาจ rename = SSH เข้าไม่ได้)
cp -a /etc/network/interfaces /etc/pve /etc/ssh/sshd_config /etc/hostname /etc/hosts /root/bk-pre9/
ip -br link # จดชื่อ NIC ปัจจุบันไว้เทียบหลังอัป
pve8to9 --full # checklist read-only -> แก้ทุก FAIL/WARN ให้หมดก่อน
pvesm set local --delete maxfiles # FAIL จริงที่เจอ: storage มี maxfiles ต้องลบทิ้ง
qm shutdown <id> # ปิด VM ทุกตัวบน node ก่อน reboot
สคริปต์อัปจริงที่ผมใช้ สลับ repo เป็น trixie + no-subscription, ปิด enterprise repo (pve + ceph), แล้ว dist-upgrade แบบ non-interactive เก็บ config เดิมไว้ ไม่ให้มันถามทีละไฟล์
#!/bin/bash
# /root/repo-upgrade.sh
export DEBIAN_FRONTEND=noninteractive
export PATH=/usr/sbin:/usr/bin:/sbin:/bin:$PATH
# 1) ปิด enterprise repo (pve + ceph) -> Enabled: false
for f in /etc/apt/sources.list.d/*.sources; do
grep -qi 'enterprise.proxmox.com' "$f" 2>/dev/null || continue
grep -q '^Enabled:' "$f" && sed -i 's/^Enabled:.*/Enabled: false/' "$f" || echo 'Enabled: false' >> "$f"
done
# 2) เพิ่ม pve-no-subscription (trixie, deb822)
cat > /etc/apt/sources.list.d/pve-no-subscription.sources <<'EOF'
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
EOF
# 3) Debian repo เปลี่ยน bookworm -> trixie
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list.d/debian.sources
# 4) update + dist-upgrade (เก็บ config เดิม = confold/confdef)
apt-get update
apt-get -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef dist-upgrade
apt-get -y autoremove
หลัง dist-upgrade เสร็จ ก่อน reboot มีของห้ามลืม
update-grub # ไม่งั้น reboot กลับ kernel เก่า 6.8 (legacy GRUB ไม่ชี้ kernel ใหม่)
a2dismod php7.3 2>/dev/null; systemctl restart apache2 # php7.3.load ชี้ .so ที่หาย -> apache fail
systemctl reboot
# verify: pveversion=9.x · uname -r=7.0.x-pve · qm list ครบ · ip -br link (NIC ชื่อเดิม) · ssh ใช้ได้
update-grub ลืมไม่ได้ · ต้อง pvesm set <store> --delete maxfiles ก่อน · ถ้ามี apache ต้อง a2dismod php7.3 · [email protected] fail เป็น cosmetic หายเอง · ssh.exe ของ Windows ค้างกับ OpenSSH 10 ให้ใช้ git-bash ssh หรือ plink · host จะ ping ขึ้นก่อน sshd ราว 30-40 วิ รอ retry อย่าเพิ่งตกใจ
3. ล้าง VM เก่า ก่อนทำ master/fleet ใหม่
ก่อนวางของใหม่ผมล้าง VM เก่าออกให้เกลี้ยง มีสองสคริปต์ ตัวแรกล้างหมด ตัวที่สองล้างเฉพาะตัวที่เกินมา (เก็บ master + ตัวที่ใช้อยู่)
#!/bin/bash
# /root/delete-all.sh — stop+destroy ทุก VM + ลบ ISO เก่า (เก็บ virtio + win11 iot)
export PATH=/usr/sbin:/usr/bin:/sbin:/bin:$PATH
ids=$(qm list 2>/dev/null | awk 'NR>1{print $1}')
for id in $ids; do
qm stop "$id" --skiplock >/dev/null 2>&1
qm destroy "$id" --purge --skiplock >/dev/null 2>&1 # --purge = ลบ disk + ออกจาก config
done
cd /var/lib/vz/template/iso && for f in *.iso; do
case "$f" in virtio-win-latest.iso|win11-iot-ltsc-2024.iso) : ;; *) rm -f "$f";; esac
done
# /root/deletevms.sh — เก็บ VMID ต่ำสุดตาม KEEP, ลบตัวท้ายที่ stopped, ข้าม running + master 9xxx
NN=$((10#$(hostname|tail -c2)))
case $NN in 1) KEEP=7;; 2) KEEP=15;; 3) KEEP=15;; esac
base=$((NN*100))
for conf in /etc/pve/nodes/"$(hostname)"/qemu-server/*.conf; do
id=$(basename "$conf" .conf); case "$id" in ''|*[!0-9]*) continue;; esac
{ [ "$id" -ge $((base+1)) ] && [ "$id" -le $((base+99)) ]; } || continue # เว้น master 9xxx
if [ $((id-base)) -gt "$KEEP" ]; then
[ "$(qm status "$id"|awk '{print $2}')" = running ] && continue
qm destroy "$id" --purge
fi
done
4. รวมเป็น Cluster (pvecm)
3 node standalone รวมเป็น cluster เดียวชื่อ pocluster (corosync วิ่งบน 172.22.22.x) ทำที่ console หรือ SSH
# --- บน po001 (node แรก สร้าง cluster) ---
pvecm create pocluster
pvecm status # ดู Quorate + node แรก
# --- บน po002 แล้ว po003 (join เข้า cluster) ---
pvecm add 172.22.22.51 # ใส่ root pw ของ po001; ต้อง SSH ถึง .51 ได้ก่อน
pvecm status # ต้องเห็น 3 node, Quorate: Yes
ผลจริง Name: pocluster · Nodes: 3 · Quorate: Yes แล้ว /etc/pve/nodes/{po001,po002,po003} จะโผล่ทุกเครื่อง เพราะ config sync ผ่าน corosync ให้เอง
corosync ใช้วง 172.22.22.x ทำ cluster link ห้าม add ตอน node มี VMID ชนกัน — ที่นี่ผมแยก VMID range ตาม node (1xx/2xx/3xx) อยู่แล้วเลยไม่ชน หลังเป็น cluster แล้ว node ต่อ node มี SSH key ให้ ใช้ BatchMode ได้เลย
5. เพิ่ม ZFS storage ต่อ node
แปลง Samsung SSD (/dev/sda) เป็น zpool (ตั้งชื่อไม่ซ้ำต่อ node) แล้ว register เป็น PVE storage มี safety abort ถ้าเจอว่าไม่ใช่ดิสก์ Samsung กันแก้ผิดลูก
# /root/zfsconv.sh
NN=$((10#$(hostname|tail -c2)))
case $NN in 1) POOL=ss1t01;; 2) POOL=ss1t02;; 3) POOL=ss500g03;; esac
DEV=/dev/sda
case "$(lsblk -dno MODEL $DEV)" in *Samsung*) ;; *) echo ABORT; exit 1;; esac # กันผิดดิสก์
wipefs -a "${DEV}1" "$DEV"
zpool create -f -o ashift=12 -O compression=lz4 -O atime=off "$POOL" "$DEV"
pvesm add zfspool "$POOL" --pool "$POOL" --content images,rootdir --nodes "$(hostname)"
zpool list "$POOL"; pvesm status | grep "$POOL"
wipefs + zpool create ลบข้อมูลใน /dev/sda หมด รันแค่ครั้งเดียวตอน setup และต้องมั่นใจจริง ๆ ว่าเป็นดิสก์ว่างที่ตั้งใจ safety abort ด้านบน (เช็ครุ่น Samsung) ช่วยได้ระดับหนึ่งแต่ดูเองอีกชั้น
6. ทำ Windows Golden Image + Template
หัวใจของงาน VDI คือทำ "ภาพต้นแบบ" ตัวเดียวให้ดีก่อน แล้วค่อย clone ออกเป็นสิบ ๆ ตัว ขั้นตอนคือลง Windows สด -> generalize ด้วย sysprep -> หด disk -> ทำเป็น template
ลง Windows ให้เรียบร้อย (ลงโปรแกรม ปรับ setting) แล้ว generalize เพื่อให้ทุก clone ได้ SID / MachineGUID / ชื่อเครื่องใหม่ ไม่งั้น clone ออกมาชนกันเองในวง
# รันใน Windows master (cmd)
copy unattend.xml C:\Windows\System32\Sysprep\unattend.xml
C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown /unattend:C:\Windows\System32\Sysprep\unattend.xml
ตัว unattend.xml ที่ผมใช้ ข้าม OOBE, ตั้ง user admin / pass <PW> (ขั้น provision ค่อยเปลี่ยนทีหลัง), AutoLogon, ComputerName=* (สุ่มชื่อ), region ไทย, UI en-US
หลัง sysprep first boot Windows จะ reboot เอง (SSH หลุดตอน boot = ปกติ) ถ้าไป force shutdown เร็ว VM จะพังขึ้น "computer restarted unexpectedly" วนไม่จบ ต้องลงใหม่
หด disk เหลือ 32G ก่อนทำ template หัวใจคือ qemu-nbd + ntfsresize + parted clone master เป็น work-copy 9999 ก่อน ไม่แตะตัว master จริง มี safety abort ทุกจุดกันตัด disk ทับ data
# /root/shrink32.sh (แก่น)
case $((10#$(hostname|tail -c2))) in 1) SRC=9001;; 2) SRC=9002;; 3) SRC=9003;; esac
TMP=9999
qm destroy $TMP --purge --skiplock 2>/dev/null
qm clone $SRC $TMP --name new32g --full # work-copy เต็ม (ไม่แตะ master)
DISK=$(ls /var/lib/vz/images/$TMP/* | head -1)
modprobe nbd max_part=8
qemu-nbd -c /dev/nbd0 -f raw "$DISK"; sleep 2 # map disk เป็น block device
CNUM=$(lsblk -blno NAME,SIZE,FSTYPE /dev/nbd0 | awk '$3=="ntfs"{print $2,$1}' | sort -rn | head -1 | grep -oE '[0-9]+$')
echo y | ntfsresize -f -s 28G "/dev/nbd0p${CNUM}" # หด filesystem ก่อน
parted -s /dev/nbd0 resizepart "$CNUM" 30.5GB # แล้วค่อยหด partition
for pn in $(parted -sm /dev/nbd0 print | awk -F: 'NR>2{print $1}'); do
[ "$pn" -gt "$CNUM" ] && parted -s /dev/nbd0 rm "$pn" # ลบ recovery partition หลัง C:
done
qemu-nbd -d /dev/nbd0
qemu-img resize -f raw --shrink "$DISK" 32G # partition สุดท้ายต้องจบ < 32G ก่อน
qemu-img info "$DISK" | grep 'virtual size'
แปลงเป็น template ทั้ง local-dir และ ZFS
qm template 9002 # 900<NN> -> template (ต้นทางของ linked clone)
# ZFS-template: full copy ครั้งเดียว ไว้ clone ตัวที่จะอยู่บน ZFS
qm clone 9002 9502 --name ztmpl --full --storage ss1t02 && qm template 9502
7. Clone เป็น VDI fleet
พอมี template ก็ clone ออกเป็นเครื่องจำนวนมากได้ ผมใช้ linked clone เพราะเร็วและประหยัดเนื้อที่ (แชร์ base กับ template) แบ่งโควตาต่อ node ว่ากี่ตัวอยู่ local-dir กี่ตัวอยู่ ZFS แต่ละตัวได้ VMID = VLAN tag ของตัวเอง + ต่อ NIC mgmt
# /root/clonefleet.sh (แก่น)
NN=$((10#$(hostname|tail -c2)))
case $NN in
1) M=9001; LOCAL_N=9; ZFS_N=26;;
2) M=9002; LOCAL_N=21; ZFS_N=26;;
3) M=9003; LOCAL_N=21; ZFS_N=13;;
esac
ZTID=$((9500+NN)); BR=vmbrMGMT; base=$((NN*100))
TOTAL=$((LOCAL_N+ZFS_N))
for ((k=1;k<=TOTAL;k++)); do
id=$((base+k))
# k ตัวแรก = local-dir (linked จาก master) ; ที่เหลือ = ZFS (linked จาก ZFS-template)
if [ $k -le $LOCAL_N ]; then SRC=$M; else SRC=$ZTID; fi
qm clone $SRC $id --name win-c$id # linked clone (เร็ว+ประหยัด)
qm set $id -net0 "virtio,bridge=vmbrPROD,tag=$id" # VLAN ต่อเครื่อง (isolation)
qm set $id -net1 "virtio,bridge=$BR" # mgmt NIC (ไม่มี gateway)
done
linked จาก master 900X
- เร็ว ประหยัดเนื้อที่ (แชร์ base กับ master)
- อยู่ดิสก์ระบบของ node
- โควตาจำกัดตาม LOCAL_N
linked จาก ZFS-template 950X
- อยู่บน zpool แยก (ssXt0X)
- linked clone ข้าม storage ไม่ได้ ต้อง clone จาก template ที่อยู่บน ZFS
- ได้ compression lz4 + snapshot ของ ZFS
เพราะ master ผ่าน sysprep /generalize มาแล้ว (ข้อ 6) ทุก clone เลยได้ SID / MachineGUID / ชื่อเครื่องใหม่ของตัวเองตอน first boot นี่เป็นวิธีมาตรฐานของการ deploy Windows image ไม่ใช่การ spoof อะไร
8. Management network + pin IP
ผมให้ทุก clone มี NIC ใบที่สอง (net1) ต่อ bridge mgmt ที่ ไม่มี gateway เอาไว้ RDP/SSH เข้าไปดูแล แต่เนตงานยังออกทาง net0 ปกติ การไม่มี gateway บนวง mgmt ทำให้ traffic งานไม่หลุดออกผิดทาง
# /root/mgmtnet.sh — bridge ไม่มี uplink + DHCP ที่ไม่แจก gateway/DNS
NN=$((10#$(hostname|tail -c2))); BR=vmbrMGMT; SUB=10.77.$NN
grep -q "iface $BR " /etc/network/interfaces || cat >> /etc/network/interfaces <<EOF
auto $BR
iface $BR inet static
address $SUB.254/24
bridge-ports none
bridge-stp off
bridge-fd 0
EOF
ifup $BR
# option 3 + 6 ว่าง = ไม่มี default route/DNS -> เนตไม่ออกทางนี้
dnsmasq --interface=$BR --bind-interfaces \
--dhcp-range=$SUB.50,$SUB.250,255.255.255.0,10m \
--dhcp-option=3 --dhcp-option=6 \
--except-interface=lo --no-resolv --no-hosts \
--dhcp-leasefile=/run/dnsmasq-mgmt.leases --pid-file=/run/dnsmasq-mgmt.pid
จับ MAC ของ net1 map เป็น 10.77.NN.<VMID%100> (DHCP reservation) จะได้เดา IP จาก VMID ได้ + เช็ก IP ชน
# /root/repin.sh
NN=$((10#$(hostname|tail -c2))); SUB=10.77.$NN; HOSTS=/run/mgmt-hosts.conf; : > "$HOSTS"
for conf in /etc/pve/nodes/"$(hostname)"/qemu-server/*.conf; do
id=$(basename "$conf" .conf); case "$id" in ''|*[!0-9]*) continue;; esac
[ "$id" -ge 9000 ] && continue # เว้น master/template
grep -q '^name: win-c' "$conf" || continue
mac=$(grep -oP 'net1: virtio=\K[0-9A-Fa-f:]+' "$conf" | tr 'A-Z' 'a-z')
[ -n "$mac" ] && echo "$mac,$SUB.$((id-NN*100)) # VM$id" >> "$HOSTS"
done
pkill -f "dnsmasq.*vmbrMGMT"; sleep 1
dnsmasq --interface=vmbrMGMT --bind-interfaces --dhcp-range="$SUB.20,$SUB.250,255.255.255.0,10m" \
--dhcp-hostsfile="$HOSTS" --dhcp-option=3 --dhcp-option=6 --except-interface=lo \
--no-resolv --no-hosts --dhcp-leasefile=/run/dnsmasq-mgmt.leases --pid-file=/run/dnsmasq-mgmt.pid
awk -F, '{print $2}' "$HOSTS" | awk '{print $1}' | sort | uniq -d # โชว์ IP ชน (ควรว่าง)
ถ้า re-clone VM ตัวเดิม MAC จะเปลี่ยนใหม่ -> IP จริงต้องดูจาก lease ตาม MAC อย่าเดาเอาจาก VMID
9. Provision Windows ผ่าน SSH
ผมไม่ได้ลง qemu-guest-agent เลยคุม guest ผ่าน SSH ตรง ๆ (Windows OpenSSH default shell เป็น PowerShell ต้องห่อคำสั่งด้วย cmd /c "...")
- qm start เปิด VM
- รอ first-ping ~5 นาที อดทน first boot ของ Windows ใหม่ช้า
- เช็ก ping นิ่ง 30 วิ + ssh whoami ได้ ค่อยถือว่าพร้อม
- รัน provision ตั้งค่าทั้งหมดผ่าน SSH
- shutdown เฉพาะถ้าสำเร็จ ถ้า provision พลาดอย่าเพิ่งปิด จะได้เข้าไปดู
# SSH เข้า guest (user/<PW>) ครั้งแรก auto-accept cert, ห่อด้วย cmd /c
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null [email protected] \
'cmd /c "powercfg /change standby-timeout-ac 0 & netsh advfirewall firewall set rule group=\"remote desktop\" new enable=Yes"'
ตัว provision.bat ทำ ไม่ให้เครื่อง sleep, เปิด RDP + firewall, ตั้ง auto-login user/<PW>, ล้าง cache ตอน boot แล้ว shutdown · ผมปิด Windows Update ถาวรด้วยเพราะเป็นเครื่อง VDI ที่ไม่อยากให้รีบูตเองกลางงาน อันนี้แล้วแต่คนชอบ
(1) shutdown เร็วระหว่าง sysprep specialize = VM พัง ปล่อยให้ reboot เอง · (2) รันทีละ 1 VM ต่อ node เท่านั้น หลายตัวพร้อมกัน RAM เต็ม · (3) sshpass/plink ต้องครบทั้ง 3 node · (4) งานยาว/remote อย่ารันสดค้าง connection ให้วาง script รัน background แล้วค่อยอ่าน log
10. ลำดับรันทั้งหมด
1. repo-upgrade.sh -> reboot -> update-grub (ทีละ node: po003 -> po002 -> po001)
2. pvecm create/add -> cluster pocluster (3 node quorate)
3. zfsconv.sh -> ZFS pool + storage ต่อ node
4. [Windows master] -> sysprep -> shrink32.sh -> qm template (900X) + ZFS-template (950X)
5. delete-all.sh / deletevms.sh -> ล้าง VM เก่า
6. mgmtnet.sh -> vmbrMGMT (gateway-less DHCP)
7. clonefleet.sh -> clone VDI fleet (local + ZFS, tag = VMID)
8. repin.sh -> mgmt IP เรียงตาม VMID
9. provisionall.sh -> provision Windows ทีละตัว
ย้ำอีกที ทั้งหมดนี้ Claude เป็นคนลงมือยิงให้ผ่าน VS Code ผมไม่ได้แตะ shell ของ Proxmox เองเลยสักครั้ง คำสั่งทุกตัวในบทความคือของจริงที่มันสร้างระหว่างทำงาน ใครจะอ่านเอาไปทำเองก็ได้ หรือจะวางบทความนี้ให้ AI อ่านแล้วสั่งทำตามทีละขั้นก็ได้เหมือนกัน ปรับจำนวนตัว ชื่อ pool หรือช่วง VMID เป็นแบบของตัวเองได้ตามสะดวก หลักการเหมือนกันหมด ตรงไหนผมอธิบายตกหล่นหรือพิมพ์ผิด เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
อยากให้เราทำให้ไหม?
ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



ความคิดเห็น 0
ยังไม่มีความคิดเห็น — เป็นคนแรกเลย