4 คะแนน โดย GN⁺ 2024-09-15 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • สำหรับสตาร์ทอัพระยะเริ่มต้น การใช้เวลาไปกับการสร้างผลิตภัณฑ์และหา product-market fit อาจดีกว่าการเตรียม Kubernetes หรือระบบ autoscaling ตั้งแต่วันแรก
  • การมี Lambda functions 20–30 ตัว พร้อมล็อกที่กระจายอยู่ใน SQS และ CloudWatch ทำให้การดีบัก การเปลี่ยนแปลง และการดีพลอยยากขึ้น ทั้งที่อาจทำให้ง่ายลงได้ด้วยคอนเทนเนอร์ NodeJS เดียว หรือแอป Flask/FastAPI พร้อม Redis
  • ในกรณีที่แยก CRUD และ business logic ออกเป็น microservices 7 ตัวบน EKS เวลาส่วนใหญ่กลับถูกใช้ไปกับการดูแลอินฟรามากกว่าการพัฒนาฟีเจอร์
  • แม้จะเป็น VM เดียว ก็ยังมีตัวเลือกอย่าง EC2, GCP VM, Hetzner, latitude.sh และสามารถใช้เซิร์ฟเวอร์ระดับ RAM 40GB·หลายคอร์ ที่ให้พลังประมวลผลเพียงพอสำหรับบริการช่วงเริ่มต้น
  • แม้สถาปัตยกรรมจะเรียบง่าย แต่ถ้าจะใช้งานจริงก็ยังต้องมี HTTPS, SSH/SSM แบบจำกัดสิทธิ์, CI/CD, DNS, การสำรองฐานข้อมูล, VM สำรอง, การกู้คืนจากภัยพิบัติ, กฎความปลอดภัย และนโยบายการเก็บรักษาแบ็กอัป

โครงสร้างพื้นฐานที่มากเกินไปเกิดขึ้นได้อย่างไรในสตาร์ทอัพระยะเริ่มต้น

  • Pieter Levels ถูกยกเป็นตัวอย่างของคนที่รัน micro-SaaS หลายตัวบนเซิร์ฟเวอร์เดียว เพื่อหลีกเลี่ยงความซับซ้อนของโครงสร้างพื้นฐานคลาวด์และโฟกัสกับ product-market fit
  • วิธีนี้ไม่ใช่คำตอบที่เหมาะกับทุกทีม แต่สะท้อนให้เห็นชัดว่าการดีพลอยและการจัดการอินฟราสามารถ ซับซ้อนขึ้นเพียงเพื่อความซับซ้อนเอง ได้อย่างไร
  • ทีมพัฒนาเล็ก ๆ หลังผ่านช่วง MVP อาจเจอปัญหาเรื่องการดีพลอยและการดูแลฐานข้อมูล แต่ก็ไม่ได้หมายความว่าทุกโปรเจกต์ต้องเริ่มด้วย Kubernetes, ระบบกระจายที่ซับซ้อน หรือ autoscaling ตั้งแต่วันแรก
  • อินฟราที่เรียบง่ายช่วยให้ทีมมีเวลาไปกับการสร้างผลิตภัณฑ์ที่ดีและค้นหาความเหมาะสมกับตลาดได้มากขึ้น
  • บริษัทระดับ enterprise มีโจทย์อีกแบบทั้งเรื่อง compliance และจำนวนคนที่มาก แต่สตาร์ทอัพระยะเริ่มต้นไม่จำเป็นต้องลอกความซับซ้อนนั้นมาทั้งหมด

กรณีจริง: ภาระการปฏิบัติการที่เกิดจากความซับซ้อน

  • Lambda มากเกินไป

    • มี Lambda หลายตัวถึง 20–30 ตัวสำหรับบริการต่าง ๆ
    • SQS และงานเบื้องหลังหลายอย่างก็ถูกออกแบบบน Lambda เช่นกัน
    • ล็อกกระจายอยู่ทั่ว CloudWatch ทำให้ตามหาสาเหตุของปัญหาได้ยาก
    • การดีบักทรมาน การแก้ไขยุ่งยาก และแม้จะเป็น monorepo ก็ยังทำให้การดีพลอยซับซ้อน
    • ทั้งที่สามารถทำให้ง่ายกว่านี้ได้ด้วยคอนเทนเนอร์ NodeJS เดียว หรือแอป Python Flask/FastAPI พร้อมงานเบื้องหลังที่ใช้ Redis
  • microservices มากเกินจำเป็น

    • มี microservices ขนาดเล็ก 7 ตัวรันอยู่บน Kubernetes EKS
    • CRUD และ business logic ถูกแยกออกเป็นบริการคนละตัว
    • Kubernetes ทรงพลังมาก แต่ทีมนี้กลับใช้เวลากับอินฟรามากกว่าการพัฒนาฟีเจอร์
    • จึงยังเป็นคำถามว่าการแยกบริการในระดับนั้นจำเป็นจริงหรือไม่สำหรับขนาดของทีมและระบบ

ทำไมแนวทางเซิร์ฟเวอร์เดียวจึงเป็นทางเลือกที่ใช้งานได้จริง

  • สถาปัตยกรรมเซิร์ฟเวอร์เดียว คือการใช้ประโยชน์จากประสิทธิภาพของ VM สมัยใหม่อย่างเต็มที่
    • สามารถหา VM ที่แรงและคุ้มงบได้จาก Hetzner, latitude.sh
    • อินสแตนซ์ GCP VMs, EC2 ก็มีราคาที่สมเหตุสมผล
    • เซิร์ฟเวอร์ที่มี RAM 40GB และหลายคอร์อาจเป็นทางเลือกที่ดีกว่าการแตกเป็นบริการกระจายหลายตัว, Lambda หลายตัว หรือ ECS task หลายชุด
    • เมื่อทุกอย่างอยู่รวมกันในที่เดียว การปฏิบัติการและการจัดการก็ง่ายขึ้น
    • การขยายไปสู่ระดับหลายล้าน QPS ค่อยไปจัดการเมื่อถึงเวลาจริงก็ได้ และตอนนั้นก็มักจะมีทีมอินฟราแล้ว
  • การรัน single VM อย่างเสถียรยังต้องมีพื้นฐานด้านปฏิบัติการที่จำเป็น
    • เครื่องที่เชื่อถือได้ อย่าง EC2, GCP VM, Hetzner
    • สำหรับเว็บต้องมี HTTPS และสำหรับการดีพลอยต้องมี การเข้าถึงที่ปลอดภัย เช่น SSH จำกัด IP หรือ SSM
    • CI/CD สำหรับการดีพลอยแบบไม่มี downtime
    • การตั้งค่า DNS
    • การสำรองฐานข้อมูลเป็นประจำ
    • VM สำรองสำหรับทำ redundancy
    • ต้องมีกลยุทธ์ disaster recovery ที่มั่นคงและมีค่าเวลาเฉลี่ยในการกู้คืนที่ผ่านการทดสอบ ซึ่งสามารถทำได้ด้วย VM สำรอง

Docker Compose และ Docker Compose Anywhere

  • Docker Compose เหมาะกับการจัดการหลายบริการในการพัฒนาแบบโลคัลด้วยคำสั่งเดียว แต่ยังถูกใช้ใน production น้อยกว่า
    • มีการกล่าวถึงว่า Docker Swarm ถูก deprecated แล้ว
    • Docker Compose อาจเกิด downtime ระหว่างการอัปเดต
    • มี คู่มือการดีพลอยสำหรับ production และต้องหาสมดุลระหว่างความเรียบง่ายกับความพร้อมสำหรับ production
  • Docker Compose Anywhere เป็นโปรเจกต์ช่วงสุดสัปดาห์ที่ทำขึ้นเพื่อให้การตั้งค่า single VM ง่ายขึ้น
    • ใช้ GitHub Actions เพื่อตั้งค่า Linux server แบบ one-click
    • รองรับการดีพลอยต่อเนื่องแบบไม่มี downtime โดยใช้ GitHub Container Registry และ Docker Rollout
    • มีการจัดการ environment variables และ secrets และกำลังพิจารณา age หรือ sops เพื่อปรับปรุงความปลอดภัย
    • มีการสำรอง Postgres อัตโนมัติด้วย GitHub Actions
    • รองรับหลายแอปบน VM เดียว
    • ใช้ Traefik และ Let’s Encrypt เพื่อทำ SSL อัตโนมัติ
    • สามารถดีพลอยแอปอย่าง Next.js, Go, Python, Node.js ได้

หลักความปลอดภัยและการปฏิบัติการที่ตัดออกไม่ได้แม้ระบบจะเรียบง่าย

  • ความปลอดภัยและการปกป้องข้อมูลไม่ใช่สิ่งที่ละได้ แม้ในสถาปัตยกรรมที่เรียบง่าย
    • ต้องมีกฎไฟร์วอลล์ที่เข้มงวด เปิดเฉพาะพอร์ตที่จำเป็น
    • จัดการ SSH keys อย่างปลอดภัย และบน AWS ควรใช้ SSM ส่วนบน GCP ควรใช้ CLI
    • อาจใช้ bastion host เพื่อเพิ่มความปลอดภัย
    • ปกป้อง secrets และพิจารณาใช้ WAF หรือ Cloudflare
    • ส่งแบ็กอัปฐานข้อมูลที่เข้ารหัสแล้วไปยัง S3 หรือคลาวด์สตอเรจที่ปลอดภัยเทียบเท่า
    • ทำ disk snapshots เป็นประจำเพื่อเพิ่ม redundancy
    • กำหนดนโยบายการเก็บรักษาสำหรับแบ็กอัปและ snapshots
  • ลำดับความสำคัญของวิศวกรคือการรักษา ความเรียบง่าย ของระบบและโฟกัสกับผลิตภัณฑ์หลัก
  • โครงสร้างที่ซับซ้อนจากการพยายามเลียนแบบแนวทางแบบ Google engineering หรือบริษัทยักษ์ใหญ่ รวมถึงเครื่องมือใหม่ ๆ มักดึงความสนใจออกจากสิ่งสำคัญได้ง่าย
  • ไม่ว่าจะเป็นสตาร์ทอัพหรือไม่ สิ่งสำคัญที่สุดคือการคุยกับผู้ใช้และค้นหา product-market fit

1 ความคิดเห็น

 
GN⁺ 2024-09-15
ความเห็นจาก Hacker News
  • เคยต้องเหนื่อยแทบตายกับหลายโปรเจกต์เพราะ เทคโนโลยีตามกระแส อยู่บ่อยครั้ง
    ทั้งที่ทีมมีขนาดเล็ก แต่กลับสร้างผลงานคุณภาพต่ำอย่างไม่น่าเชื่อโดยอ้างว่าต้องการ “ความสามารถในการขยายแบบไร้ขีดจำกัด” และก็เคยมีทีมที่ยังไม่เป็นผู้ใหญ่พอจะเข้าใจด้วยซ้ำว่า LTS คืออะไร แต่ตัดสินใจว่าจำเป็นต้องใช้ Kubernetes
    ตอนนี้มีโค้ด Puppet แบบเรียบง่ายที่สามารถสร้าง VM ที่ harden แล้วตามขนาดที่ต้องการบนผู้ให้บริการใดก็ได้ แล้วรัน Docker service, แบ็กเอนด์ Python หรือเสิร์ฟไฟล์สแตติกบน VM นั้นได้
    ไม่ว่าจะเป็น Hetzner VM แบบ 2 คอร์หรือ 48 คอร์ ก็สร้างบริการได้ภายใน 5 นาที ควบคุมการตั้งค่าด้วย manifest ที่อยู่ใน source control และตรวจสอบการปฏิบัติตามค่าคอนฟิกด้วยปลั๊กอิน Naemon แบบกำหนดเอง
    เป็นกระบวนการที่ทำซ้ำได้อย่างสมบูรณ์ แต่ทีมสตาร์ทอัพกลับสร้างคอนฟิกแบบใช้ครั้งเดียวที่เหมือนเกล็ดหิมะบนคลาวด์ จ่ายหลายพันยูโรต่อเดือน แล้วยังได้ผลลัพธ์แย่กว่าสิ่งที่ผู้บุกเบิก DevOps เมื่อปี 2017 เคยทำไว้
    เคยเขียนบทความเรื่องนี้ชื่อ The Emperor's New clouds ด้วย: https://logical.li/blog/emperors-new-clouds/

    • ตอนเริ่มอาชีพ ปกติจะจัดการทุกอย่างด้วยเชลล์สคริปต์บน เซิร์ฟเวอร์ bare metal ที่ติดตั้ง Solaris และภายหลังเป็น SuSe หรือ RedHat
      ไม่เคยเข้าใจคำถามที่ว่า “ถ้าไม่มี Docker หรือเทคโนโลยีอื่น ๆ จะทำให้คอนฟิกทำซ้ำได้อย่างไร”
      สคริปต์เป็นแบบกำหนดผลลัพธ์แน่นอน เวอร์ชันของ dependency ถูกตรึงไว้ คอนฟิก อาร์กิวเมนต์อินพุต และลำดับการรันก็เหมือนกัน และรันบนเครื่องคำนวณที่ให้ผลลัพธ์แน่นอน
      ไม่มีเหตุผลอะไรที่จะทำซ้ำไม่ได้
    • เวลามีคนบ่นแบบนี้ รู้สึกว่า Kubernetes มักถูกยัดเข้ามาแบบไม่เกี่ยวเสมอ
      แทนที่จะบอกว่ามี Docker อยู่บน VM ที่ harden แล้ว ก็แค่บอกว่ามี kubelet อยู่ และแทนที่จะมี “docker services” หลายตัวแบบแก้ขัด ก็สามารถควบคุม VM ทั้งหมดนั้นด้วย control plane ของ k8s ที่มีค่าใช้จ่ายน้อยมากได้
      ไม่เห็นว่าทำไมวิธีนั้นถึงดีกว่า และกลับดูแย่กว่าด้วยซ้ำ
      โครงสร้างพื้นฐานคลาวด์ที่แย่คือกรณีที่พยายามใช้ทุกอย่างที่ AWS ขาย จนโครงสร้างพื้นฐานทั้งหมดถูกผูกไว้กับเลเยอร์ abstraction ที่สูงเกินไปและย้ายไปแพลตฟอร์มอื่นไม่ได้
      k8s ไม่ใช่เรื่องแบบนั้นเลย
    • จะ มอนิเตอร์ คอนฟิกนี้อย่างไร? จัดการ access control อย่างไร? ถ้าจะ deploy ไปยังผู้ให้บริการอื่นที่ไม่ใช่ Hetzner จะทำอย่างไร? ดู log อย่างไร? คนอื่นจะดูแลต่ออย่างไร? จัดการ backup, งาน cron, node ที่ offline, ingress ใหม่, การ provision storage เพิ่มอย่างไร?
      ถ้าคำตอบของข้อใดข้อหนึ่งคือ “ทำเอง” หรือ “ใช้สคริปต์อันเดียวก็พอ” นั่นแหละคือเหตุผลที่ k8s มีคุณค่า
    • ถามจริง ๆ นะ ทำไมถึงใช้ Docker? ตัด overhead อืด ๆ นั้นทิ้งไปได้เลย
      ถ้าเป็นแบ็กเอนด์ Python ก็แค่ทำซ้ำ build script บน VPS ตรง ๆ: pip install requirements.txt > python main.py > nano /etc/systemd/system/myservice.service > systemd start myservice > จบ
      การขยายจำนวนอินสแตนซ์ก็แค่นำคำสั่งเหล่านี้ใส่ใน bash script ชื่อ build_my_app.sh ซึ่งทำหน้าที่เหมือน Dockerfile ตัวใหม่ และติดตั้งบนเซิร์ฟเวอร์ใดก็ได้ภายในไม่กี่สิบวินาที
    • เห็นด้วย แต่สำหรับผม คลาวด์ มีข้อดีใหญ่อยู่ข้อหนึ่ง
      ถ้าใช้เป็น IaaS จะทำโปรโตไทป์ได้เร็วกว่าวิธีอื่นมาก รวมถึง VPS ของผู้ให้บริการอื่นด้วย
      โดยเฉพาะ Google Cloud ที่มี lock-in น้อย และสอดคล้องกับหลักการสร้างความประหลาดใจให้น้อยที่สุดมากกว่า
      แต่หลังจากสร้างโปรโตไทป์แล้ว ก็ควรถามว่าควรสร้างใหม่ในที่ที่ถูกกว่าหรือไม่
      การขยายดิสก์ได้แทบไม่จำกัดและมี snapshot เป็นเรื่องดี และคลาวด์สามารถช่วยให้ขยายโปรโตไทป์ไปถึงโหลดระดับ production เพื่อวัดขนาดที่จำเป็นจริงได้
      แต่ถ้าพึ่ง “เวทมนตร์คลาวด์” อย่าง Cloud Run หรือ Lambda เวลาในการเรียนรู้และดีบักสุดท้ายก็พอ ๆ กับการทำด้วยวิธีแบบเดิม
  • ในสตาร์ทอัพเล็ก ๆ แทบจะทำกันประมาณนี้อยู่แล้ว
    แม้จะมีส่วนซับซ้อนอย่างการขยายอัตโนมัติของคิวงานที่มี GPU ปะปนอยู่ แต่แกนหลักคือ nginx, เว็บแอป, Postgres, Redis บน VM ตัวเดียว
    เพราะเป็น B2B ทราฟฟิกก็แทบไม่มี
    นักพัฒนาสามารถรันคอนฟิกเดียวกันนี้ได้ตรง ๆ บนแล็ปท็อป Linux หรือ Linux VM บนแพลตฟอร์มอื่น และถ้าต้องการเพื่อเดโมหรือทดสอบ แต่ละคนก็มีคลาวด์ VM ของตัวเองได้
    การบูตสแตรประบบใหม่ก็ประมาณเช็กอิน SSH key แล้วรัน shell script
    ดีบักง่าย ไม่ซับซ้อนหรือแพง และก่อนจะถึงจุดที่ต้องขยายแนวนอน ก็สามารถ ขยายแนวตั้ง ได้ค่อนข้างมาก
    อาจไม่เหมาะกับทุกคน แต่ผมมองว่าก่อนถึงระยะ seed นั้นเหมาะสมอย่างสมบูรณ์

    • ถ้าสนใจ โฮสติ้ง Git รายใหญ่ทั้งสองแห่ง และน่าจะที่อื่นด้วย มี endpoint ที่แมปชื่อผู้ใช้กับ SSH key ที่ลงทะเบียนไว้แล้ว: https://github.com/mdaniel.keys https://gitlab.com/mdaniel.keys
      เป็นการเพิ่มชั้นอ้อมอีกขั้นจากวิธี “เช็กอิน public key” และผู้ใช้สามารถเปลี่ยน key ของตัวเองได้โดยไม่ต้องเปลี่ยน Git
      อีกอย่าง แม้จะออกห่างจากคำอธิบายเดิมไปพอสมควร แต่การเช่าใช้ SSH key จัดการสถานการณ์ offboarding ได้ดีกว่ามาก ซึ่งดีจริง ๆ: https://github.com/hashicorp/vault/blob/v1.12.11/website/con...
      ระหว่างหาลิงก์ ยังเจอเอกสารที่อ้างว่า Vault มีรหัสผ่านแบบใช้ครั้งเดียวให้ด้วย <https://github.com/hashicorp/vault/blob/v1.12.11/website/con...>
      แต่ผมอยู่ฝั่ง “PasswordLogin no” อย่างหนักแน่น ดังนั้นฝั่งนั้นก็ต้องใช้ด้วยความระมัดระวังกันเอง
    • ผมทำคอนฟิกแบบนี้ โดยไม่มี Redis
      Postgres ทำได้ทุกอย่าง
    • ชอบความเรียบง่ายของแนวทางนี้
      แล้วในคอนฟิกแบบนั้น ติดตาม การตั้งค่าและการอัปเดต ของ VM กันอย่างไร?
  • คำตอบคือ “ไม่ ไม่จำเป็น”
    SaaS ของผมเริ่มต้นรันบนเซิร์ฟเวอร์เครื่องเดียว และหลังจากได้ product-market fit แล้วจึงย้ายไปหลายเซิร์ฟเวอร์
    พวกนี้เป็น เซิร์ฟเวอร์ bare metal ของ Hetzner ไม่มีไมโครเซอร์วิส และไม่ได้ยุ่งกับ Kubernetes แต่รันฐานข้อมูลแบบกระจายอยู่
    เซิร์ฟเวอร์ bare metal เหล่านี้ทรงพลังกว่า virtual machine ของผู้ให้บริการคลาวด์อย่างมหาศาล
    หลายปีก่อนผมเคยวัดเองด้วย: https://jan.rychter.com/enblog/cloud-server-cpu-performance-...
    โดยรวมแล้วแนวทางนี้ได้ผลดีอย่างน่าขัน
    ไม่ต้องรับมือกับความซับซ้อนแบบ Kubernetes เลี่ยงความล้มเหลวแบบลูกโซ่ที่เกิดขึ้นอย่างหลีกเลี่ยงไม่ได้ในระบบซับซ้อน และประหยัดเวลาในการพัฒนา การบำรุงรักษา รวมถึงค่าเซิร์ฟเวอร์รายเดือน
    คำถามที่พบบ่อยคือ “แล้วจะสเกลยังไง” แต่ตอนนี้ยังไม่รู้ด้วยซ้ำว่าจะต้องสเกลหรือไม่ และด้วยคอมพิวเตอร์ที่ทรงพลังแบบนี้กับการออกแบบที่สมเหตุสมผล แค่ เซิร์ฟเวอร์ 3–5 เครื่อง ก็ไปได้ไกลมาก
    แน่นอนว่าไม่ได้หมายความว่าให้เอาธุรกิจไปรันในตู้เสื้อผ้าที่บ้าน
    สำหรับการจัดการเซิร์ฟเวอร์ยังต้องมี automation อยู่ดี และผมใช้ ansible กับ terraform

    • เรื่องการสเกลเป็น ไม้กายสิทธิ์ ชั้นเยี่ยม
      มันกระตุ้นความหวังว่า software จะประสบความสำเร็จอย่างมหาศาลในเวลาอันสั้น และผู้คนก็อยากเชื่อแบบนั้น
    • คำตอบคือ “ขึ้นอยู่กับสถานการณ์”
      ไม่แน่ใจว่าได้อ่านบทความหรือดูแค่หัวข้อ
      ถ้าเลื่อนลงไปถึงส่วน A few considerations ด้านล่าง ก็คงหัวเราะไม่ออก
      “ข้อควรพิจารณาบางอย่าง” เหล่านั้นเป็นงานด้านความปลอดภัยก้อนใหญ่ทีเดียว โดยเฉพาะถ้าคุณจัดเก็บหรือส่งข้อมูลที่อ่อนไหวมาก
      ในสถานการณ์แบบนี้ จะจัดการข้อกำหนด compliance อย่าง HIPAA อย่างไร?
      โปรแกรมเมอร์มีสองประเภท
      คนที่คิดว่าตัวเองเห็นมาหมดแล้ว กับคนที่รู้ว่าตัวเองแทบยังไม่เห็นอะไรเลย
      เพราะฉะนั้นคำฟันธงแบบเด็ดขาดเช่นนี้จึงน่าเหนื่อยใจ
  • แก่น 20% ของ Kubernetes คือส่วนอย่าง Deployment, Pod, Service, วิธีจัดการการปล่อยแบบ blue-green, การนิยามแบบ declarative และการแยก namespace ซึ่งดีมากจริง ๆ
    ถ้ายึดแค่พื้นฐานเรียบง่ายเหล่านี้ ใช้บริการ Kubernetes แบบ managed cloud และวางฐานข้อมูลที่มี state ไว้นอกคลัสเตอร์ ก็จะเป็นประสบการณ์ที่ดี
    ปัญหาเกิดขึ้นเมื่อถูกดูดเข้าไปในโพรงกระต่ายของ “cloud native” แล้วเริ่มใช้ระบบโอเพนซอร์สเฉพาะทางสารพัด, operator, ambassador, sidecar pattern ฯลฯ
    สิ่งเหล่านั้นมีไว้สำหรับสภาพแวดล้อมที่มีทีมเทคนิคหลายทีมที่เป็นอิสระต่อกันแต่เชื่อมโยงกัน และมีภาษาโปรแกรมมิงหลากหลายอยู่ร่วมกัน

    • สำหรับผม Kubernetes ก็แค่นั้นเอง
      ผมรู้สึกว่าในการถกเถียงแบบนี้ ผู้คนมักพูดถึงสองสิ่งที่ต่างกัน
      สำหรับผม มันเป็นแค่วิธี deploy ที่สม่ำเสมอและดีกว่า Docker Compose
      control plane เสียค่าใช้จ่ายน้อยมาก ส่วน worker ก็คือ VM ทั่วไปที่มี kubelet
      แต่สำหรับหลายคน “Kubernetes” ดูเหมือนจะหมายถึงย่อหน้าที่สองข้างบน
      ไม่จำเป็นต้องใช้แบบนั้นเลย
      แค่ลองตั้งค่า k3s cluster แล้วเรียนรู้แค่ workload, service, ingress ก็พอ
      สิ่งที่ต้องใช้เพื่อแทนที่ VM กับ Docker แบบแก้ขัดก็มีเท่านั้นเอง
    • จากการทำงานกับหลายบริษัทและหลายโปรเจกต์ ผมก็ได้ข้อสรุปเดียวกัน
      99% ต้องการหรืออยากได้แค่ประมาณ docker-compose++
      ถ้ามี zero-downtime deployment เป็นค่าเริ่มต้น และมีระบบตั้งค่าเรียบง่ายสำหรับ replica set หรือกลไกการทำ replica/กระจายโหลดแบบอื่น ๆ ก็แทบจบแล้ว
      อยากให้มีอะไรสักอย่างที่ทำแค่นั้นพอดี
      Kubernetes มีภาระเยอะ ส่วน Docker Compose ก็พื้นฐานเกินไปหน่อยสำหรับข้อกำหนดสำคัญของ production
    • ใช่เลย ตรงนี้แหละ
      Kubernetes มีปุ่มและแป้นหมุนเป็นล้าน ๆ ให้ปรับให้เหมาะกับแทบทุกการใช้งาน แต่ก็สามารถเพิกเฉยต่อมันได้เหมือนกัน แล้วใช้แค่ ฟีเจอร์หลัก เพื่อให้ทุกอย่างเรียบง่าย
      สามารถทำชุดตั้งค่าที่มีการ deploy ที่ดี, log กับ metric ที่ใช้ง่ายมาก และ developer experience ที่ดีได้อย่างรวดเร็ว
    • ผมเพิ่งรู้ว่าบริษัทใช้ Kubernetes อยู่
      เพราะชื่อเสียงมันแย่มากและผมไม่เคยใช้มาก่อน ตอนถามว่าตั้งเซิร์ฟเวอร์สำหรับเครื่องมือภายในได้ไหม เลยเตรียมใจเจอเรื่องเลวร้ายที่สุด
      แต่จริง ๆ คนที่ตั้งระบบไว้ทำ tutorial 30 นาทีให้ อธิบายแนวคิดทั้งหมด แล้วให้ข้อมูลมากพอที่จะ deploy เซิร์ฟเวอร์ได้ และผมก็ deploy ได้โดยไม่มีปัญหา
      การทำให้ auto deploy ด้วย git push ก็เสร็จเร็วมาก
      สำหรับผมมันดูเป็นตัวเลือกที่ชัดเจนเกินไปด้วยซ้ำ
      ถ้า service ไม่ได้มีแค่ตัวเดียวจริง ๆ มันใช้ง่ายกว่ามาก
      แต่อย่างไรก็ดี ผมไม่ได้เป็นคนติดตั้งเอง ชื่อเสียงแย่ ๆ อาจมาจากส่วนนั้นก็ได้
  • ถ้าไม่มี k8s ในเรซูเม่ ใครจะได้งานใหม่ล่ะ :)
    ถ้าพูดจริงจัง ผมคิดว่าหลายคนจงใจเลือกทางยากเพื่อเรียนรู้ infrastructure ขนาดใหญ่
    อีกเหตุผลที่พบบ่อยคือ “ถ้ามีลูกค้าเยอะมาก มันจะง่ายขึ้นมาก” หรือ “สามารถขยายแบบ dynamic ตาม demand ได้”
    ทั้งหมดนี้สมเหตุสมผลสำหรับคนที่สร้างมัน แต่ไม่ได้สมเหตุสมผลเท่าไรสำหรับ founder หรือ CTO มืออาชีพ

    • อาจฟังดูแรง แต่การทำแบบนั้นทั้งที่ไม่จำเป็นคือ ความสิ้นเปลืองและการใช้ทรัพยากรในทางที่ผิดอย่างไม่เป็นมืออาชีพ
      บางคนไม่สนใจความต้องการและกำหนดเวลาของลูกค้าเป้าหมาย แล้วเผาเงินไปกับการสร้างของเพ้อฝันที่ดูดี
      คล้ายกับเอารถไปอู่เพื่อเปลี่ยนยาง แต่ช่างใช้เวลา 3 สัปดาห์เพราะอยากเติมเต็มความต้องการเติบโตของตัวเองด้วยการติดตั้งไฮดรอลิกแบบ lowrider กับฝาครอบล้อหมุนได้
      แย่ที่สุดคือมันทำให้คนถัดไปแยกไม่ออกโดยเนื้อแท้
      ไม่รู้ว่าสิ่งที่อยู่ตรงนั้นมีอยู่เพราะจำเป็นจริง ๆ หรือเป็นแค่ของประดับแวววาว
    • แค่ดู ระดับความซับซ้อน ใน subreddit โฮมแล็บก็พอ
      ไม่แน่ใจว่าผู้คนทำเพราะสนใจ เพราะชอบเทคโนโลยี หรืออย่างที่บอกคืออยากอัปสกิลเชิง technocrat เพื่อใส่ k8s ในเรซูเม่
      ผมคิดแค่ว่า “ดูแล้วน่าจะดูแลลำบากมาก”
    • ผมเคยเห็นโปรเจกต์ที่ต้องใช้เวลาหลายปีแกะกองยุ่งเหยิงจาก deployment k8s ที่ม้วนขึ้นมาแบบครึ่ง ๆ กลาง ๆ ตามระดับความเข้าใจตอนแรก พร้อม antipattern และวิธีผิด ๆ ที่เกิดขึ้นในตอนนั้น
      ดังนั้นผมจึงคิดว่า infrastructure k8s ควรให้ผู้เชี่ยวชาญจริง ๆ ในวงแคบกว่า หรืออย่างน้อยคนที่ชำนาญพอจะนำ mentee ได้ เป็นผู้ออกแบบและลงมือทำ
      และเมื่อไม่จำเป็น ซึ่งก็คือ startup, ธุรกิจขนาดเล็ก และบริษัทขนาดปกติส่วนใหญ่ ก็ควรรักษา paradigm เดิม ที่ใช้ง่ายกว่าไว้
    • ธนาคารยูนิคอร์นของบราซิล Nubank เข้าใกล้เรื่องนี้แบบว่า “ถ้าสิ่งนี้ใช้ได้ ก็คงเป็นเพราะเราจะไปถึงสเกลใหญ่ได้อย่างรวดเร็ว” และเริ่มด้วย architecture ที่รองรับสเกลนั้นตั้งแต่แรก
      พวกเขาพอใจกับทางเลือกนี้มาก และเขียนรายละเอียดไว้ในบล็อก
      เป็นกรณีที่ “ถ้ามีลูกค้าเยอะมาก มันจะง่ายขึ้นมาก” เกิดขึ้นจริง
    • resume-driven development เป็นสิ่งที่คุ้มค่าจะเรียนรู้ให้มองออก
  • เป็นประเด็นถกเถียงที่เก่าและมักชวนเหนื่อย แต่ขอเสริมความเห็นเล็กน้อยของผม
    ถ้าถามว่าต้องเลือกเฟรมเวิร์กซับซ้อนตั้งแต่วันแรกไหม ถ้าทีมไม่ได้มีประสบการณ์ด้านนั้นมากพอ ก็คงไม่จำเป็น
    แต่สิ่งที่ผมไม่เห็นด้วยคือแนวคิดที่ว่า การจัดการอินฟราด้วยกระบวนการเฉพาะและเครื่องมือคัสตอม จะใช้แรงบำรุงรักษาน้อยกว่าเครื่องมือที่ผ่านการพิสูจน์แล้วเสมอ
    นั่นคือท่าทีที่ดื้อดึงปฏิเสธหุ่นไล่กาเรื่อง “ความซับซ้อน” ทั้งที่กระบวนการที่ทำเองนั้นไม่ได้เรียบง่ายเลย และยังดึงเวลาไปจากผลิตภัณฑ์หลักอย่างมาก
    ทุกคนชอบความเรียบง่ายของการคัดลอกไบนารีไปยัง VPS แล้วรีสตาร์ตบริการ
    แต่ไม่นานก็จะต้องมีการจัดการคอนฟิกและความลับ และเมื่อมีเซิร์ฟเวอร์หลายเครื่องเพื่อความพร้อมใช้งานและความซ้ำซ้อน ก็จะต้องมี progressive deployment, load balancing, rollback ฯลฯ
    คุณก็คงอยากมีสภาพแวดล้อม staging ด้วย และต้องทำให้เวิร์กโฟลว์นี้ทำซ้ำได้ง่าย
    เมื่อทีมใหญ่ขึ้น ก็จะเห็นชัดว่าไม่สามารถรันสภาพแวดล้อมที่คล้าย production ในเครื่อง local ได้
    แล้วความต้องการก็จะเพิ่มเข้ามาเรื่อย ๆ
    สุดท้าย ทุกความต้องการใหม่ก็ต้องแก้ด้วยวิธีเฉพาะของตัวเอง แทนที่จะพึ่งพา แนวทางมาตรฐาน ที่คนอื่นแก้ไว้แล้ว
    ภายหลังก็จะกลายเป็นปัญหาต้นทุนจม
    จะทิ้งเครื่องมือคัสตอมที่รู้จักและเข้าใจ แล้วย้ายไปสู่ “ความซับซ้อน” ที่ไม่รู้จักหรือไม่?
    ยิ่งลงทุนไปมากเท่าไร ภายหลังก็ยิ่งย้ายยากขึ้นเท่านั้น
    ข้อเสนอของผมคือ ตั้งแต่แรกให้ทำตามแนวปฏิบัติที่จะทำให้การย้ายไปใช้เครื่องมือมาตรฐานในภายหลังง่ายขึ้น
    เช่น deploy ด้วยคอนเทนเนอร์ตั้งแต่วันแรก และใช้แนวทาง 12-factor
    และเมื่อเริ่มลำบากเพราะฟีเจอร์ที่จำเป็น ก็ควรย้ายไปใช้เครื่องมือที่ผ่านการพิสูจน์แล้วให้เร็ว ดีกว่าปล่อยให้สายเกินไป
    มีโอกาสสูงที่คุณจะพบว่าความกลัวต่อสิ่งที่ไม่รู้จักนั้นไม่มีมูล และในระยะยาวเวลาที่ใช้กับอินฟราจะลดลง

    • เป็นคำพูดที่สรุปความรู้สึกสองด้านต่อปัญหานี้ได้ดี
      แนวทางที่ผมเคยพิจารณาคือ เริ่มด้วยเครื่องมือมาตรฐานตั้งแต่วันแรก คือ k8s + gitops แต่ยังคงรันบน VM เครื่องเดียว
      คิดอย่างไรบ้าง?
    • อีกมุมหนึ่งคือ การจ้างคนในอุตสาหกรรมที่คุ้นเคยกับ ระบบ SDLC ที่ทำเองนั้นแทบเป็นไปไม่ได้จริง ๆ
      ในทางกลับกัน สามารถหาคนที่เป็น “วิศวกรคลาวด์” ซึ่งเข้าใจระบบคลาวด์ที่ “ซับซ้อน” เหล่านี้ และ deploy/บำรุงรักษาด้วย terraform ได้จำนวนมาก
      เป็นชุดทักษะที่นำมาใช้งานได้ทันที
  • VM, block/blob storage, DNS, IdP, ผู้รับจดทะเบียนโดเมน
    ในคลาวด์ สิ่งที่ผมเคยใช้แล้วรู้สึกสบายใจก็มีแค่นี้
    พอเข้าไปใน FaaS และพวกเดียวกัน มันก็เริ่มแปลกมากสำหรับผม
    ผมรับมือได้ยากกับการที่ไม่สามารถเข้าไปดูเครื่องที่รัน production environment อยู่ได้
    ประสบการณ์ดีบักผ่านแดชบอร์ดคลาวด์นั้นแย่มาก
    ผมมองว่าแนวทางของ Microsoft ใกล้เคียงที่สุดกับสิ่งที่ “ใช้งานได้จริง” แต่ก็ยังน่ากลัวมาก และไม่อยากแตะต้องอีก
    ผ่านมา 10 ปีแล้ว สถาปัตยกรรมในอุดมคติของผมยังคงเป็น codebase แบบ monolithic บน VM เครื่องเดียวที่สื่อสารกับ instance SQLite ภายในเครื่อง
    การมาของ NVMe storage ช่วยเสริมแนวทางนี้ได้ค่อนข้างมาก
    การสำรองข้อมูลจัดการด้วย snapshot ของ block storage และความทนทานของ transaction ถ้าจำเป็นก็ใช้ WAL replication
    เรียบง่ายจนดูโง่
    ทำให้โฟกัสกับธุรกิจและลูกค้าได้
    ลูกค้าไม่สนใจเรื่องพวกนี้เลย และจะไม่จ่ายเงินให้ด้วย
    โค้ดและอินฟราทั้งหมดเป็นปัจจัยติดลบล้วน ๆ จึงควรมีให้น้อยที่สุดเท่าที่ทำได้

    • VM, block/blob storage, DNS, IdP, ผู้รับจดทะเบียนโดเมน คือ วิธีที่แพงที่สุด ในการสร้างบริการคลาวด์
      เวลาคนพูดว่าคลาวด์แพงกว่า on-premises สาเหตุมักเป็นเรื่องนี้
      ถ้าจะรัน VM ตลอด 24 ชั่วโมง มีตัวเลือกที่ดีกว่า
  • แม้แต่หนังสือเรื่อง microservices ก็ยังบอกว่า ให้สร้าง monolith ก่อน
    ก่อนจะได้ feedback จากผู้ใช้จริง เราไม่มีทางรู้ว่าควรแบ่งระบบอย่างไร และการแยก monolith ออกเป็นส่วน ๆ ง่ายกว่าการจัดโครงสร้าง service ใหม่
    คุณอาจไม่จำเป็นต้องแยก monolith ออกเลยตลอดไปก็ได้
    Stripe สุดท้ายก็แยกบางส่วนออกจาก Rails monolith แต่ monolith นั้นไปได้ไกลอย่างน่าทึ่ง
    เป็นเรื่องยากที่จะดีบักได้ง่ายกว่า monolith อย่าง Django/Rails
    อย่างไรก็ตาม การมองล่วงหน้าเล็กน้อยว่าอินฟราจะไปทางไหนก็มีประโยชน์
    เวอร์ชันแรก ๆ ของบริษัทเราใช้ Django Docker container บน VM เครื่องเดียว และ deploy ด้วยมือผ่าน docker pull; docker stop; docker start
    คอนฟิกนี้อยู่ได้นานกว่าที่คิด
    Docker เป็นวิธีที่ดีในการเลี่ยงปัญหา packaging dependency
    ช่วงแรก ๆ ปัญหาอย่างเวลาติดตั้ง DB driver ใหม่แล้วต้องดูว่าเซิร์ฟเวอร์มีไฟล์ C header ที่จำเป็นไหม หรือคอนฟิกต่างจาก Mac หรือเปล่า อาจน่ารำคาญได้
    หลังรอบ seed extension เราจึงย้ายไป k8s เพราะความต้องการทางธุรกิจด้าน reliability และ scalability และ k8s ก็รองรับได้ดีจนถึง Series B
    เพราะเรา Dockerize ทุกอย่างไว้ การย้ายจึงง่าย แต่ในช่วงแรกเราลดความซับซ้อนอย่างจริงจัง

    • ใช่
      และควร ใช้เฟรมเวิร์กให้ถูกต้อง ไม่ใช่สร้างเวอร์ชันห่วย ๆ ของฟีเจอร์ที่เฟรมเวิร์กมีให้อยู่แล้วขึ้นมาใหม่
      ในแง่นี้ ผู้เชี่ยวชาญหนึ่งคนให้ผลงานดีกว่าคนไม่ชำนาญสิบคน
      ความแตกต่างจะสะสมมากขึ้นเรื่อย ๆ ตามเวลา
      ผมคิดว่าสาเหตุจริงครึ่งหนึ่งที่คนเบื่อ monolith คือ monolith ที่แย่และไม่ได้ถูกดูแลอย่างถูกต้อง
    • ที่น่าสนใจคือ หนังสือเรื่อง monolith กลับบอกว่า ให้แบ่งออกเป็น service ที่เล็กลง
      มันบอกว่าข้อมูลควรถูกเก็บไว้ใน service ของตัวเอง และถ้าต้องใช้แนวทางหลาย paradigm เช่น relational และ full-text search ก็อาจกลายเป็นหลาย service
      user experience ก็ควรใช้ service ของตัวเอง
      อย่างน้อยควรมี service อีกตัวคั่นอยู่ระหว่างนั้น และโดยทั่วไป Django กับ Rails จะอยู่ตรงนี้
      และอาจต้องมี service เพิ่มเติมแบบเลือกได้ เช่น authentication หรือธุรกรรมทางการเงิน
  • ผมรันโปรเจกต์หนึ่งอยู่บน VPS เดือนละ 10 ดอลลาร์ เครื่องเดียวประมาณ 6 ปี
    จริง ๆ จ่ายน้อยกว่านั้นด้วยซ้ำเพราะส่วนลดถาวรที่ได้จาก lowendtalk และเป็นผู้ให้บริการ VPS ที่เน้น game server
    ถ้าไม่นับครั้งหนึ่งที่ล่มทั้งวันเพราะผมตั้งค่าพลาดจนต้องลง OS ใหม่แบบสะอาด และอีกครั้งที่ผู้ให้บริการเปลี่ยน IP address หลังแจ้งล่วงหน้า ก็แทบจะเสถียรระดับ 99.999
    เทคโนโลยี VPS พัฒนาไปมากจริง ๆ และเสถียรมาก
    ดิสก์ของ node ตั้งเป็น RAID 1 และตอนบำรุงรักษา node ก็สามารถ live migrate ตัว VM ไปยังเครื่องอื่นได้ง่าย
    ถ่าย snapshot ได้ด้วย
    สำหรับผม เหตุผลที่จะเลือก cloud infrastructure ไม่ใช่เพราะความเสถียรที่สูงกว่า แต่เพราะฟังก์ชันด้านการทำงานร่วมกันและการจัดการปฏิบัติการ เช่น IAM, secret management, infrastructure as code หรือเพราะเหตุผลด้าน compliance ของ data center อย่าง HIPAA

    • ผู้ให้บริการไหน? ดูดีนะ
  • แล้วแต่สถานการณ์
    โดยส่วนตัวผมชอบโซลูชันบนคลาวด์ เพราะช่วยประหยัดเวลาได้มาก
    แต่ต้องเลือกอย่างระมัดระวังมากว่าจะใช้อะไร และก็มีบางโซลูชันที่ซับซ้อนเกินไปจนเห็นได้ชัดว่าให้ผลตรงกันข้าม
    ผมบริหารสตาร์ทอัพแบบ bootstrap ขนาดเล็กอยู่
    เรายังมีเงินไม่พอแม้แต่จะจ่ายเงินเดือนให้ตัวเอง และผมยังต้องทำงานที่ปรึกษาเป็นงานเสริมเพื่อเลี้ยงชีพ
    เมื่อมีทั้งงบประมาณและเวลาจำกัดแบบนี้ เราจึงต้องระมัดระวังมากว่าจะใช้อะไร
    เพราะแบบนั้นผมถึงชอบของอย่าง Google Cloud
    ค่าใช้จ่าย GCP ค่อนข้างต่ำ อยู่ที่ไม่กี่ร้อยยูโรต่อเดือน
    เราอาจย้ายไปผู้ให้บริการที่ถูกกว่านี้ได้ แต่ก็ยากที่จะหาเหตุผลมารองรับการลงทุนลงแรงนั้น และเมื่อเทียบกับ AWS ที่เคยใช้มาก่อน ผมก็ชอบ UI และเครื่องมือของ Google ด้วย
    Kubernetes ไม่มีโอกาสได้ใช้
    แค่ค่าใช้จ่ายในการรันคลัสเตอร์เปล่า ๆ ก็น่าจะแพงกว่าค่า GCP รายเดือนตอนนี้แล้ว
    และเราก็ไม่จำเป็นต้องใช้ เพราะไม่ได้ตกหลุมพราง microservices
    แต่ผมชอบ Docker
    มันทำให้การ deploy ซอฟต์แวร์ง่ายสุด ๆ
    เว็บไซต์ของเราเป็นบัคเก็ต Google Storage ที่เสิร์ฟผ่าน load balancer และ Google CDN
    load balancer ตัวเดียวกันจะ route REST calls ไปยัง VM สองเครื่องที่รัน monolith
    VM เหล่านี้สื่อสารกับ managed DB, managed Elasticsearch และ managed Redis
    DB กับ Elasticsearch แพง แต่การใช้แบบ managed ช่วยประหยัดเวลาและแรงได้มาก
    สิ่งที่เรามีก็แทบมีแค่นี้ทั้งหมด เรียบง่ายและก็ไม่ได้แพงขนาดนั้น
    ถ้าย้ายทั้งหมดไปที่อย่าง Hetzner ก็น่าจะลดต้นทุนได้ราว 50%
    อาจคุ้มที่จะลองทำ แต่สำหรับผมมันยังไม่ใช่เรื่องเร่งด่วนมาก
    ถ้าเสีย managed services เหล่านั้นไป ชีวิตผมจะยากขึ้น
    ดูเหมือนว่าลูกค้าบางรายจะชอบ AWS มากกว่า ดังนั้นสักวันหนึ่งเราอาจต้องกลับไป AWS ก็ได้ และก็มีประเด็นนั้นอยู่ด้วย