11 คะแนน โดย GN⁺ 2026-03-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • นี่คือบทความวิชาการของ ACM ที่ส่องให้เห็น กระบวนการวิวัฒนาการทางเทคนิค ของ Docker ซึ่งนับตั้งแต่เปิดตัวครั้งแรกในปี 2013 ก็ได้เปลี่ยนวิธีที่นักพัฒนาสร้าง ดีพลอย และรันแอปพลิเคชันอย่างสิ้นเชิง โดยสรุปงานวิจัยด้านระบบที่สั่งสมมาหลายทศวรรษซึ่งซ่อนอยู่เบื้องหลัง CLI ที่ดูเรียบง่าย
  • รากฐานทางเทคนิคสำคัญของ Docker คือการใช้ namespace ของ Linux เพื่อให้เกิดการแยกโปรเซสได้โดยไม่ต้องใช้ virtual machine และทำคอนเทนเนอร์แบบน้ำหนักเบาได้ด้วยการผสาน namespace ทั้ง 7 ประเภทที่ค่อย ๆ ถูกเพิ่มเข้ามาตั้งแต่ปี 2001
  • เพื่อรองรับ macOS และ Windows มีการเลือกสถาปัตยกรรมแบบสวนทางความคิดเดิม โดยฝัง library virtual machine monitor (HyperKit) ไว้ภายในแอปเดสก์ท็อป และรัน Linux อยู่ภายในโปรเซสของผู้ใช้แทนแนวทาง hypervisor แบบเดิม
  • ปัจจุบัน Docker รองรับฮาร์ดแวร์ต่างสถาปัตยกรรมอย่าง ARM·RISC-V และเวิร์กโหลด AI แล้ว และได้กลายเป็น โครงสร้างพื้นฐานมาตรฐานสำหรับการพัฒนา ครอบคลุมทั้งคลาวด์ เดสก์ท็อป และเอดจ์
  • เมื่อเวิร์กโหลด AI เติบโตขึ้น การจัดการ การพึ่งพา GPU ได้กลายเป็นความท้าทายใหม่ และ Docker ก็ยังคงพัฒนาต่อเนื่อง ทั้งการรองรับ GPU ผ่าน CDI(Container Device Interface) และการผสาน TEE(สภาพแวดล้อมการทำงานที่เชื่อถือได้)

จุดกำเนิดทางเทคนิค

  • ในช่วงต้นทศวรรษ 2000 การติดตั้ง dependency จำนวนมากด้วยตนเองบนลินุกซ์ดิสโทร รวมถึงการคอมไพล์และตั้งค่าซอฟต์แวร์เองเป็นเรื่องปกติ และเมื่อคลาวด์คอมพิวติ้งเริ่มเติบโตในปี 2010 กระบวนการนี้ก็ยิ่งซับซ้อนขึ้น
  • Docker ทำให้ทุกอย่างง่ายขึ้น โดยให้นักพัฒนาแพ็กแอปพลิเคชันพร้อม dependency ทั้งหมดเป็น อิมเมจระบบไฟล์("คอนเทนเนอร์") เพื่อให้รันได้บนเครื่องใดก็ตามที่ติดตั้ง Docker
  • ต่างจาก virtual machine ที่ไม่ต้องติดตั้งระบบปฏิบัติการทั้งชุด และสามารถรันได้ด้วยคำสั่งเพียงไม่กี่คำสั่ง

เวิร์กโฟลว์ทั่วไป

  • เมื่อนักพัฒนาเขียน Dockerfile ก็จะเป็นการกำหนดขั้นตอนการบิลด์แบบเป็นลำดับโดยอิงไวยากรณ์ของเชลล์
    • ตัวอย่างเว็บไซต์ Python: เริ่มจาก FROM python:3 แล้วอธิบายการติดตั้ง dependency การคัดลอกโค้ด การเปิดพอร์ต และคำสั่งรันไว้ในไฟล์เดียว
  • ใช้ docker build เพื่อสร้างอิมเมจคอนเทนเนอร์ และใช้ docker push เพื่อพุชไปยัง Docker Hub
  • รันด้วยการระบุการเมานต์ data volume และการเปิดเผย network port เช่น docker run -v data:/app/data -p 80:80
  • นับตั้งแต่ปี 2013 เป็นต้นมา CLI ได้ขยายความสามารถอย่างมากและแบ็กเอนด์ก็ถูกออกแบบใหม่ทั้งหมด แต่ เวิร์กโฟลว์พื้นฐาน คือการเขียน Dockerfile → docker builddocker run ยังคงเหมือนเดิม
  • พบ Dockerfile มากกว่า 3.4 ล้านไฟล์ อยู่ที่รากของ public repository บน GitHub

หลักการทำงานภายใน: Linux namespace

  • เคอร์เนลของระบบปฏิบัติการแยกหน่วยความจำของโปรเซสออกจากกัน แต่ทรัพยากรของระบบหลายอย่าง เช่น ระบบไฟล์ ไฟล์ตั้งค่า และไลบรารีแบบไดนามิก ยังคงถูกแชร์ร่วมกัน
    • ทำให้การติดตั้งหลายแอปบนเครื่องเดียวกันที่มี ข้อกำหนดไลบรารีแบบไดนามิกที่ขัดแย้งกัน เป็นเรื่องยากมาก
    • และอาจเกิด การรบกวนที่ไม่ต้องการ ระหว่างโปรเซส เช่น การชนกันของ network port
  • ปัญหานี้แก้ได้ด้วยการรันแต่ละแอปใน virtual machine (VM) แยกกัน แต่จะมีน้ำหนักมากมากจากเคอร์เนล ระบบไฟล์ แคช และ bridged network ที่ซ้ำซ้อน
    • เนื่องจาก guest OS แต่ละตัวทำงานอย่างเป็นอิสระ จึง กำจัดความซ้ำซ้อน ของสตอเรจและหน่วยความจำได้ยาก
  • chroot() ของ Unix v7 ในปี 1978 อนุญาตให้มี root filesystem แยกต่างหากได้ แต่ไม่รองรับการประกอบระบบไฟล์จากหลายแอป
  • Nix และ Guix แก้ปัญหาด้วยการรีแพ็กแอปไปไว้ในไดเรกทอรีรายแอปพร้อม dynamic linking แต่ใช้งานกับซอฟต์แวร์แบบ proprietary ได้ยาก และไม่สามารถแก้ปัญหา network port ชนกันได้
  • Docker เลือกใช้ namespace ของ Linux: ทำให้แต่ละโปรเซสควบคุมวิธีเข้าถึงทรัพยากรที่แชร์กัน เช่น ไฟล์และไดเรกทอรี ได้อย่างอิสระ
    • ตัวอย่าง: โปรเซสสองตัวใน namespace คนละชุดสามารถตีความ /etc/passwd เป็น /alice/etc/passwd และ /bob/etc/passwd ได้ต่างกัน
    • namespace จะถูกนำมาใช้เฉพาะ ตอนเปิดทรัพยากร เท่านั้น หลังจากนั้น file descriptor จะทำงานเป็นทรัพยากรเคอร์เนลปกติโดยไม่มีโอเวอร์เฮดเพิ่ม
  • ประวัติการนำ namespace เข้ามาใช้
    • ปี 2001 Linux 2.5.2: mount namespace
    • ปี 2006 Linux 2.6.19: IPC namespace
    • ปี 2007 Linux 2.6.24: network stack namespace
    • รองรับ namespace ทั้งหมด 7 ประเภท
  • ต่างจาก Plan 9 ที่มีการออกแบบ namespace มาตั้งแต่ต้น ใน Linux นั้น namespace ถูก ค่อย ๆ เพิ่มเข้ามาแบบทีละขั้น จึงเป็นฟีเจอร์ระดับต่ำและใช้งานยาก
  • ฟังก์ชันคล้ายกันใน FreeBSD และ Solaris ก็ไม่เคยไปถึงระดับการใช้งานอย่างแพร่หลาย
  • สิ่งที่ Docker มีส่วนสำคัญในปี 2013 คือการหาจุดสมดุลเชิงปฏิบัติระหว่าง การแยกที่หนักแบบ VM กับ ความสะดวกในการใช้ส่วนประกอบพื้นฐานของ OS

โครงสร้างการรัน Linux container ของ Docker

  • Docker ใช้โครงสร้างแบบ client-server โดยประกอบด้วยเซิร์ฟเวอร์ดีมอนที่รันบนโฮสต์ (dockerd) และ CLI client ที่ส่งคำขอผ่าน RESTful API
  • ราวปี 2015 ได้แยก monolithic daemon ออกและจัดโครงสร้างใหม่เป็นคอมโพเนนต์เฉพาะทาง
    • BuildKit: ประกอบอิมเมจระบบไฟล์
    • containerd: สร้างอินสแตนซ์จากอิมเมจให้เป็นคอนเทนเนอร์ที่กำลังรัน และจัดการทรัพยากรเครือข่ายกับสตอเรจ

อิมเมจคอนเทนเนอร์

  • เมื่อเรียก docker build จะสร้างอิมเมจแบบ layered filesystem ที่แสดงไฟล์ปฏิบัติการและข้อมูลตาม Dockerfile
    • เลเยอร์ล่างสุด: ดิสโทรระบบปฏิบัติการอย่าง Debian หรือ Alpine Linux (หรือประกอบเองด้วย tar archive)
    • เลเยอร์ถัดมา: ความแตกต่างของระบบไฟล์ที่เกิดจากการรันคำสั่งแต่ละรายการใน Dockerfile
  • จัดเก็บในระบบสตอเรจแบบ content-addressed: ใช้แฮชของอิมเมจระบบไฟล์เป็นคีย์
    • ช่วย deduplicate ได้อย่างมีประสิทธิภาพ รับประกันความไม่เปลี่ยนแปลง และตรวจสอบการดัดแปลงผ่านแฮชได้
  • ในปี 2016 Open Container Initiative(OCI) ได้ทำให้อิมเมจฟอร์แมตเป็นมาตรฐาน และมีอิมพลีเมนเทชันอิสระจำนวนมาก
  • ใช้ระบบไฟล์ของ Linux อย่าง overlayfs, btrfs, ZFS เพื่อ snapshot และ clone เลเยอร์แบบ copy-on-write ได้อย่างมีประสิทธิภาพ
  • รองรับ lazy-pulling ของอิมเมจผ่าน stargz storage snapshotter

อินสแตนซ์คอนเทนเนอร์

  • เมื่อเรียก docker run ระบบจะจัดสรรทรัพยากรของระบบเพื่อสร้างโปรเซสที่ถูกแยกด้วย namespace จากอิมเมจ OCI ("คอนเทนเนอร์")
  • งานที่ containerd ทำโดยการตั้งค่า namespace ที่จำเป็นให้แต่ละคอนเทนเนอร์แบบไดนามิก ได้แก่
    • กำหนด cgroups (control groups) ของโปรเซสเพื่อแยกทรัพยากรและจำกัดความเร็ว I/O
    • remap network port ภายในคอนเทนเนอร์ไปยังพอร์ตที่เปิดออกภายนอกบนอินเทอร์เฟซของโฮสต์
    • เชื่อมต่อ mutable storage volume ของระบบไฟล์โฮสต์เพื่อเก็บสถานะแอปแบบถาวร
    • แยก process tree ของคอนเทนเนอร์ด้วย PID namespace
    • ใช้ user namespace เพื่อแมป UID ภายในคอนเทนเนอร์ไปยัง UID อื่นบนโฮสต์ (เช่น UID 1000 ในคอนเทนเนอร์ → UID 12345 หรือ 23456 บนโฮสต์)
  • แม้การตั้งค่า namespace จะมีโอเวอร์เฮดอยู่บ้าง แต่ ต่ำกว่าการ spawn Linux VM เต็มรูปแบบมาก และส่วนใหญ่ใช้เวลาไม่ถึง 1 วินาที
  • เคอร์เนล Linux จะ garbage collect คอนเทนเนอร์ที่สิ้นสุดการทำงานแล้วเหมือนโปรเซสทั่วไป

ก้าวข้าม Linux: รองรับ macOS และ Windows

  • ด้วยสถาปัตยกรรมแบบ client-server ทำให้ CLI สามารถส่งคำสั่งไปยัง Docker instance ระยะไกลผ่านการเชื่อมต่อเครือข่ายที่ปลอดภัยได้
  • ในปี 2015 แม้ Docker จะถูกยอมรับอย่างกว้างขวางในการพัฒนาบน Linux แต่ก็เจอ อุปสรรคด้านการใช้งานที่ทำให้นักพัฒนา macOS/Windows ไม่สามารถรัน Linux container ได้
    • นักพัฒนาส่วนใหญ่ใช้ macOS/Windows เป็นสภาพแวดล้อมการพัฒนาหลัก แต่อิมเมจระบบไฟล์ของ Docker รันได้เฉพาะบนเคอร์เนล Linux
    • พร้อมกับการเติบโตของ public cloud ทำให้ Linux กลายเป็นสภาพแวดล้อมที่นิยมสำหรับการดีพลอย

การสร้างแอปพลิเคชัน Docker for Mac

  • ข้อจำกัดหลัก: ต้อง ทำงานได้โดยไม่ต้องตั้งค่าเพิ่มเติม สำหรับนักพัฒนาที่คุ้นเคยกับ Docker เวอร์ชัน Linux และต้องสามารถรัน Docker image เดิมได้
  • พลิกแนวทางเดิม (การรัน Linux แยกต่างหากข้างเดสก์ท็อป OS) โดย ฝังไฮเปอร์ไวเซอร์ ไว้ ภายใน แอปใน user space ของ macOS/Windows แล้วรัน Linux ในนั้น
    • ได้แรงบันดาลใจจากงานวิจัย unikernel: พิสูจน์ให้เห็นว่าสามารถฝังคอมโพเนนต์ของ OS ลงในแอปพลิเคชันที่ใหญ่กว่าได้อย่างยืดหยุ่น
  • HyperKit: library VMM ที่ใช้ส่วนขยาย hardware virtualization ของ Intel CPU เพื่อรัน Linux kernel ในโปรเซสผู้ใช้ทั่วไป
    • Linux kernel ที่ฝังอยู่จะรัน Docker daemon ซึ่งจัดการคอนเทนเนอร์และทำหน้าที่เป็น Docker server endpoint ตามปกติ
    • รายละเอียดการจัดการ Linux ทั้งหมดถูกซ่อนไว้ภายในแอปเดสก์ท็อป → docker build และ docker run บนเดสก์ท็อปถูกส่งต่อไปยังอินสแตนซ์ Linux ที่ฝังอยู่และ "ใช้งานได้เลย"
  • แนวทางนี้ยังถูกนำไปใช้กับระบบคอนเทนเนอร์อื่นอย่าง Podman และกลายเป็นวิธีมาตรฐานในการรันคอนเทนเนอร์บน macOS/Windows

LinuxKit: ดิสทริบิวชัน Linux แบบคัสตอมสำหรับการฝังตัว

  • ดิสทริบิวชัน Linux แบบคัสตอมที่ออกแบบมาให้ ฝังเป็นคอมโพเนนต์ของแอปอื่น ไม่ใช่ให้รันแบบสแตนด์อโลน
  • สร้าง user space แบบคัสตอม ที่มีเฉพาะคอมโพเนนต์ขั้นต่ำที่จำเป็นต่อการรัน Docker container เพื่อให้เวลาเริ่มแอปต่ำที่สุด
  • รันทุกคอมโพเนนต์เดี่ยวภายในคอนเทนเนอร์ ทำให้ไม่มี อะไรเลยที่รันอยู่ ใน root namespace ที่ใช้ตอนบูต
  • ใช้ copy-on-write filesystem และ network namespace แบบเดียวกับที่ Docker container ใช้งาน
  • การผสาน LinuxKit + HyperKit ทำให้บูตโปรเซส Linux ได้ด้วยความเร็ว แทบไม่ต่างจากโปรเซส native บน macOS
  • เปิดตัวในปี 2016 ในแอป Docker for Mac และ Windows

ปัญหาเครือข่ายและทางแก้ด้วย SLIRP

  • การเชื่อมต่อเครือข่ายจากคอนเทนเนอร์ Linux ที่ฝังอยู่ไปยัง macOS/Windows เป็นปัญหาที่ยากกว่าที่คาด
  • วิธี Ethernet bridging แบบเดิมต้องการการจัดการเครือข่ายที่ซับซ้อน และ ไฟร์วอลล์กับตัวตรวจจับไวรัส บนเดสก์ท็อปองค์กรตรวจพบว่าเป็นทราฟฟิกที่อาจเป็นอันตราย จนเกิดบั๊กรายงานจากผู้ใช้เบต้านับพันรายการ
  • ทางออกคือ SLIRP: เครื่องมือที่ถูกใช้ครั้งแรกในช่วงกลางทศวรรษ 1990 เพื่อเชื่อมต่อ Palm Pilot PDA เข้ากับอินเทอร์เน็ต
    • ระหว่าง TCP handshake ของคอนเทนเนอร์ เฟรม Ethernet จะถูกส่งไปยังโฮสต์ผ่าน shared memory ด้วย virtio protocol
    • ใช้ไลบรารี unikernel ของ MirageOS เพื่อแปลงคำขอ networking ของ Linux ให้เป็น native socket call ของ macOS/Windows
    • สแตก TCP/IP ใน user space ชื่อ vpnkit ที่เขียนด้วย OCaml จะรับข้อมูลบน host OS และเรียก macOS connect() syscall
    • ในมุมมองของนโยบาย VPN ทราฟฟิกขาออกจะถูกรับรู้ว่าเกิดจาก แอป Docker ไม่ใช่จากเครื่องอีกเครื่องหนึ่ง
  • หลังปล่อย vpnkit ในการทดสอบเบต้าเมื่อปี 2016 บั๊กรายงานจากผู้ใช้องค์กรลดลง มากกว่า 99%
  • ต่อมาแนวทาง SLIRP ยังถูกนำไปใช้ในวงการ serverless cloud ด้วย โดยเทคนิคเครือข่ายยุค dial-up เก่าถูกนำมาแก้ปัญหาการจัดการคอนเทนเนอร์แบบใหม่

การจัดการทราฟฟิกเครือข่ายขาเข้า

  • เมื่อคอนเทนเนอร์ Linux เปิดฟังพอร์ต มันจะไม่ถูกเปิดเผยสู่อินเทอร์เน็ตโดยอัตโนมัติ เว้นแต่จะร้องขออย่างชัดเจนจาก CLI (เช่น docker run -p 80:80 nginx)
  • ประสบการณ์ใช้งานในอุดมคติ: พอร์ตของคอนเทนเนอร์ควรไปโผล่ที่ IP ของเดสก์ท็อปโดยตรง เพื่อให้เข้าผ่านเบราว์เซอร์ได้ที่ http://localhost:8080
    • ระบบ virtualisation บนเดสก์ท็อปแบบเดิมอย่าง VMware Fusion จะเปิดเผย IP กลางชั่วคราว แทน localhost
  • ติดตั้ง โปรแกรม eBPF แบบคัสตอมในเคอร์เนล LinuxKit → กระตุ้นให้สร้าง listening socket ที่สอดคล้องกันบนเดสก์ท็อปโฮสต์ → เปิดใช้งานตัวทำ port forward
  • ผลลัพธ์: เมื่อรันคอนเทนเนอร์ Linux บน Mac จะเข้าถึงผ่าน localhost ได้ทันที ให้ประสบการณ์นักพัฒนาแบบเดียวกับเครื่อง Linux แบบ native

สตอเรจ

  • นักพัฒนาต้องสามารถแก้ไขโค้ดบนเครื่องโลคัล พร้อมกับรันโค้ดและการทดสอบภายในคอนเทนเนอร์ได้
  • บน Linux สามารถเข้าถึงไฟล์แบบ live ได้ผ่าน bind mount ด้วย docker run -v /host:/container
  • macOS และ Windows ใช้เคอร์เนลคนละแบบ จึงไม่สามารถใช้ bind mount ได้
    • Docker ใช้โปรโตคอล shared memory virtio-fs ที่มีต้นกำเนิดจาก KVM hypervisor เพื่อส่งการดำเนินการ filesystem ไปยังโฮสต์ (ในรูปแบบคำขอ FUSE)
    • โฮสต์จะรับคำขอเหล่านี้แล้วเรียก syscall open, read, write ที่สอดคล้องกัน
  • โค้ดและข้อมูลของนักพัฒนายังคงอยู่บน host filesystem จึงเข้าถึงได้จากเครื่องมือสำรองข้อมูลและค้นหาอย่าง Apple Time Capsule หรือ Spotlight

Windows Services for Linux (WSL)

  • ในปี 2017 Microsoft เปิดตัว WSL: รันแอป Linux ได้โดยตรงบน Windows
    • เวอร์ชันแรกใช้แนวทาง library OS ที่ แปลง system call ของไบนารี Linux ให้เป็น system call ของ Windows แบบไดนามิก แทนการใช้ virtualisation
    • แม้จะสำเร็จกับหลายแอป แต่มี system call ที่รองรับไม่เพียงพอ สำหรับการรัน Docker container
  • ปี 2018 เปิดตัว WSL2: ออกแบบใหม่ให้รัน Linux VM เต็มรูปแบบ อยู่เบื้องหลัง คล้าย Docker for Mac
    • Docker บน WSL2 รัน daemon และ user container ภายในดิสทริบิวชัน LinuxKit WSL
    • จัดการ Docker API และ network port forwarding ให้กับทั้งตัว Windows เองและดิสทริบิวชัน Linux อื่น
  • สถาปัตยกรรมสำคัญที่ทำให้ Docker container พัฒนาข้ามแพลตฟอร์มได้คือแนวทาง library OS ที่นำสิ่งซึ่งเดิมเป็น “โค้ดสำหรับเคอร์เนลเท่านั้น” มาใช้ซ้ำเป็นไลบรารีใน user space เพื่อฝังลงในแอปอื่น
  • ความสำเร็จของสถาปัตยกรรมนี้พิสูจน์ได้จากการที่มัน มองไม่เห็นแต่มีอยู่ทุกหนแห่ง: นักพัฒนาหลายล้านคนใช้ Docker ทุกวันโดยไม่ต้องกังวลว่ากำลังรันอยู่บน OS อะไร

เวิร์กโฟลว์นักพัฒนาแบบใหม่: หลายสถาปัตยกรรม CPU

  • ในยุคแรกของ Docker เวิร์กโหลดบนคลาวด์ส่วนใหญ่ยังอยู่บนสถาปัตยกรรม Intel
  • สถานการณ์เปลี่ยนไปเมื่อมีการเปิดตัว Amazon Graviton ARM ในปี 2018 และ Apple M1 ARM ในปี 2020
    • การรันเวิร์กโหลดบน ARM สามารถ ลดต้นทุนและเพิ่มประสิทธิภาพ ได้
  • จำเป็นต้องรองรับหลายสถาปัตยกรรม CPU ภายใน Docker image เดียวกัน เช่น Intel, ARM, POWER และ RISC-V
  • ฝั่งเซิร์ฟเวอร์ได้ขยายฟอร์แมต OCI image ให้รองรับ multiarch manifests
  • สำหรับการ build image หลายสถาปัตยกรรม CPU บนโฮสต์เครื่องเดียว ใช้ความสามารถ binfmt_misc ของ Linux
    • แปลงระหว่างไบนารี ARM และ Intel ได้อย่างโปร่งใสผ่าน QEMU
    • โดยหลักแล้วจะมี overhead เฉพาะในขั้นตอน build และ multiarch image ที่ได้จะ รันแบบ native ได้บนทุกโฮสต์
  • Apple นำการรองรับทั้งฮาร์ดแวร์และซอฟต์แวร์สำหรับการแปลงชุดคำสั่ง CPU ผ่าน Rosetta มาใช้ ทำให้ผสานเข้ากับสถาปัตยกรรม Docker ได้ง่าย
  • ปัจจุบันการ รันคอนเทนเนอร์ Intel และ ARM ควบคู่กัน กลายเป็นเวิร์กโฟลว์ปกติของนักพัฒนา

การจัดการความลับผ่าน Trusted Execution Environment (TEE)

  • ในสภาพแวดล้อมคอนเทนเนอร์ การจัดการ ความลับ (secrets) เช่น รหัสผ่านหรือ API key เป็นความท้าทายมาโดยตลอด
    • ต้อง ฉีดเข้าไปแบบไดนามิก โดยไม่ฝังไว้ในอิมเมจไฟล์ซิสเต็ม
  • Docker รองรับ socket forwarding ทำให้สามารถเมานต์ local domain socket เข้าไปในคอนเทนเนอร์ได้
    • ในกรณีของ Docker for Mac/Windows ยังสามารถ forward socket ไปถึง Linux VM ได้
    • ทำให้ใช้งานระบบจัดการคีย์อย่าง ssh-agent ภายในคอนเทนเนอร์ได้โดยไม่ต้องเปิดเผยคีย์โดยตรง
  • socket forwarding ให้การป้องกันในระดับพื้นฐาน แต่ต่อมัลแวร์ในซัพพลายเชนซอฟต์แวร์ที่ซับซ้อนขึ้นนั้น จำเป็นต้องมี ชั้นการป้องกันเพิ่มเติม
  • นำ การป้องกันระดับไฮเปอร์ไวเซอร์ มาใช้โดยตรงภายใน container runtime เพื่อยกระดับการป้องกันข้ามคอนเทนเนอร์
  • Trusted Execution Environment (TEE): ความสามารถด้านฮาร์ดแวร์ของ CPU สมัยใหม่ที่สามารถสร้าง confidential VM ซึ่ง ปกป้องข้อมูลลับได้แม้จาก host OS
    • สามารถบังคับใช้ข้อจำกัดการเข้าถึงข้อมูลข้ามขอบเขตของแอป เคอร์เนล และไฮเปอร์ไวเซอร์ได้
    • อย่างไรก็ตาม การตั้งค่าและใช้งาน TEE ก็มี ความซับซ้อนในการดูแลจัดการ คล้ายกับการทำ OS virtualization
  • คณะทำงาน Confidential Containers กำลังพัฒนาแอปที่ทำงานภายใน TEE และจัดการด้วย Docker
    • Docker CLI จะ forward ข้อความที่เข้ารหัส จาก TEE ภายในเครื่องเดสก์ท็อป ผ่านโฮสต์ ไปยังสภาพแวดล้อม TEE บนคลาวด์ระยะไกล
    • นักพัฒนาสามารถยืนยันตัวตนกับสภาพแวดล้อมคลาวด์ที่มีความอ่อนไหวได้โดยไม่ต้องไปถึงสถานที่จริง และข้อมูลรับรองจะ ถูกเก็บอย่างปลอดภัยใน desktop enclave

รองรับ GPGPU สำหรับเวิร์กโหลด AI

  • การมาของเวิร์กโหลด AI ทำให้เกิดความท้าทายรูปแบบใหม่ทั้งหมด: เวิร์กโหลดแมชชีนเลิร์นนิงส่วนใหญ่ทำงานบน GPU
  • ปัญหาหลักคือ เวิร์กโหลด GPU ต้องใช้ kernel GPU driver และ user-space library ที่ตรงกันอย่างแม่นยำ ขณะที่หลายคอนเทนเนอร์ทำงานอยู่บนเคอร์เนลที่ใช้ร่วมกันเพียงตัวเดียว
    • หากสองแอปต้องการ คนละเวอร์ชัน ของ kernel GPU driver ตัวเดียวกัน ก็จะเกิดความขัดแย้งพื้นฐานแบบเดียวกับที่ Docker ตั้งใจแก้ตั้งแต่แรก
  • ตั้งแต่เดือนมีนาคม 2023 Docker รองรับ CDI (Container Device Interface)
    • ปรับแต่งอิมเมจไฟล์ซิสเต็มในจังหวะที่เริ่มต้นคอนเทนเนอร์
    • ทำ bind mount ไฟล์อุปกรณ์ GPU และ dynamic library เฉพาะของ GPU พร้อมสร้างแคช ld.so ใหม่
  • CDI ช่วยรับประกันความพกพาของอิมเมจระหว่าง GPU บางคลาสและบางผู้ผลิต แต่ระหว่าง OS ที่ต่างกันหรือแบรนด์ฮาร์ดแวร์ที่ต่างกันยัง ไม่ลื่นไหลอย่างสมบูรณ์
    • เนื่องจาก dynamic library ที่ CDI เพิ่มเข้ามานิยาม API ที่ต่างกัน จึงไม่มีสิ่งที่เทียบได้กับ Linux system call ABI ที่มีเสถียรภาพซึ่งเป็นอินเทอร์เฟซดั้งเดิมของคอนเทนเนอร์
    • เหตุผลที่แอปสำหรับ Nvidia GPU รันบน Apple M-series CPU ได้ยาก คือการรองรับ GPU virtualization ยัง ไม่พัฒนาไปถึงระดับที่แปลง vector instruction ระหว่างฮาร์ดแวร์ที่หลากหลายได้
  • กำลังพัฒนา วิธีที่ยืดหยุ่นและปลอดภัยยิ่งขึ้น ในการจัดการ dependency ที่เกี่ยวข้องกับ GPU ร่วมกับชุมชนคอนเทนเนอร์และผู้ผลิต GPU
  • คาดหวังว่าโครงการริเริ่มด้าน portable interface จะนำไปสู่ฉันทามติ

บทสรุป

  • Docker เริ่มต้นในปี 2013 ด้วยเป้าหมายที่จะช่วยให้นักพัฒนาสร้าง แชร์ และรันแอปได้ง่ายขึ้น
  • ปัจจุบันได้ถูกรวมเข้ากับเวิร์กโฟลว์การพัฒนาบนคลาวด์และเดสก์ท็อปมาตรฐานอย่างลึกซึ้ง มี นักพัฒนาหลายล้านคนทั่วโลกใช้งานทุกวัน และรองรับ คำขอหลายพันล้านครั้งต่อเดือน
  • เป้าหมายที่สม่ำเสมอมาคือการรักษาชุมชนโอเพนซอร์สที่ มีชีวิตชีวาและหลากหลาย ซึ่งสร้างมาตรฐานเพื่อการทำงานร่วมกัน
    • CNCF (Cloud Native Computing Foundation) ทำหน้าที่เป็นผู้ดูแลคอมโพเนนต์หลักหลายตัว
    • Open Container Initiative (สังกัด Linux Foundation) เป็นผู้ดูแลฟอร์แมตอิมเมจ
  • ปัจจุบันมีอิมพลีเมนเทชันขององค์ประกอบเหล่านี้จำนวนมากที่ยังพัฒนาอย่างต่อเนื่อง และมีการนำไปใช้งานเพิ่มขึ้นในสภาพแวดล้อม edge เช่น คลาวด์ เดสก์ท็อป ยานยนต์ มือถือ และยานอวกาศ
  • ณ ปี 2025 เวิร์กโฟลว์ของนักพัฒนาทั่วไปได้รวมการทดสอบและดีพลอยอย่างต่อเนื่อง, IDE language server และ การช่วยเขียนโค้ดด้วย AI ผ่าน agentic coding
  • จากมุมมองของ Docker เวิร์กโฟลว์หลักแบบ “build and run” ยังคล้ายกับเมื่อ 10 ปีก่อนมาก แต่ การสนับสนุนจากระบบเพื่อลดแรงเสียดทานในสภาพแวดล้อมที่หลากหลาย ได้รับการเสริมอย่างมาก
  • เป้าหมายคือทำให้ Docker เป็น เพื่อนร่วมทางที่มองไม่เห็น ที่ช่วยให้นักพัฒนาส่งโค้ดขึ้นใช้งานได้เร็วขึ้น และ ออกแบบให้ขยายได้ เพื่อรองรับเวิร์กโฟลว์การเขียนโค้ดด้วย AI สมัยใหม่

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

 
GN⁺ 2026-03-08
ความเห็นจาก Hacker News
  • ตอนที่ Docker ออกมาใหม่ ๆ ตอนนั้นก็เริ่มเอียนกับคำว่า ‘นวัตกรรม’ อีกชิ้นแล้ว
    ไม่ชอบทั้ง NoSQL ที่ยังทำไม่เสร็จดี, ไมโครเซอร์วิสแบบยัดเยียด, และกระแสที่พยายามเปลี่ยนทุกการเรียกฟังก์ชันให้เป็น RPC
    แต่ตอนนี้กลับใช้มันบ่อยเพราะความเรียบง่าย
    อย่างไรก็ตาม คอนเทนเนอร์ของคนอื่น ก็ยังเหมือนนรกอยู่ดี อย่างน้อยฉันพยายามทำให้มันเรียบง่ายไว้ แต่บางคนยัดทุกอย่างลงไปจนให้ความรู้สึกว่าเจ้าตัวเองก็ไม่รู้กระบวนการดีพลอยด้วยซ้ำ
    ตอนนี้เหมือนเราอยู่ในยุคที่มีโค้ดทะลักออกมา ทั้งที่นักพัฒนาเองก็ยังไม่เคยเปิดดู เพราะอาศัย LLM

    • พอเห็นทีม DevOps ต้องมานั่ง Zoom คอลไม่รู้จบ ทุกเช้ามืดเพื่อแก้ปัญหาคอนเทนเนอร์ ก็ยิ่งมั่นใจว่าไม่มีใครรู้จริง ๆ ว่าข้างในมันเกิดอะไรขึ้น
  • มีความพยายามมากมาย แต่สุดท้ายเหตุผลที่ Dockerfile ยังอยู่รอดคือความยืดหยุ่น
    เพราะมันคุ้นเคยกับโครงสร้างแบบเดิม ๆ คือคัดลอกไฟล์แล้วรันคำสั่ง
    ถึงจะดูหยาบ ๆ แต่ความยืดหยุ่นแบบเรียบง่ายนี้ก็น่าจะยังเป็นกระแสหลักต่อไป

    • เพราะไม่มี build tool ที่เป็นกลางต่อภาษา สุดท้ายก็ต้องไปรันคำสั่งอะไรก็ได้ที่ไปเรียก package manager ของแต่ละภาษาอยู่ดี
      ถ้าทุกคนใช้ Nix หรือ Bazel กันหมด docker build อาจกลายเป็นเรื่องชวนขำก็ได้
    • มีอุปสรรคที่ขวาง reproducible build อยู่
      ถ้าแฮชต่างกันในแต่ละบิลด์ก็เชื่อถือไม่ได้ ดังนั้นตราบใดที่ปัจจัยอย่างเวลาแก้ไขไฟล์ยังถูกรวมในแฮช ความสอดคล้องแบบสมบูรณ์ก็ยังทำได้ยาก
    • การไม่มีที่เก็บกลางแบบ Docker registry คือ คอขวด ของโซลูชันทางเลือก
      ส่วนตัวชอบ mkosi แต่ไม่ใช่ทุกคนที่อยากเริ่มจาก OS template เปล่า ๆ
    • Nix ยอดเยี่ยมมากสำหรับการสร้าง Docker คอนเทนเนอร์
    • รู้สึกว่าอยากให้มันผูกกับ registry ได้แน่นกว่านี้อีกหน่อย
      ในกรณีส่วนใหญ่ก็แค่ pull จาก public registry แล้ว push ไป private registry ทำให้แทบไม่ได้ใช้ local image เลย
      มันอาจไม่มีประสิทธิภาพนัก แต่ก็ดูยังไม่แย่พอจะต้องเปลี่ยน
  • จำได้ว่า Docker ถูกเปิดตัวครั้งแรกที่ PyCon US Santa Clara ปี 2013
    ถ้าดู วิดีโองานนำเสนอบน YouTube ก็ถือเป็นช่วงเวลาประวัติศาสตร์เลย
    ดูเหมือนจะมีความสับสนเพราะช่วงเวลาที่ตีพิมพ์บทความกับช่วงที่นำเสนอจริงไม่ตรงกัน แต่คร่าว ๆ ก็ราว 13 ปีก่อน

    • ชื่อนี้ตั้งขึ้นมาในความหมายว่า ‘ย้อนเวลากลับไป’ เฉย ๆ
      “Twelve years of Docker containers” ฟังดูไม่ลื่นเท่า “A decade of Docker”
    • ที่จริงแล้วปี 2014 ถึงจะถูกต้อง
      จำ โพสต์เปิดตัวช่วงแรกบน HN ได้
      ตอนนั้นเหนื่อยกับทางเลือกอย่าง LXC หรือ Vagrant แล้ว แต่ Docker เหมือน ผู้กอบกู้ จริง ๆ
  • น่าสนใจที่ Docker เอา SLIRP ซึ่งเป็นเครื่องมือ dial-up จากยุค 1990 กลับมาใช้ใหม่เพื่อทะลุไฟร์วอลล์

    • Podman เองก็เคยใช้ slirp4netns อยู่ช่วงหนึ่ง แต่ช่วงหลังเปลี่ยนไปใช้ Pasta แล้ว
    • SLIRP ไม่ได้ทำมาสำหรับ Palm Pilot แต่เป็นยูทิลิตีที่สร้างขึ้นเพื่อให้ ผู้ใช้ shell account ซึ่งใช้ SLIP/PPP ไม่ได้ สามารถจำลองการเชื่อมต่ออินเทอร์เน็ตได้
      มันรับการเชื่อมต่อขาเข้าไม่ได้ แต่ก็เป็นแนวคิดคล้าย ๆ ต้นแบบของ NAT
    • การเอาเครื่องมือสำหรับ Palm Pilot มาใช้ทะลุไฟร์วอลล์นี่เป็น ไอเดียสุดบ้า แต่ความสิ้นหวังแบบนั้นแหละที่มักสร้างการแฮ็กโครงสร้างพื้นฐานที่ดีที่สุด
    • SLIRP มีไว้สำหรับ network namespace แบบ ‘rootless’ คือเป็นวิธีเอาคอนเทนเนอร์ไปต่อกับเครือข่ายของโฮสต์โดยไม่ต้องใช้สิทธิ์ root
  • อยากใช้ Docker มานานแล้ว แต่ทุกครั้งที่ลองก็มักขาดฟีเจอร์ที่ต้องการไปเสมอ
    น่าจะเป็นเพราะใช้ เทคสแต็ก ที่ไม่ค่อยมีคนใช้

  • ความยิ่งใหญ่ของ Docker คือทำให้คำว่า “ใช้ได้บนเครื่องฉันนะ” กลายเป็นมาตรฐานอุตสาหกรรม
    ตอนนี้เราอยู่ในยุคที่สามารถ ‘ส่งมอบ’ ตัวเครื่องนั้นไปขึ้นโปรดักชันได้เลย

    • ในฐานะผู้ร่วมเขียน ก่อน Docker ผมทำงานกับ Xen และ Docker ถือเป็น เหตุการณ์ที่เปลี่ยนวัฒนธรรม IT ไปทั้งระบบ
      เมื่อก่อนการดีพลอยเป็นกระบวนการใหญ่โตมาก แต่ตอนนี้กลายเป็นว่าเราดีพลอยไฟล์ซิสเต็มได้ตรง ๆ แล้ว
      นวัตกรรมของ coding agent ในตอนนี้ก็ให้ความรู้สึกเป็นการเปลี่ยนผ่านทางวัฒนธรรมคล้ายกัน
    • แก่นสำคัญของ Docker คือมันทำให้เราจับบิลด์ให้อยู่ในรูปของ กระบวนการที่ทำซ้ำได้
      ถ้าสามารถสร้างสภาพแวดล้อมเดิมได้ด้วยสคริปต์ 10 บรรทัด การ “ดีพลอยเครื่อง” ก็ไม่ได้แย่อะไร
    • Docker เป็นเหมือน static linking แบบสุดโต่ง ชนิดหนึ่ง
      เราควรถามตัวเองว่าทำไมแนวทางแบบนี้ถึงดึงดูดใจนักขนาดนั้น
    • จากเดิมที่ว่า “ใช้ได้บนโน้ตบุ๊กนะ” ตอนนี้เหมือนกลายเป็น “งั้นก็เอาโน้ตบุ๊กมาทำเป็นคอนเทนเนอร์แล้วโยนเข้า pipeline เลย”
      เหตุผลที่ abstraction ชนะเสมอ ก็เพราะการแก้ปัญหาที่ต้นตอมันยากเกินไป
    • เห็นคอนเทนเนอร์ห่วย ๆ พยายามใช้ Dockerfile จัดการบริการทุกอย่างแทน ระบบแพ็กเกจที่ดีจริง แล้วเหนื่อยใจ
  • ไม่ค่อยรู้เรื่อง networking เท่าไร แต่บน Mac อยากให้คอนเทนเนอร์มี IP address แยกต่างหาก
    อยากเข้าผ่าน container_ip:80 ได้โดยไม่ต้องทำ port mapping
    บน Linux ทำได้ แต่บน Mac ต้องผ่าน VM เลยซับซ้อน
    เคยลอง วิธีที่ใช้ WireGuard แต่พอ Docker อัปเดตก็พังทุกที
    ถ้ามีวิธีที่รองรับอย่างเป็นทางการก็คงดี

    • ในฐานะวิศวกร Docker ขอแนะนำให้ลอง ส่วนขยาย Tailscale
      Tailscale Docker Extension จะจัดการการตั้งค่าให้อัตโนมัติ
      ถ้าเหตุผลที่อยากเลี่ยง port mapping เป็นเพราะพอร์ตเปลี่ยนแบบไดนามิก ก็แนะนำให้ลองตัวเลือก --net=host และเปิดการตั้งค่า Host Networking
    • ไม่มี Mac แต่ขอแนะนำ โปรเจกต์ Colima เป็นทางเลือกโอเพนซอร์ส
  • ปี 2013 เป็นปีที่เรียกได้ว่า แพ็กเกจจิ้งออกดอกออกผล เพราะทั้ง Docker, Guix และ NixOS ต่างก็ออกมาในปีเดียวกัน
    ไปค้นพบข้อเท็จจริงนี้ตอนเขียนบทความที่เกี่ยวข้อง
    เลยสงสัยว่าหลังจากนั้นเคยมีปีไหนอีกไหมที่มีหลายโปรเจกต์เจ๋ง ๆ โผล่มาพร้อมกันแบบนี้

    • hg กับ git ออกห่างกันแค่ไม่กี่สัปดาห์ และ fossil ก็ออกตามมาติด ๆ
    • พูดตามตรง รู้สึกว่ามีแค่ Docker เท่านั้นที่ไปถึงระดับแมสจริง ๆ
      Guix กับ Nix ยังอยู่ในกลุ่ม ผู้ใช้เฉพาะทาง เป็นหลัก
  • พอ ML กับ AI เข้าไปอยู่ทุกที่ ขนาดอิมเมจก็ โตแบบทวีคูณ
    แค่ torch ตัวเดียวก็กินพื้นที่หลาย GB แล้ว
    คิดถึงยุคอิมเมจ 30MB สมัยก่อน

    • เคยเห็นอิมเมจที่ติดตั้ง TensorFlow ซ้ำสองรอบ ด้วย
      ไฟล์ไม่สามารถแชร์ข้ามเลเยอร์กันได้ ทำให้สิ้นเปลืองมาก
      เพราะอย่างนั้นตอนนี้เลยกำลังทำ registry ทางเลือก ที่รองรับ dedupe ระดับไฟล์ด้วยตัวเอง
    • ตอนนี้ผมใช้งาน Ruby กับ PHP คอนเทนเนอร์ไม่กี่ตัวบน Alpine Linux แบบ immutable ที่อิง ISO ซึ่งรวมทั้งหมดแล้วราว 750MB
  • เรื่องที่ Docker ปลอมตัวเป็น VPN เพื่อหลอกซอฟต์แวร์ความปลอดภัยสำหรับองค์กรก็น่าสนใจมากจริง ๆ
    มองในฐานะประวัติศาสตร์ทางเทคนิคก็นับว่าเป็นกรณีศึกษาที่สนุกมาก