ย้าย DA CentOS 7 → Debian 12 บน Proxmox ตอนที่ 1 — NAT pre-stage
server ตัวหลักของลูกค้ารันบน CentOS 7 มาเกือบสิบปี หมด EOL ไปกลางปี 2024 ผมดองไว้นานพอควรกว่าจะได้ลงมือ ตอนนี้ย้ายเสร็จแล้ว นิ่งดี ใช้งานจริงมาเกือบเดือน เลยมาเล่าวิธีที่ผมใช้
สรุปใน 1 นาที
- อาการ/ปัญหา
- ย้าย DirectAdmin จาก CentOS 7 ไป Debian 12 แล้วกลัว downtime นาน
- ใครควรอ่าน
- ผู้ดูแล shared host ที่วางแผนย้าย OS ของเครื่องที่มีลูกค้าใช้งานอยู่
- ทางแก้แบบสั้น
- สร้าง VM ใหม่บน internal bridge แบบ NAT เตรียมระบบให้เสร็จขณะที่ VM เก่ายังให้บริการ แล้วค่อยสลับเครื่องในจังหวะสั้นๆ
server ตัวหลักของลูกค้าผมรันบน CentOS 7 มาเกือบสิบปี หมด EOL ไปตั้งแต่กลางปี 2024 ดองมานานพอควรครับ มี user อยู่บนเครื่องนี้ 80 กว่าราย รอย้าย OS ใหม่กันทั้งนั้น งานเพิ่งเสร็จไปปลายเดือนที่แล้ว ตอนนี้นิ่งดี ใช้งานจริงมาเกือบเดือนยังไม่มีปัญหา
ซีรีส์นี้ผมจะเล่ากระบวนการย้ายทั้งหมดตั้งแต่ต้นจนจบ ตอนแรกขอเริ่มที่ขั้น NAT pre-stage ก่อน ซึ่งเป็นหัวใจของการลด downtime ครับ
แนวคิด: เตรียม VM ใหม่ก่อน โดยไม่ดับ VM เก่า
หลักการง่ายมากครับ แทนที่จะ shutdown VM เก่าก่อนแล้วค่อยมานั่ง build VM ใหม่ (ซึ่งจะทำให้ลูกค้าค้างเป็นชั่วโมงๆ) ผมเลือกสร้าง VM ใหม่ขึ้นมาบน internal bridge แยกต่างหาก อยู่ใน private subnet ที่ไม่ชนกับ public IP ของเครื่องเก่า
ระหว่างที่ผมเตรียม VM ใหม่อยู่นั้น VM เก่ายัง online ให้บริการลูกค้าตามปกติ ไม่รู้ตัวด้วยซ้ำว่ามีเครื่องใหม่กำลังถูกเตรียมอยู่ข้างๆ พอเตรียมระบบเสร็จเรียบร้อยจนใกล้ครบกระบวนการ ค่อยมา swap NIC ทีหลังในจังหวะสั้นๆ
บอกกันตรงๆ ก่อนเลยครับ — ตอนแรกผมตั้งใจว่าเทคนิคนี้จะทำให้ downtime ของลูกค้าเข้าใกล้ศูนย์ แต่พอลงมือจริงไปเจอกำแพงสองเรื่อง คือ DA Legacy license กับ qcow2 ที่อ่านช้า สุดท้ายเลยจบที่ downtime จริงประมาณ 1 ชั่วโมง รายละเอียดเดี๋ยวเล่าเต็มๆ ตอนท้าย ตรงนี้ขอลงรายละเอียดส่วน prep ก่อน
โครงสร้าง 2-bridge
โครงสร้างเครือข่ายที่ผมวางไว้คือใช้ bridge สองตัวบน Proxmox host ตัวหนึ่งเป็น public อีกตัวเป็น internal ที่มี NAT ออก
public bridge
- PVE host + VM เก่า ผูกอยู่ที่นี่
- ใช้ IP จริง 203.0.113.x
- ลูกค้าเข้าผ่านทางนี้ตามปกติ
internal bridge
- private 192.168.10.0/24
- NAT egress ออกทาง vmbr0
- VM ใหม่อยู่ที่นี่ เตรียมระบบ
จุดสำคัญคือ VM ใหม่ผูกอยู่กับ vmbr1 จึงไม่ชนกับ public IP ของ VM เก่าเลย ทำให้สองเครื่องทำงานคู่ขนานกันได้บน host เดียวกัน
ตั้งค่า network ฝั่ง PVE — /etc/network/interfaces
ผมกำหนด vmbr0 เป็น bridge ขา public ผูกกับ physical NIC ของ host ส่วน vmbr1 เป็น bridge ลอยๆ ไม่มี physical port แต่ทำหน้าที่เป็น gateway ของ private subnet พร้อม MASQUERADE ออก vmbr0
auto vmbr0
iface vmbr0 inet static
address 203.0.113.41/29
gateway 203.0.113.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
auto vmbr1
iface vmbr1 inet static
address 192.168.10.254/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o vmbr0 -j MASQUERADE
post-up iptables -A FORWARD -s 192.168.10.0/24 -j ACCEPT
post-up iptables -A FORWARD -d 192.168.10.0/24 -j ACCEPT
post-down iptables -t nat -D POSTROUTING -s 192.168.10.0/24 -o vmbr0 -j MASQUERADE
post-down iptables -D FORWARD -s 192.168.10.0/24 -j ACCEPT
post-down iptables -D FORWARD -d 192.168.10.0/24 -j ACCEPT
bridge-ports none ตรงนี้คือกุญแจสำคัญครับ มันบอกว่า vmbr1 ไม่ต้องผูกกับ NIC จริงตัวไหน เป็น bridge ภายใน host ล้วนๆ ส่วน rule MASQUERADE คือตัวที่ทำให้ทุก packet ที่ออกจาก 192.168.10.0/24 ถูกแปลงต้นทางเป็น IP ของ host แล้ววิ่งออก vmbr0 ได้ — VM ใหม่จึงต่อ internet ได้ตามปกติ ดึง package มาลงได้ แม้จะไม่มี public IP เป็นของตัวเอง
เสร็จแล้ว ifup vmbr1 ขึ้นมา แล้วตรวจว่า bridge ขึ้นจริงและ rule NAT ติด
ifup vmbr1
ip a show vmbr1
iptables -t nat -L POSTROUTING -n | grep MASQ
ถ้าเห็น address 192.168.10.254 บน vmbr1 และเห็นบรรทัด MASQUERADE ใน chain POSTROUTING ก็แปลว่าฝั่ง network พร้อมแล้ว
SSH access เข้า VM ใหม่ผ่าน PVE
ทีนี้ VM ใหม่อยู่ใน private subnet เราจะ ssh ตรงจากข้างนอกไม่ได้ ต้องทำ DNAT forward ผ่าน host เข้าไป ผมเลือกใช้ port หนึ่งบน host (สมมติเรียกว่า <fwd-port>) ชี้เข้า port 22 ของ VM ใหม่
iptables -t nat -A PREROUTING -p tcp --dport <fwd-port> -j DNAT --to 192.168.10.20:22
iptables -A FORWARD -p tcp -d 192.168.10.20 --dport 22 -j ACCEPT
netfilter-persistent save
netfilter-persistent save สำคัญครับ ไม่งั้น rule หายตอน reboot จากนั้นทดสอบจาก workstation
ssh -p <fwd-port> [email protected]
ถ้าทุกอย่างถูก เราจะทะลุผ่าน NAT forward เข้าไปถึง shell ของ VM ใหม่ในเครื่องเดียว ทั้งที่มันยังไม่มี IP จริงเป็นของตัวเอง
สร้าง VM ใหม่บน vmbr1
ขั้นถัดมาคือสร้างตัว VM ขึ้นมาผูกกับ vmbr1 ตรง ผมใช้ qm create กำหนด spec ตามที่ลูกค้าต้องการ
qm create 101 \
--name newserver \
--memory 60000 \
--cores 16 \
--machine q35 \
--bios seabios \
--scsihw virtio-scsi-single \
--net0 virtio,bridge=vmbr1 \
--scsi0 VMDATA:900,discard=on,ssd=1,iothread=1
ตรง --net0 ...,bridge=vmbr1 คือจุดที่ผูก VM ไว้กับ internal bridge ทำให้มันเกิดมาอยู่ใน private subnet เลย
ขั้นนี้มี gotcha อยู่ 4 อันที่ผมเคยโดนมาก่อน ขอเตือนไว้ให้ระวัง
1) อย่าใส่ viommu=on — installer จะตก kernel panic บน Debian 12 + q35 ผมเสียเวลาไป 2 ชั่วโมงกว่าจะรู้ว่าตัวนี้คือต้นเหตุ. 2) ใช้ q35 ไม่ใช่ i440fx — เป็น modern PCIe ให้ ZFS performance ดีกว่า. 3) NIC name บน Debian 12 + q35 + virtio จะเป็น enp6s18 ไม่ใช่ ens18 ของ Debian 13 ใครชินกับ ens18 มาก่อนจะหลงทาง. 4) virtio queues=8 ตั้งทีหลังเพื่อให้ใช้ทุก vCPU แบบ concurrent.
ส่วน virtio multiqueue ผมไปตั้งทีหลังด้วยคำสั่งนี้
qm set 101 --net0 virtio,bridge=vmbr1,queues=8
การตั้ง queues ให้เท่ากับจำนวน vCPU จะช่วยให้ traffic กระจายงานข้าม core ได้ ไม่ไปกองอยู่ core เดียวเวลามี throughput สูงๆ
ลง Debian 12 minimal
boot เข้า ISO แล้วเลือก install แบบ minimal เลยครับ ติ๊กเฉพาะ SSH server กับ standard system utilities พอ ไม่ต้องลง desktop หรือ service อะไรเกินจำเป็น เดี๋ยว CustomBuild จะมาวางของที่ต้องใช้เองทีหลัง
ส่วน partition ผมแบ่งประมาณนี้
/home ให้ใหญ่ที่สุดเพราะ data ของ user ทั้ง 80 กว่ารายจะไปกองอยู่ตรงนั้น
Quota mount option — จุดที่พลาดง่าย
ตรงนี้สำคัญมากสำหรับ DirectAdmin ที่ partition / และ /home ต้องใส่ mount option สำหรับ quota เข้าไปด้วย
usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0
ผมเลือก vfsv0 ทั้งที่ DA docs รุ่นใหม่แนะนำ vfsv1 เพราะ vfsv0 compat กับ quota file format ของ CentOS 7 เดิม ตอน restore quota ของลูกค้ามา ถ้าใช้ vfsv1 มันจะ restore ไม่ขึ้น ผมเสียเวลาลองรอบหนึ่งก่อนถึงยอมเปลี่ยนกลับมา vfsv0
ติดตั้ง base packages
หลัง install OS เสร็จ ผมลง package พื้นฐานที่ DA และ CustomBuild ต้องใช้ก่อน
apt update && apt install -y \
openssh-server curl wget quota iptables chrony \
perl python3 sudo rsync bzip2 \
netfilter-persistent
systemctl enable --now chrony
chronyc sources -v
เวลาบนเครื่องต้องตรง เพราะ DA license validation จะ check time ด้วย ผมเคยลืมตั้ง chrony มาก่อน ผลคือ license activate ไม่ผ่านเพราะ time skew มากเกินไป เสียเวลาไล่หาตั้งนาน กว่าจะรู้ว่าเป็นเรื่องนาฬิกา
ประโยชน์ที่ได้: prep ทั้งหมดทำได้โดยไม่กระทบลูกค้า
นี่คือคุณค่าจริงของ NAT pre-stage ครับ — ทุกขั้นตอนเตรียมระบบด้านล่างนี้ทำบน VM ใหม่ได้เลยขณะที่ลูกค้ายังใช้งานเครื่องเก่าอยู่
- Debian 12 install + base packages — ราว 30 นาที
- DA install + license activate — ราว 10 นาที (DA panel ตัวเก่าจะหลุดไปแค่ 1 นาที แต่ services ฝั่งลูกค้ายังทำงานปกติ)
- CustomBuild stack — ราว 2 ถึง 2.5 ชั่วโมง
- custom data prep (DNSSEC keys, hooks, templates) — ราว 30 นาที
- firewall config staging — ราว 10 นาที
- pre-cutover smoke test — ราว 30 นาที
รวมแล้วราว 3 ถึง 4 ชั่วโมงของงาน prep ทั้งหมด — ช่วงนี้ลูกค้าไม่กระทบเลยแม้แต่นิดเดียว เพราะทุกอย่างเกิดบนเครื่องคู่ขนานที่ซ่อนอยู่ใน private subnet
แต่ cutover เองยังต้องใช้เวลา ไม่ใช่ศูนย์
ตอนแรกผมหวังว่า downtime จะเข้าใกล้ศูนย์ แต่ของจริงไม่เป็นอย่างนั้น เพราะติดสองเรื่อง
DA Legacy license
- เป็นแบบ last DA wins
- รัน DA สองตัวพร้อมกันไม่ได้
- ต้อง stop DA เก่าก่อนถึงจะ activate ตัวใหม่ได้
qcow2 อ่านช้า
- DA backup ของเครื่องเก่าใช้เวลาเป็นชั่วโมง
- เป็น bottleneck หลักของ cutover
- ตรงนี้เป็นเหตุผลที่ ZFS เข้ามาช่วยในตอนถัดไป
สองเรื่องนี้รวมกันทำให้ downtime จริงของลูกค้าจบที่ประมาณ 1 ชั่วโมง ไม่ใช่ศูนย์อย่างที่ตั้งใจไว้ตอนแรก รายละเอียดของ cutover เต็มๆ ผมจะเล่าในตอนท้ายของซีรีส์ครับ
ตอนหน้า
ตอนหน้าจะต่อเรื่อง storage — ผมจะถอด mdadm เก่าออก แล้วสร้าง ZFS mirror ขึ้นมาแทน โดยทำขณะที่ VM เก่ายังรัน online ให้บริการลูกค้าอยู่พร้อมกันเลย
ใครจะปรับ subnet, port, หรือ spec ให้เข้ากับเครื่องตัวเองก็ตามสะดวกครับ หลักการเหมือนกันหมด — เตรียมเครื่องใหม่ให้พร้อมก่อน แล้วค่อย swap ทีหลัง เพื่อให้ลูกค้ากระทบน้อยที่สุด ไว้นึกอะไรออกเพิ่มหรือเจอจุดที่ควรแก้ ผมจะมาอัปเดตให้ครับ
อยากให้เราทำให้ไหม?
ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



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