- VPS ของ DigitalOcean ที่ใช้ Ubuntu 16.04 LTS มีปัญหาเรื่องหมดระยะซัพพอร์ตและภาระด้านความปลอดภัย แต่ก็ยังคง uptime ได้ถึง 1491 วันก่อนปลดระวาง
- เซิร์ฟเวอร์ใหม่ย้ายไปใช้ Hetzner VPS ในเยอรมนีพร้อม FreeBSD 14.3 และได้สเปกแรงกว่าเซิร์ฟเวอร์เดิมราคา $13/เดือน โดยจ่ายไม่ถึง 6 ยูโรต่อเดือน
- ใช้ Jails และ Bastille เพื่อสร้างสภาพแวดล้อมแยกตามแต่ละเว็บไซต์ โดย Caddy Jail รับหน้าที่ SSL และ reverse proxy ก่อนส่งต่อไปยังแต่ละ nginx Jail
- ในการทดสอบโหลด เซิร์ฟเวอร์ FreeBSD ใหม่มี throughput สูงกว่า 3 ถึง 11 เท่า หลังปรับ
kern.ipc.somaxconn เพื่อรองรับการเชื่อมต่อพร้อมกัน 10,000 รายการ
- การย้ายระบบต้องเรียนรู้เรื่อง เครือข่าย และการตั้งค่า FreeBSD แต่ด้วยการตั้งค่าแบบรวมศูนย์และเอกสารที่มีคุณภาพ ทำให้ตั้งระบบได้ง่ายกว่าที่คาด
ที่มาของการย้ายระบบ
- บล็อกเดิมรันอยู่บน DigitalOcean VPS มานานกว่า 10 ปี และใช้ Ubuntu 16.04 LTS ในดาต้าเซ็นเตอร์นิวยอร์ก
- Ubuntu 16.04 LTS หมดการซัพพอร์ตมาตั้งแต่อย่างน้อย 5 ปีก่อน และไม่สามารถรับอัปเดตจากคลังแพ็กเกจ
apt ได้อีก
- ระบบเก่ามีความเสียเปรียบด้านความปลอดภัย และก่อนหน้านี้บล็อก WordPress อีกตัวหนึ่งเคยถูกโจมตีแทรกลิงก์คาสิโนและการพนันบน VPS เก่า
- นอกจากบล็อกแล้ว เซิร์ฟเวอร์เดิมยังให้บริการอีกหลายเว็บไซต์ แต่ส่วนใหญ่เป็น เว็บไซต์แบบ static
- แม้แต่บล็อกที่ได้รับความนิยมมากที่สุดก็ปกติอยู่ที่ระดับไม่กี่พัน pageview ต่อเดือน และแทบไม่มีทราฟฟิกสูงมาก ยกเว้นบางบทความที่ไวรัลบน Hacker News
- เซิร์ฟเวอร์ให้บริการไฟล์ static ด้วย
nginx/1.10.3 และตั้งค่าแยกตามเว็บไซต์ไว้ใน /etc/nginx/sites-available
- บล็อกสร้างด้วย Hugo และขั้นตอน deploy เดิมคือ เขียนบนเครื่อง local → commit และ push ไปยัง repository → SSH เข้าเซิร์ฟเวอร์ → pull repository → รัน
hugo
- เดิมที VPS เครื่องนี้ยังถูกใช้สำหรับการทดสอบและเขียนโปรแกรม จึงมีซอฟต์แวร์เก่าหลงเหลืออยู่มาก
- ถึงอย่างนั้นมันก็ยังทำงานได้ปกติ และตอนปลดระวางมี uptime 1491 วัน หรือราว 4 ปีโดยไม่ต้องรีบูต
- เซิร์ฟเวอร์ใหม่ย้ายไปใช้ Hetzner VPS ในเยอรมนี ซึ่งสเปกดีกว่าเดิมแต่ค่าใช้จ่ายต่อเดือนต่ำกว่าครึ่ง
- เซิร์ฟเวอร์เดิมของ DigitalOcean มี RAM 2GB, vCPU 1 ตัว, ดิสก์ 50GB, ทราฟฟิกต่อเดือน 2TB และราคา $13/เดือน
- เซิร์ฟเวอร์ที่ถูกที่สุดของ Hetzner ก็ยังมีหน่วยความจำและ CPU เป็นสองเท่าของเดิม พื้นที่เก็บข้อมูลน้อยลงเล็กน้อย แต่ทราฟฟิกมากกว่า 10 เท่า
- สเปก Hetzner ที่เลือกใช้สุดท้ายแรงกว่าเดิมในราคาไม่ถึง 6 ยูโรต่อเดือน
เหตุผลที่เลือก FreeBSD
- เลือก FreeBSD เพราะต้องการลองใช้ระบบใหม่ในสภาพแวดล้อม production จริง
- ข้อดีที่ถูกยกมาคือการออกแบบแบบบูรณาการ ความเสถียร ความปลอดภัย และ Jails
- Jails คือความสามารถด้าน virtualization/containerization ที่มีอยู่ใน FreeBSD มานานกว่า 25 ปี
- สามารถรัน “มินิซิสเต็ม” ในลักษณะ sandbox ที่ไม่สามารถเข้าถึง host system ได้
- ขณะที่โซลูชันคอนเทนเนอร์อย่าง Docker เหมาะกับการแพ็กโปรแกรมและมีลักษณะชั่วคราวหรือ immutable มากกว่า แต่ Jails ถูกใช้งานใกล้เคียงกับ subsystem หรือ mini VM ที่แชร์ kernel เดียวกัน
- ZFS ก็เป็นตัวเลือกที่น่าสนใจสำหรับไฟล์ซิสเต็มฝั่งเซิร์ฟเวอร์
- มีทั้งความสามารถด้าน data integrity และ snapshot และมีบางส่วนคล้าย Btrfs ฝั่ง Linux
- ZFS ถูกมองว่าสุกงอมกว่า Btrfs มาก และหากทำ snapshot บ่อย ๆ ก็อาจพึ่งพาระบบ snapshot/backup แบบเสียเงินของผู้ให้บริการ VPS น้อยลงได้
- โครงสร้างเป้าหมายคือให้แต่ละเว็บไซต์มี Jail ของตัวเอง และในแต่ละ Jail มีทั้งเครื่องมือ build ที่จำเป็นและ nginx
- Jail สำหรับเมนเว็บเซิร์ฟเวอร์จะรับบทเป็น reverse proxy ที่เชื่อมต่อกับภายนอก
- หาก Jail ใดถูกเจาะ ก็ออกแบบให้สามารถลบแล้วสร้างใหม่ได้
การติดตั้ง FreeBSD และการนำ Bastille มาใช้
- หน้าสร้าง VM ของ Hetzner มีอิมเมจระบบปฏิบัติการพื้นฐานให้เลือกค่อนข้างจำกัด จึงไม่เห็น BSD โดยตรง
- เลือกใช้ Bastille เพื่อให้การจัดการ Jails ทำได้ง่ายขึ้น
- หลายขั้นตอนที่ต้องทำเองในการสร้าง Jail สามารถจัดการผ่านคำสั่ง
bastille ได้
- ตัวอย่างคำสั่งคือ
bastille list, bastille create, bastille console
- การติดตั้งและเปิดใช้งานทำตาม เอกสารเริ่มต้นของ Bastille
pkg install bastille
sysrc bastille_enable="YES"
เครือข่ายและโครงสร้าง reverse proxy
- สแตกทั้งหมดใช้ Caddy Jail ตัวเดียวจัดการทุกโดเมนและใบรับรอง SSL แล้ว reverse proxy ทราฟฟิกไปยัง Jail ของแต่ละเว็บไซต์
- Jail ของแต่ละเว็บไซต์มีเฉพาะเครื่องมือที่จำเป็นต่อการ build และให้บริการไซต์นั้น
- โครงสร้างนี้มองได้คล้ายกับการมีหลาย virtual machine อยู่ในเครือข่ายเดียวกัน
- สร้าง virtual network interface ภายในชื่อ
bastille0
sudo sysrc cloned_interfaces+="lo1"
sudo sysrc ifconfig_lo1_name="bastille0"
sudo service netif cloneup
sudo sysrc ifconfig_bastille0="inet 10.0.0.1 netmask 255.255.255.0"
- เป็นการ clone loopback interface ตั้งชื่อเป็น
bastille0 และกำหนดเครือข่าย 10.0.0.1/24
- Jail ต่าง ๆ จะทำงานอยู่บน network interface นี้
- คำขอ HTTP/HTTPS จากภายนอกจะถูกส่งต่อไปยัง Caddy Jail ผ่านกฎของ PF(Packet Filter)
- ใน
/etc/pf.conf มีการตั้งค่า external interface vtnet0, internal interface bastille0 และ tailscale1
- ทราฟฟิกพอร์ต
80, 443 จะถูก redirect ไปยัง 10.0.0.5 ซึ่งเป็น Caddy server
ext_if = "vtnet0"
int_if = "bastille0"
vpn_if = "tailscale1"
set skip on $int_if
set skip on $vpn_if
nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)
rdr pass on $ext_if proto tcp from any to any port {80, 443} -> 10.0.0.5
block all
pass out quick on $ext_if keep state
- เปิดใช้งาน PF และ gateway ด้วยคำสั่งต่อไปนี้
sysrc pf_enable="YES"
service pf start
sysrc gateway_enable="YES"
การตั้งค่า Caddy และ Jail รายเว็บไซต์
- เดิมทีเซิร์ฟเวอร์เก่าใช้ nginx มานาน แต่ในโครงสร้างใหม่เลือก Caddy เพื่อให้การจัดการใบรับรอง SSL เป็นอัตโนมัติ
- ในสภาพแวดล้อม nginx เดิมต้องต่ออายุใบรับรองด้วย
certbot เป็นระยะ และเคยลืมต่ออายุหลายครั้ง
- ก่อนสร้าง Caddy Jail ต้อง bootstrap FreeBSD release ให้ Bastille ก่อน
bastille bootstrap 14.3-RELEASE
- สร้าง Caddy Jail ด้วย IP
10.0.0.5
bastille create caddy 14.3-RELEASE 10.0.0.5 bastille0
bastille start caddy
- ชื่อ Jail คือ
caddy, release คือ 14.3-RELEASE, interface คือ bastille0
- สามารถใช้
bastille list เพื่อตรวจสอบสถานะ และใช้ bastille console caddy เพื่อเข้าเชลล์ภายใน Jail
- ติดตั้ง Caddy และเปิดใช้บริการจากภายใน Jail
pkg install caddy
sysrc caddy_enable="YES"
service caddy start
- ไฟล์ตั้งค่า Caddy อยู่ที่
/usr/local/etc/caddy/Caddyfile ภายใน Jail
- หากต้องการจัดการไฟล์ตั้งค่าจากฝั่ง host สามารถ mount ไดเรกทอรีของ host เข้าไปใน Jail ได้
- ในตัวอย่างใช้
nullfs พร้อมตัวเลือกอ่านอย่างเดียว ro เพื่อไม่ให้ Caddy แก้ไขไฟล์ตั้งค่า
bastille mount caddy /usr/local/etc/my-caddy-config /usr/local/etc/caddy nullfs ro 0 0
การ deploy เว็บไซต์และบล็อก
- เว็บไซต์แรกที่ deploy คือ
es.cro.to และจัดการ repository ของเว็บไซต์ผ่าน GitHub repository
- เก็บ repository ไว้ที่
/usr/local/www/escroto บน host และ mount ไดเรกทอรีนี้เข้าไปใน site Jail แบบอ่านอย่างเดียว
- ทุกเว็บไซต์ถูกจัดระเบียบให้อยู่ใต้
/usr/local/www บน host
- สร้าง Jail ชื่อ
escroto ด้วย nginx Bastille template
bastille bootstrap https://github.com/bastillebsd/templates
bastille create escroto 14.3-RELEASE 10.0.0.11 bastille0
bastille template escroto www/nginx
- กำหนด IP เป็น
10.0.0.11
- หน้าเริ่มต้นของ nginx อยู่ที่
/usr/local/www/nginx ตามธรรมเนียมของ FreeBSD
- mount ไดเรกทอรีเว็บไซต์จาก host เข้าไปใน Jail แบบอ่านอย่างเดียว
bastille mount escroto /usr/local/www/escroto /usr/local/www/escroto nullfs ro 0 0
- ใช้สคริปต์ deploy เพื่อป้องกันไม่ให้ไดเรกทอรี
.git ของ repository ถูกเสิร์ฟผ่านเว็บ
rm -fr /usr/local/www/nginx/*
cp -R /usr/local/www/escroto/* /usr/local/www/nginx/
rm -fr /usr/local/www/nginx/.git
- การ deploy เวอร์ชันใหม่ทำโดยอัปเดต repository บน host แล้วรันสคริปต์ deploy ภายใน Jail
cd /usr/local/www/escroto
git pull
bastille cmd escroto /root/deploy.sh
- การตั้งค่า Caddy จะ redirect
cro.to ไปยัง es.cro.to แบบถาวร และ proxy es.cro.to ไปยัง 10.0.0.11
cro.to {
redir https://es.cro.to{uri} permanent
}
es.cro.to {
reverse_proxy 10.0.0.11
}
- บล็อกใช้ Hugo และจัดการผ่าน GitHub repository
- clone repository ไว้ที่
/usr/local/www/blog บน host
- สร้าง
blog Jail ในลักษณะคล้าย escroto และกำหนด IP เป็น 10.0.0.12
bastille create blog 14.3-RELEASE 10.0.0.12 bastille0
bastille template blog www/nginx
bastille mount blog /usr/local/www/blog /usr/local/www/blog nullfs ro 0 0
- ติดตั้ง Hugo ภายใน
blog Jail
bastille pkg blog update
bastille pkg blog install gohugo
- สคริปต์ deploy ของบล็อกจะล้าง nginx web root แล้วสร้างผลลัพธ์ของ Hugo ไปที่
/usr/local/www/nginx
rm -fr /usr/local/www/nginx/*
cd /usr/local/www/blog
hugo -d /usr/local/www/nginx
- ก่อนย้าย DNS ใช้
crocidb.cro.to ชี้ไปยังเซิร์ฟเวอร์บล็อกใหม่เพื่อทดสอบแทนโดเมนเดิม
crocidb.cro.to {
reverse_proxy 10.0.0.12
}
เบนช์มาร์กและการทดสอบโหลด
- ก่อนเปลี่ยน DNS record ได้เปรียบเทียบความสามารถในการรับโหลดระหว่างเซิร์ฟเวอร์เดิม
crocidb.com กับเซิร์ฟเวอร์ใหม่ crocidb.cro.to
- ผู้เข้าชมบล็อกส่วนใหญ่มาจากอเมริกาเหนือ รองลงมาคือยุโรปและอเมริกาใต้ ดังนั้น latency ไปยังเซิร์ฟเวอร์ใหม่ในเยอรมนีอาจเพิ่มขึ้นเล็กน้อยสำหรับผู้ใช้บางส่วน
- ประเด็นหลักที่สนใจคือความเร็วในการให้บริการเว็บไซต์ static และความสามารถในการทนโหลดสูง
- มีการใช้เครื่องมือออนไลน์ฟรีอย่าง GTMetrix, Pingdom, WebPageTest ด้วย แต่ความต่างของสองเซิร์ฟเวอร์ส่วนใหญ่เห็นชัดแค่ในเรื่อง latency
- ใช้ wrk และ hey เป็นเครื่องมือเบนช์มาร์กโหลด HTTP
- ทั้งสองตัวสามารถสร้างคำขอพร้อมกันจำนวนมาก และเก็บข้อมูลอย่าง latency, error response และ throughput ต่อวินาที
- เมื่อรัน
wrk จาก VPS อีกเครื่องใน Hetzner เดียวกัน เซิร์ฟเวอร์ใหม่ทำผลงานเหนือกว่าอย่างชัดเจน
wrk -t4 -c100 -d30s --latency https://crocidb.com/
- ตัวเลือกคือ 4 threads, การเชื่อมต่อพร้อมกัน 100 รายการ และรัน 30 วินาที
- เซิร์ฟเวอร์เดิมมี average latency
89.63ms, requests per second 833.41, throughput 8.29MB/s
- เซิร์ฟเวอร์ใหม่มี average latency
6.75ms, requests per second 12260.10, throughput 130.80MB/s
- เครื่องที่ใช้ทดสอบอยู่ในดาต้าเซ็นเตอร์เดียวกับเซิร์ฟเวอร์ใหม่ จึงไม่ใช่การเปรียบเทียบที่ยุติธรรมนัก
- ยังลองรัน
wrk ผ่าน Proton VPN จากหลายภูมิภาค แต่ผลลัพธ์ต่ำกว่าที่คาด
- ค่าเฉลี่ยของเซิร์ฟเวอร์เดิมอยู่ที่ประมาณ
300 requests/s ส่วนเซิร์ฟเวอร์ใหม่อยู่ที่ประมาณ 800 requests/s
- สุดท้ายจึงเปลี่ยนจากการใช้ VPN สำหรับผู้ใช้ทั่วไป ไปเป็นการสร้าง VPS จริงในหลายภูมิภาคแทน
การทดสอบตามภูมิภาคด้วย Vultr VPS
- เลือก Vultr เพื่อให้ใช้อินฟราสตรักเจอร์ต่างจาก DigitalOcean และ Hetzner ที่เป็นที่ตั้งของเซิร์ฟเวอร์
- เนื่องจากภาระในการทำงานแบบ manual จึงจำกัดภูมิภาคไว้ 4 แห่งคือ London, São Paulo, Silicon Valley, Tokyo
- สร้าง Fedora VM รุ่นที่ถูกที่สุดในแต่ละภูมิภาคแล้วใช้รันทดสอบ
- สุดท้ายตัดสินใจว่า
hey เหมาะกับการทดสอบมากกว่า
./hey_linux_amd64 -n 1000000 -c 10000 -t 10 -z 5m -h2 https://crocidb.com/ > crocidb.com.log
./hey_linux_amd64 -n 1000000 -c 10000 -t 10 -z 5m -h2 https://crocidb.cro.to/ > crocidb.cro.to.log
- การตั้งค่าคือคำขอรวม
1,000,000 ครั้ง, concurrency 10,000, timeout 10 วินาที, เวลารวม 5 นาที และใช้ HTTP/2
- เป็นโหลดที่สูงกว่าทราฟฟิกบล็อกจริงมาก
- ในการรันครั้งแรก เซิร์ฟเวอร์ FreeBSD ใหม่รับ การเชื่อมต่อพร้อมกัน 10,000 รายการ ไม่ไหวและล้มเหลวตั้งแต่ช่วงต้น
- เมื่อตรวจสอบขนาด socket queue ด้วย
netstat -Lan พบว่าทั้งหมดเป็น 128
- ค่าเริ่มต้น
kern.ipc.somaxconn คือ 128 จึงเพิ่มเป็นดังนี้
sysctl kern.ipc.somaxconn=16384
- ในการทดสอบจาก São Paulo ทั้งสองเซิร์ฟเวอร์ตอบกลับด้วย error จำนวนมาก แต่เซิร์ฟเวอร์ FreeBSD รับมือกับ
1,000,000 requests ตามที่ตั้งใจไว้ได้ ขณะที่เซิร์ฟเวอร์ Ubuntu เดิมยังตอบกลับไม่ถึง 20,000 requests
- เซิร์ฟเวอร์ Ubuntu เดิมทำสำเร็จเพียงประมาณ
7% ของคำขอทั้งหมด
- เซิร์ฟเวอร์ FreeBSD ใหม่ทำสำเร็จประมาณ
94%
- ที่ Tokyo อัตราความสำเร็จของเซิร์ฟเวอร์ใหม่ลดลงเล็กน้อย แต่ยังไม่ถึงขั้นน่ากังวลมาก
- เมื่อวัดด้วย requests per second เซิร์ฟเวอร์ใหม่ดีกว่าเดิมอย่างน้อย 3 เท่า และมากสุด 11 เท่า
- ในส่วน latency percentile เซิร์ฟเวอร์ใหม่เพิ่มขึ้นค่อนข้างเป็นเส้นตรงจนถึงราวจุด
90% ทำให้คาดการณ์พฤติกรรมได้มากกว่า
- แม้อยู่ภายใต้โหลดสูง ผู้ใช้ส่วนใหญ่ทั่วโลกก็ยังสามารถรับเนื้อหาหน้าแรกของบล็อกได้ในเวลา ต่ำกว่า 3.5 วินาที
- ผลลัพธ์จาก Tokyo ไม่ได้ถูกวิเคราะห์เชิงลึก
- การวิเคราะห์ตามช่วงของคำขอใน
hey ชี้ว่าทราฟฟิกไปญี่ปุ่นอาจช้ากว่า
- ค่า DNS dial-up/lookup ของโดเมนที่สองดูต่ำผิดปกติ และอาจมีผลจาก CNAME record
- ค่า
resp wait และ resp read ก็สูงผิดปกติเช่นกัน แต่เนื่องจากนับเฉพาะคำขอที่สำเร็จ จึงอาจเป็นไปได้ว่าเซิร์ฟเวอร์เดิมตอบสนองเร็วในช่วงแรก แล้วแทบจะกันคำขอใหม่ออกไปในช่วงหลัง
การสลับใช้งานจริงและบทเรียนสำคัญ
- แม้เบนช์มาร์กจะยังตอบได้ไม่ครบทุกประเด็น แต่ผลลัพธ์ก็เป็นที่น่าพอใจพอที่จะสลับ DNS record ไปยังเซิร์ฟเวอร์ใหม่
- จากนั้นบล็อกนี้จึงให้บริการอย่างเป็นทางการบนเซิร์ฟเวอร์ Hetzner ที่ใช้ FreeBSD
- การตั้งเครื่องโฮสต์เว็บไซต์บน FreeBSD ต้องผ่านการทดลอง แก้ไข build และล้มเหลวอยู่หลายชั่วโมง แต่ไม่ได้ซับซ้อนอย่างที่คิด
- หากต้องการก็สามารถเลือกใช้บริการเว็บโฮสติ้งที่ตรงตามเงื่อนไขได้ เช่น OpenBSD Amsterdam
- หรือจะใช้ Proxmox เพื่อจัดการคอนเทนเนอร์และแดชบอร์ดบริหารก็ได้
- ฝั่งทางเลือกของ FreeBSD ยังมี Sylve ถูกกล่าวถึงด้วย
- อย่างไรก็ดี การประกอบระบบเองให้ประสบการณ์เรียนรู้มาก จึงถือว่าเป็นทางเลือกที่น่าพอใจ
- เซิร์ฟเวอร์ Ubuntu เดิม ก็แข็งแกร่งมากเช่นกัน
- ตลอด 10 ปีมันรับภาระโหลดของเว็บไซต์ได้ดี และใน 4 ปีสุดท้ายก็ทำงานต่อเนื่องโดยไม่ต้องรีบูต
- ทำงานได้เสถียรโดยแทบไม่ต้องลงแรงกับการตั้งค่ามากนัก
- การตั้งค่า FreeBSD ง่ายกว่าที่คาด โดยเฉพาะแนวทางรวมศูนย์การตั้งค่าระบบไว้ในที่เดียวและคุณภาพของเอกสารออนไลน์
- หากต้องการประกอบเครื่องโฮสต์บล็อกด้วยตัวเอง จำเป็นต้องมี ความรู้ด้านเครือข่าย ที่ไกลเกินกว่าขอบเขตที่นักพัฒนาเกมมักคุ้นเคย
- กระบวนการเรียนรู้ระบบอื่นเป็นเรื่องสนุก และครั้งหน้าอาจลอง OpenBSD หรือ NetBSD ก็ได้
- อย่างไรก็ดี ผู้เขียนสรุปว่าประโยชน์ใช้สอยของงานทั้งหมดนี้มีขีดจำกัด เพราะทราฟฟิกของบล็อกส่วนใหญ่มาจากการ crawl ของระบบ AI
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ความผิดพลาดที่ใหญ่ที่สุดที่ฉันเคยทำคือ uptime ที่สูง
เพราะ arjie.com รันอยู่บน Hetzner VPS มานานกว่า 10 ปี ตอนที่ Hetzner จะปิดเครื่องโฮสต์พื้นฐานนั้น ฉันก็ไม่รู้เลยว่าตัวเองตอนเป็นวัยรุ่นตั้งค่าอะไรเอาไว้บ้าง
มีแบ็กอัปอยู่ แต่เว็บดับมา 10 ปีแล้ว
ทุกวันนี้เลยทำทุกอย่างให้ย้ายได้ และย้ายจริงหลายครั้งเพื่อเช็กว่ามันใช้ได้
ยังจำยุคที่คนมอง uptime ของเครื่องเหมือนเหรียญเกียรติยศได้อยู่เลย
ฉันแก่ขึ้นแต่ไม่ได้ฉลาดขึ้นเท่าไร แค่เดี๋ยวนี้ดู uptime ของบริการ แทน
เมื่อก่อน DNS record อย่าง MX ก็มีจุดประสงค์ใกล้เคียงกัน และคลัสเตอร์ยุคเก่า ๆ ก็ซับซ้อนพอตัว แต่ก็ทิ้งบทเรียนอย่าง split brain ไว้ จนถึงทุกวันนี้ยังต้องอธิบายอยู่เรื่อย ๆ ว่าทำไมคลัสเตอร์ Proxmox แบบ 2 โหนดถึงพัง และทำไมถึงแนะนำให้เพิ่ม witness
ที่ VMware เคยเอาปัญหาของคลัสเตอร์ HA 2 โหนดไปกลบด้วยวิธีเฉพาะหน้าก้อนใหญ่ก็ผิดตั้งแต่แรก และถ้าวิธีนั้นยังอยู่ก็น่าจะยังผิดอยู่
uptime สูงแปลว่าไม่ได้แพตช์ และการแพตช์ก็เป็นสิ่งที่ทุกคนชอบทำกันอยู่แล้ว
มันจะถูกรื้อแล้วสร้างใหม่ทั้งหมดทุก 20 ปี และใน Breakneck ของ Dan Wang ที่เพิ่งอ่านมาก็อธิบายว่าแนวปฏิบัติการสร้างใหม่แบบนี้ช่วยรักษาความรู้ที่ไม่อย่างนั้นอาจสูญหายไปตามกาลเวลา
Wang เปรียบเทียบศาลเจ้าอิเสะกับ Notre Dame โดยมองว่าหนึ่งในเหตุผลที่การสร้างหลังคา Notre Dame ใหม่ยากมาก อาจเป็นเพราะความรู้สูญหายไปแล้ว
ฉันไม่ได้คุ้นกับอาคารทั้งสองมากพอจะบอกว่านี่เป็นการเทียบที่ยุติธรรมหรือเปล่า แต่ชอบหลักการนี้
ในหนังสือมันเป็นแค่อุปมาเล็ก ๆ แต่โดยรวมแล้วแนะนำมาก
รีบูตไม่กี่วินาทีก็กลับมาได้ และการอัปเกรดก็ทำแบบไม่สะดุดได้ด้วยการชี้ DNS ไปยังอินสแตนซ์ใหม่
แต่ถ้าเป็นเครื่องจริงที่โคลนได้ไม่ง่าย เรื่องจะต่างออกไป
ไม่จำเป็นต้องให้ทุกอย่างถูกจัดการด้วย Ansible แบบเต็มรูปแบบ ส่วนใหญ่ฉันใส่แค่คอนฟิกเริ่มต้นไว้ตรงนั้น และยังมีอะไรที่จัดการด้วยมืออีกเยอะ
ฟังดูตลกนิดหน่อย แต่ช่วยได้บ่อยกว่าที่คิด
งานส่วนตัว/งานอดิเรกโดยมากฉันรันด้วยชุด Caddy หน้าเว็บ + Docker Compose
ถ้าเป็นเว็บง่าย ๆ Caddy ก็เสิร์ฟคอนเทนต์เอง ส่วนถ้าเป็น “เว็บแอป” ก็แทบทั้งหมดจะถูกทำเป็นคอนเทนเนอร์ แล้วให้ Caddy ทำ TLS termination และ reverse proxy ไปยังแอปที่อยู่ใต้ Docker
ปกติจะใช้โครงสร้าง
~/apps/appnameและในแต่ละไดเรกทอรีของแอปจะมีไฟล์ Docker Compose กับไดเรกทอรีข้อมูลที่เมานต์ไว้หลัง
compose downก็สามารถดึงข้อมูลออกด้วย (s)ftp เพื่อเก็บระยะยาวหรือย้ายไซต์/บริการได้เมื่อก่อนเคยรันหลาย VM บน dedicated server แต่ย้ายไปเป็น VPS แยกของ OVH แล้ว และถ้าจะรันเมลบน OVH ต้องหลีกเลี่ยง local zone VM ที่ไม่อนุญาตเมลโฮสติ้ง
ทั้งนี้ก็ขึ้นกับสภาพแวดล้อม
NPM ก็ดีมากและเว็บ GUI ก็โอเค แต่ Traefik แค่เขียนสิ่งที่ต้องการลงในไฟล์ Docker Compose ก็จบ
แค่ใช้ Unraid รันคอนเทนเนอร์ และมีตัวหนึ่งเป็นเครื่องมือสาย nginx ที่ออกแบบมาให้ทำ reverse proxy ให้บริการอื่น ๆ
เพียงแต่กำลังคิดว่าจะย้ายจาก Debian ไปทางระบบ/OS แบบ immutable และเน้นคอนเทนเนอร์ก่อน อย่าง Flatcar ดีไหม
FreeBSD มีข้อได้เปรียบทางเทคนิคที่น่าสนใจ แต่จะชอบหรือไม่ก็ตาม ค่าเริ่มต้นของซอฟต์แวร์โอเพนซอร์สจำนวนมากคือ Docker และฉันก็ไม่มีทั้งเวลาและแรงจูงใจจะย้ายทุกอย่างไปเป็น FreeBSD jail
เมื่อไม่กี่สัปดาห์ก่อนฉันก็ทำแบบเดียวกัน
เซิร์ฟเวอร์ไม่ได้อัปเดตมาตั้งแต่ราวปี 2015 และยังมี Ghost blog กับ
node 0.10จากยุคนั้นติดตั้งอยู่ของฉันใช้วิธีดิบกว่านั้น คือทำแบ็กอัปไว้แล้วปล่อย Hermes agent (Gemini 3.1 Pro) ลุยเลย
มันจัดการอัปเกรดและแพตช์ที่จำเป็นทั้งหมด แล้วก็ย้ายไปยังสิ่งที่รองรับล่าสุดด้วย
หลังจากนั้นยังมีการ harden เซิร์ฟเวอร์และลบบริการที่ไม่ใช้ไปอีกพอสมควร และถ้าไม่มี AI ช่วย ก็คงจะผัดวันประกันพรุ่งต่อไป
ปัญหาจริงคือความเสี่ยงที่อะไรบางอย่างจะพัง และสิ่งที่ช่วยลดความเสี่ยงนั้นก็คือ แบ็กอัป
การใช้ FreeBSD บนเซิร์ฟเวอร์ส่วนตัวเคยเป็นประสบการณ์ที่สนุกมาก
มันมีความเท่ สะอาด เรียบง่าย และให้อารมณ์แบบ “พังก์ร็อก”
แต่สุดท้ายก็เลิกใช้เพราะจุดเจ็บหลัก ๆ: PM2 มีบั๊กบน FreeBSD และมันเป็นเครื่องมือที่ใช้จัดการโปรเซส, เลยพยายามใช้
rc.dรัน daemon แทนแต่การตั้งค่า log ยากเกินไป, ส่วนไฟร์วอลล์ก็มีอะไรให้ตั้งเองเยอะมากถ้าจะให้ตรงกับแนวปฏิบัติด้านความปลอดภัย เช่นจะจัดการ ICMP ยังไง และก็คิดถึงเทมเพลตสำเร็จรูปแบบค่าปริยายของ UFWแค่ทำด้วย IPFW แทน PF
ดูคีย์
firewall_typeในrc.confได้ที่: https://cgit.freebsd.org/src/tree/libexec/rc/rc.conf?id=8e08...ถ้าจะตั้งไฟร์วอลล์แบบเครื่องเดียวให้ง่าย ๆ ใช้
firewall_type=clientได้ หรือถ้าจะโฮสต์อะไรสักอย่างก็ใช้firewall_type=workstationแบบหลังจะมี
firewall_myservicesและfirewall_allowservicesควบคุมว่าจะเปิดพอร์ตไหน และเครือข่าย/IP ไหนเข้าถึงได้ถ้าเป็น NAT gateway ง่าย ๆ ก็ใช้
firewall_type=simpleกับfirewall_simple_(iif|inet|oif|onet)(_ipv6)?เพื่อกำหนดชื่ออินเทอร์เฟซฝั่ง ISP/ฝั่งภายใน และช่วงเครือข่าย IPv4/IPv6 ได้รายละเอียดว่าแต่ละตัวเลือกทำอะไรเป๊ะ ๆ ดูได้จากการอิมพลีเมนต์ใน
/etc/rc.firewall: https://cgit.freebsd.org/src/tree/libexec/rc/rc.firewall?id=...สำหรับ log ของ daemon ใน
rc.dถ้าเป็นข้อความธรรมดาตามวิถียูนิกซ์ก็ใช้logger(1)ได้ หรือจะ redirect ลงไฟล์แล้วใช้newsyslog(8)จัดการขนาดไฟล์ก็ได้เรื่องไฟร์วอลล์ขอแนะนำ The Book of PF[0]
PF บน FreeBSD มีความต่างด้านไวยากรณ์จาก pf ของ OpenBSD แต่ก็ยังดีพอสำหรับทำความเข้าใจว่าไฟร์วอลล์ทำงานอย่างไร และควรเขียนกฎแบบไหน
[0]: https://nostarch.com/book-of-pf-4e
ตอนแรกมันดูสะดวกมาก แต่ขณะเดียวกันก็เป็นซอฟต์แวร์ที่น่าใช้งานแบบหงุดหงิด และตอน deploy เรื่อง การอัปเดต environment variable ก็ไม่เคยทำงานอย่างที่ตั้งใจเลยสักครั้ง
ถ้าไฟดับ พอบูตกลับมาจะบังคับให้ไปรัน
fsckกับไฟล์ซิสเต็มด้วยมือออกนอกเรื่องนิดหน่อย แต่ตอนนี้ Linux distro ฟรีตัวไหนมี รอบการซัพพอร์ต ยาวที่สุดกันแน่
ช่วงหนึ่งฉันใช้ CentOS 7 กับ VM เล็ก ๆ เพราะมีอัปเดตความปลอดภัยให้นานมาก และความเสี่ยงที่อะไรจะพังจากการอัปเดตก็น้อยที่สุด
พอลองหาดูก็เหมือนว่าตอนนี้ Alma/Rocky Linux น่าจะเป็นตัวเลือกที่ดีที่สุด และมีซัพพอร์ต 10 ปี
แต่ก็ยังสงสัยว่าได้รับการดูแลดีแค่ไหน
แต่พอเวลาผ่านไปนานขนาดนั้น ecosystem ก็ drift ไปมาก และการคงให้แอปพลิเคชันบน OS นั้นทันสมัยและยังรันได้ก็ยิ่งยากขึ้นเรื่อย ๆ
แพ็กเกจโครงสร้างพื้นฐานอย่าง
glibc, ชุด Python/Apache, GCC ค่อย ๆ เข้ากันไม่ได้กับแอปสแต็กล่าสุดการอัปเกรดเวอร์ชันครั้งหลังก็ทรมานเช่นกัน ไม่ใช่แค่เพราะฉันต้อนตัวเองจนมุมด้วยการผสมแพ็กเกจแปลก ๆ แต่เพราะเส้นทางอัปเกรดเองก็เป็นแบบพยายามให้ดีที่สุดมาโดยตลอด
เหมือนฉันจะยอมแพ้ตอนข้ามจาก 6 ไป 7 และสุดท้ายก็ตระหนักว่าสิ่งที่ฉันต้องการจริง ๆ คือ Fedora
ถ้าอัปเดตทุกปีหรือทุกครึ่งปี ก็ไม่ต้องสู้กับแพ็กเกจของ distro, คอนฟิกก็ทันสมัยและใช้งานได้, การอัปเกรด distro หลักก็ราบรื่น และ downtime ก็น้อยมาก
ฉันไม่คิดจะกลับไปใช้ “server distro” อีกแล้ว
เช่นอาจออกอัปเดตเคอร์เนลเพื่อแก้ ช่องโหว่ยกระดับสิทธิ์ ได้เร็วกว่า
ส่วน Rocky ก็รับมือด้วยการมีคลังความปลอดภัยเสริมแบบเลือกใช้ซึ่งให้การบรรเทา exploit ระหว่างรอของจาก RHEL ลงมา
ถ้ามองจากเหตุการณ์ล่าสุด ทั้งคู่ก็ดูเหมือนได้รับการดูแลค่อนข้างดี
ให้ทุกบริการรันในคอนเทนเนอร์ แล้วปล่อยให้ OS ฐานอัปเดตอัตโนมัติบ่อยเท่าที่จำเป็นก็พอ
ฉันเลือก openSUSE MicroOS และเพราะมันอัปเดตกับรีบูตแทบทุกวัน เลยค่อนข้างมั่นใจว่าเซิร์ฟเวอร์ยังแข็งแรงดี
เป็น atomic update ด้วย ดังนั้นถ้ามีอะไรพังก็แค่กดปุ่ม rollback ใน Cockpit แล้วค่อยกลับมาดูตอนมีเวลาได้
เพราะสุดท้ายพอถึงเวลาต้องอัปเกรดจริง ก็มักจะเจ็บหนักพอตัว
ฉันคิดว่าการกระโดดเวอร์ชันเล็ก ๆ บ่อย ๆ ดีกว่าการปล่อยไว้นานจนทุกอย่างเปลี่ยนหมดแล้วค่อยกระโดดครั้งใหญ่
แต่ถ้าลงทะเบียนกับ Red Hat ได้ก็มี RHEL ซึ่งให้เข้าถึงอัปเดตฟรีได้ถึง 10 เครื่องต่อบัญชีที่ลงทะเบียน
RHEL น่าจะเสถียรที่สุดในบรรดา distro หลัก และ Alma กับ Rocky ก็เป็น downstream clone ของ RHEL โดยแก่นแท้
ฉันก็กำลังอยู่ในสถานการณ์เดียวกัน
มีเซิร์ฟเวอร์เก่า 2 ตัวที่ปล่อยทิ้งไว้นาน “เกินไป” จนตอนนี้กลัวจะแตะเพื่ออัปเดต
แต่พอเห็นดราม่าที่ Linux distro ต่าง ๆ เล่นกับเรื่องการยืนยัน/พิสูจน์อายุ ก็เริ่มคิดว่าจะย้ายหนีเหมือนกัน
ฉันลอง Artix ด้วย แต่หลังรีสตาร์ตเมื่อสัปดาห์ก่อนมันพังไปเลย และดูเหมือนว่า kernel update ก่อนหน้านั้นจะมีอะไรผิด จนต้องหยิบ rescue ISO ออกมาใช้
เลยเปลี่ยนเครื่องนั้นไปเป็น Devuan แต่ยังขอรอดูไปก่อน
ยังไม่มีเรื่องให้บ่นมากนัก แต่ก็ยังอยู่ในช่วง burn-in
บนแล็ปท็อปฉันใช้ Arch อยู่ แต่ชุมชนดูเป็นปฏิปักษ์เรื่องการเซ็นเซอร์พอสมควร เลยรอให้มีเวลาช่วงสุดสัปดาห์แล้วจะล้างลงอย่างอื่น
ฉันไม่ต้องการ ดราม่าทางการเมือง ในซอฟต์แวร์
ที่น่าสนใจคือครั้งนี้เป็นครั้งแรกที่ฉันซื้อแล็ปท็อปใหม่แล้วไม่เคยบูตเข้า Windows เลย แต่ลง Linux ทันที และทุกอย่างก็ “ใช้งานได้เลย”
ยิ่งเศร้าที่พอถึงจุดที่เริ่มสนุกกับ Linux จริง ๆ ผู้เล่นรายใหญ่กลับยอมรับแนวทางที่กัดกร่อนความเป็นส่วนตัวอย่าง AI everywhere, การยืนยัน/พิสูจน์อายุ, telemetry เปิดเป็นค่าเริ่มต้น
ฉันตั้งใจจะตอบทุกปฏิสัมพันธ์กับสิ่งพวกนั้นแบบ “ไม่เอา”
ตอนนี้เซิร์ฟเวอร์นั้นก็ยังรัน LTS ล่าสุดอยู่
ไม่รู้ว่าเริ่มจาก Ubuntu 4 หรือ 6 แต่ก็ผ่านมาได้เรื่อย ๆ แบบไม่มีปัญหา
บางทีการอัปเกรดช้าอาจช่วยให้หลีกเลี่ยงความเจ็บปวดของคนใช้รุ่นแรก ๆ ได้
เดี๋ยวนี้ฉันใช้ Debian มากกว่ามาก
ในยุคที่ supply-chain attack เยอะขนาดนี้ Debian Stable เหมือนอัญมณีจริง ๆ และถึงจะมีบางแพ็กเกจที่ต้องจัดการเพิ่มเองเพราะอยากได้เวอร์ชันใหม่กว่า ฉันก็ชอบจิตวิญญาณวิศวกรรมแบบเรียบง่ายแต่หนักแน่นของมัน
ทั้งคู่เป็นฝั่งที่ตามกระแสใหม่ล่าสุดเร็วที่สุด และไม่ได้ดีที่สุดด้านเสถียรภาพเสมอไป
แต่ก็ไม่ได้แปลว่า rolling distro จะต้องให้ทุกอย่างเป็นเวอร์ชันล่าสุดที่สุดตลอดเวลา
ช่วงหลายเดือนมานี้ฉันใช้ Void Linux อยู่ มันเป็น rolling distro แต่ใช้ LTS kernel และก็เลือก mainline ได้ด้วย ขณะที่ผู้ดูแลให้ความสำคัญกับเวอร์ชันแอปที่เสถียรมากกว่าการอัปเดตให้เร็วสุด
และก็มี Debian บ้างในที่ที่จำเป็น เช่น Proxmox, VPS ที่ไม่รองรับ Alpine, อุปกรณ์เกี่ยวกับงานบริษัท เป็นต้น
ยังมีเครื่องทดสอบบางตัวที่รัน Chimera แต่คงยังไม่พึ่งพามันมากจนกว่าจะมี stable release
ช่วงนี้ก็ลองเล่น AerynOS อยู่บ้าง
อายุซัพพอร์ตของแต่ละรีลีสสั้นกว่า 1 ปี ทำให้ถ้าพลาดช่วงอัปเกรดไปแล้ว การอัปเกรดภายหลังจะยากกว่า distro อื่นอย่าง Debian Stable มาก
ตอนนี้ย้ายงานเซิร์ฟเวอร์ไปใช้ Debian กับ Ubuntu แล้ว แต่ตอนหนุ่ม ๆ ช่วงกลางทศวรรษ 2000 ฉันเคยคลั่ง FreeBSD มาก
สุดท้ายใช้เวลาตั้งค่าและเล่นกับมันมากกว่าทำอะไรที่เป็นประโยชน์จริง ๆ
ตอนนั้นหาผู้ให้บริการ dedicated server หรือ VPS ที่มีสาย BSD ยากมาก และเหมือนฉันจะไปลงเอยกับ Panix.com
ก่อนหน้านั้นก็จำได้ลาง ๆ ว่ามีบริษัทชื่อ 15MinuteServers ที่น่าจะอยู่แถว NAC ในนิวเจอร์ซีย์และมี BSD ให้ใช้
ตอนนี้ก็แค่เล่าความหลังเฉย ๆ
ฉันใช้ FreeBSD บน Hetzner กับ OVH และเมื่อก่อนก็เคยใช้ Vultr ด้วย
และผู้ให้บริการ KVM VM/VPS ส่วนใหญ่ก็ให้เข้าถึงคอนโซลและเมานต์ ISO ของผู้ใช้ได้ ดังนั้นจะติดตั้งอะไรก็ได้ตามต้องการ
ที่ fastfetch รายงานว่าใช้หน่วยความจำมากกว่าความจริง น่าจะเป็นเพราะ ZFS ARC
คล้าย page cache ของ Linux คือเรียกคืนได้ทุกเมื่อ และแต่ละเครื่องมือก็เรียกมันไม่เหมือนกัน: https://www.linuxatemyram.com/
จำได้ว่าตอนมีคนอธิบาย Docker ให้ฟังครั้งแรก ฉันตอบไปว่า “อ๋อ หมายถึง jail ใช่ไหม?”
อย่างที่บทความอธิบาย มันไม่ได้เหมือนกันทั้งหมด
kqueueก็เป็นชัยชนะครั้งใหญ่เหมือนกันต้องขอบคุณนักพัฒนา FreeBSD มากจริง ๆ
ฉันสร้างบริษัทแรกและรันมันบน FreeBSD อยู่ 15 ปี และ uptime กับความทนทานของมันน่าทึ่งมาก
ฉันก็มีเซิร์ฟเวอร์ Ubuntu 16.04 ที่กลัวจะอัปเดตเหมือนกัน
ตอนนี้ uptime อยู่ที่ 1281 วัน และพอมาถึงจุดนี้ก็รู้สึกผิดที่จะรีบูตมัน
ddระบบไฟล์ไปไว้อีกเครื่อง แล้วบูตมันใน emulator อย่างqemuเพื่อ ซ้อมใหญ่ ดูก็ได้แค่ต้องระวังถ้ามีอะไรที่สตาร์ตอัตโนมัติแล้วออกไปเชื่อมต่อภายนอก
มีแบ็กอัปไม่ใช่เหรอ?
ระบบ Debian/Ubuntu ตั้งให้อัปเดตอัตโนมัติและรีบูตเป็นประจำได้ง่ายอยู่แล้ว ดังนั้นงานดูแลด้วยมือก็จะเหลือแค่ตอนอัปเกรดเวอร์ชันใหญ่