Fundamentals
Container vs Virtual Machine (VM)
Docker ไม่ได้เริ่มจากคำสั่ง docker run แต่เริ่มจากปัญหาที่นักพัฒนาทุกยุคคุ้นเคย: แอปทำงานบนเครื่องหนึ่ง แต่กลับมีปัญหาเมื่อย้ายไปอีกเครื่อง บทนี้จะพาคุณย้อนดูที่มาของ Docker แล้วเปรียบเทียบ Container กับ VM เพื่อสร้างภาพจำก่อนลงมือใช้จริง
คืนก่อนวัน Deploy: ทำไมโค้ดเดียวกันถึงรันไม่เหมือนกัน
ภาพจำสำคัญบทนี้
VM = บ้านแยกหลัง มี OS เป็นของตัวเอง / Container = ห้องในบ้านเดียวกัน แชร์ OS kernel ร่วมกัน
ลองนึกภาพทีมเล็ก ๆ ที่กำลังจะส่งเว็บขึ้น server แอปทำงานได้บนเครื่องของนักพัฒนา ทุกคนจึงคิดว่าน่าจะพร้อมแล้ว แต่พอขึ้น server กลับเจอ error เพราะเวอร์ชัน OS, runtime, library หรือ configuration ไม่เหมือนกัน โค้ดอาจเป็นชุดเดิม แต่ environment ต่างกัน ผลลัพธ์จึงต่างกันด้วย ลองหยุดคิดก่อน: ถ้าส่งแค่ source code ไปอีกเครื่อง แต่ไม่ส่ง environment ไปด้วย ปัญหานี้จะหายจริงหรือไม่?
- เครื่องนักพัฒนา — มี runtime, library และ configuration ที่แอปคุ้นเคย
- เครื่อง server — มีสภาพแวดล้อมอีกชุดหนึ่ง แม้จะรันโค้ดชุดเดียวกัน
- ปัญหาที่เกิดขึ้น — ทีมเสียเวลาไล่หาความต่าง แทนที่จะพัฒนาฟีเจอร์ต่อ
ความเป็นมาของ Docker: จากการแยกเครื่อง สู่การส่งแอปเป็นชุด
Container ไม่ได้เริ่มต้นจาก Docker และ VM ก็ไม่ใช่คำตอบที่ผิด ทั้งสองเป็นความพยายามแก้ปัญหาเดียวกัน: ทำให้แอปมีพื้นที่ทำงานที่คาดเดาได้และไม่รบกวนกัน Docker เข้ามาทำให้แนวคิด container จับต้องได้ง่ายขึ้นผ่าน workflow ที่นักพัฒนาคุ้นเคย เช่น CLI, image และการ build กับ run เป็นขั้นตอนที่ชัดเจน ตารางนี้จึงไม่ใช่รายการปีที่ต้องท่องจำ แต่เป็นเส้นทางว่าปัญหาเดิมค่อย ๆ ผลักให้เครื่องมือพัฒนาเปลี่ยนอย่างไร
| ช่วงเวลา | เกิดอะไรขึ้น | ความหมายต่อผู้เรียน |
|---|---|---|
| ก่อน Docker | แนวคิด container มีอยู่แล้ว แต่การใช้งานยังต้องพึ่งความเข้าใจระบบและเครื่องมือระดับล่าง | ยังมีช่องว่างระหว่างแนวคิด container กับ workflow ประจำวันของนักพัฒนา |
| มีนาคม 2013 | Docker เปิดตัวสู่สาธารณะ | การ build, ship และ run container เข้าใกล้ workflow ที่ใช้งานผ่าน CLI มากขึ้น |
| 9 มิถุนายน 2014 | Docker 1.0 ออกพร้อม production support | Docker เริ่มถูกมองเป็นเครื่องมือที่พร้อมนำไปใช้กับงานจริง |
| ปี 2015 | Docker บริจาค container format และ runC ให้ Open Container Project | ecosystem เริ่มขยับไปสู่มาตรฐานร่วมและการทำงานข้ามเครื่องมือ |
ทำไมควรเรียน Docker ถ้าคุณเขียนโค้ดเป็นอยู่แล้ว
คุณไม่จำเป็นต้องใช้ Docker กับทุกงาน และ Docker ก็ไม่ได้ทำให้ปัญหาทุกอย่างหายไป แต่การเรียน Docker จะช่วยให้คุณมอง environment, การ build, การ run และการ debug เป็นระบบเดียวกัน เมื่อภาพนี้ชัด คำสั่งในบทถัดไปจะไม่ใช่สิ่งที่ต้องจำแบบแยกส่วน และคุณจะต่อยอดไปยัง CI/CD, Docker Compose และ cloud ได้ง่ายขึ้น
- ทำซ้ำ environment ได้ — ลดปัญหา “เครื่องฉันทำงาน แต่เครื่องเพื่อนทำไม่ได้” ด้วยการมอง environment เป็นส่วนหนึ่งของการส่งมอบแอป
- เข้าใจเส้นทางจากโค้ดถึง server — เห็นความสัมพันธ์ระหว่างการ build, image, container และการตรวจสอบสิ่งที่กำลังรัน
- แก้ปัญหาเป็นระบบ — แยกให้ออกว่า error มาจาก image, container, network หรือ configuration แทนการลองแก้แบบสุ่ม
ปัญหาเดียวกัน มีสองแนวทาง
จากเรื่องเมื่อกี้ เราเห็นแล้วว่าทั้ง VM และ Container พยายามทำให้ environment ของแอปแยกและคาดเดาได้เหมือนกัน แต่ทั้งสองเลือกแลกคนละอย่าง: VM จำลองเครื่องทั้งเครื่อง ส่วน Container แยก process และแพ็กเฉพาะสิ่งที่แอปต้องการ วิธีคิดและต้นทุนจึงต่างกันมาก
- VM: จำลองเครื่องคอมพิวเตอร์ทั้งเครื่องพร้อม OS เต็มรูปแบบ
- Container: แชร์ OS kernel กับ host และแพ็กเฉพาะสิ่งที่แอปต้องการ
- เป้าหมายเหมือนกัน: สภาพแวดล้อมสม่ำเสมอ ย้ายได้ รันได้ทุกที่
Virtual Machine คืออะไร
ให้นึกถึงการเช่าอพาร์ตเมนต์ทั้งยูนิต VM คือการจำลองเครื่องคอมพิวเตอร์ทั้งเครื่อง (hardware เสมือน) รวมถึง CPU, RAM, และ disk ของตัวเอง ด้านบนของ hardware จริงจะมีซอฟต์แวร์ที่เรียกว่า Hypervisor ทำหน้าที่จัดการและแบ่งทรัพยากรให้แต่ละ VM แต่ละ VM มี Guest OS เป็นของตัวเองซึ่งอาจเป็น Windows หรือ Linux ก็ได้ และรันอิสระจากกันโดยสมบูรณ์ ตัวอย่าง Hypervisor ที่รู้จักกันดี ได้แก่ VMware, VirtualBox, และ Hyper-V
App
แอปพลิเคชันที่รันอยู่ใน VM
Guest OS
Windows, Linux ฉบับเต็ม (GB ต่อ OS)
VM
เครื่องเสมือนพร้อม virtual CPU, RAM, disk
Hypervisor
ตัวจัดการ VM (VMware, VirtualBox, Hyper-V)
Hardware
เครื่อง server จริงที่อยู่ล่างสุด
Container คืออะไร
ถ้า VM คืออพาร์ตเมนต์แยกยูนิต Container คือห้องแบ่งเช่าในบ้านเดียวกัน ทุกคนใช้โครงสร้างบ้าน (ระบบไฟ ประปา) ร่วมกัน แต่มีพื้นที่ส่วนตัวของตัวเอง Container แชร์ OS kernel กับ host โดยตรง จึงไม่ต้องบูต OS ใหม่ทุกครั้ง ตัว Container Engine (เช่น Docker) จะใช้ฟีเจอร์ของ Linux kernel อย่าง namespaces และ cgroups เพื่อแยก process, network, filesystem ให้แต่ละ container อยู่ในพื้นที่ของตัวเองโดยไม่รบกวนกัน
App A / App B / App C
แอปในแต่ละ container
Container
แพ็กเฉพาะ library และ dependency ของแอป
Container Engine
Docker, containerd จัดการ lifecycle
Host OS
Linux kernel ที่แชร์ร่วมกันทุก container
Hardware
เครื่อง server จริงที่อยู่ล่างสุด
เปรียบเทียบ VM กับ Container แบบตรงๆ
ตารางด้านล่างสรุปความต่างในมิติสำคัญ ไม่มีฝ่ายไหนชนะทุกมิติ แต่ละอันมีจุดแข็งและจุดอ่อนต่างกัน
| มิติ | Virtual Machine | Container |
|---|---|---|
| ขนาด | หลาย GB ต่อ VM (รวม Guest OS) | หลาย MB ต่อ Container (แค่ app + deps) |
| ความเร็วในการเริ่มต้น | หลายนาที (ต้องบูต OS) | วินาที (แชร์ kernel อยู่แล้ว) |
| การใช้ทรัพยากร | สูง — แต่ละ VM จอง RAM/CPU แยก | ต่ำ — แชร์ kernel รัน container ได้มากกว่า |
| Isolation | แข็งแกร่งมาก — แยก hardware เสมือน | ดี — แยก process/network แต่แชร์ kernel |
| ความปลอดภัย | สูงกว่า — escape จาก VM ยากมาก | ดี แต่ kernel vulnerability กระทบทุก container |
| Portability | ย้ายได้แต่ image ใหญ่ ช้า | ย้ายได้เร็ว image เล็ก push/pull สะดวก |
| OS ที่รองรับ | ใช้ Guest OS ใดก็ได้ (Windows บน Linux ได้) | ต้องเป็น OS เดียวกับ host kernel |
ควรใช้ VM เมื่อไหร่
VM ยังคงมีบทบาทสำคัญในหลายสถานการณ์ โดยเฉพาะเมื่อต้องการ isolation ระดับสูงหรือต้องรัน OS ที่แตกต่างกัน
- ต้องการรัน Windows application บน Linux server (ต่าง kernel)
- ระบบที่ต้องการ security isolation ระดับสูง เช่น banking, government
- ทดสอบ OS configurations หรือ kernel-level features
- Legacy application ที่ต้องการ OS เฉพาะเวอร์ชัน
- สภาพแวดล้อมที่ต้องการ hardware virtualization เต็มรูปแบบ
ควรใช้ Container เมื่อไหร่
Container เหมาะกับงาน modern application development ที่เน้นความเร็ว ความยืดหยุ่น และการ scale
- Microservices — แต่ละ service รันในแต่ละ container แยกกัน
- CI/CD pipeline — build, test, deploy เร็วและสม่ำเสมอ
- Development environment — ทีมใช้ environment เดียวกันผ่าน Docker
- Cloud-native application ที่ต้อง scale ขึ้นลงตามโหลด
- แอปที่ต้องการ deploy บ่อย หรือมีหลาย version พร้อมกัน
ทำไม Container ถึงนิยมในยุค DevOps และ Cloud
ยุค DevOps ต้องการ deploy เร็ว ทดสอบบ่อย และ scale ได้ทันที VM ทำได้แต่หนักเกินไป Container เข้ามาตอบโจทย์ตรงนี้ได้พอดี การที่ Container ใช้ทรัพยากรน้อย เริ่มได้เร็ว และ image เล็กทำให้รัน container ได้หลายสิบหรือหลายร้อยตัวบนเครื่องเดียวได้อย่างมีประสิทธิภาพ ประกอบกับ Docker Hub และ container registry ต่างๆ ทำให้แชร์และแจกจ่าย image ได้ง่าย และ Kubernetes ก็ถูกสร้างมาเพื่อ orchestrate container โดยเฉพาะ ทำให้ ecosystem ทั้งหมดเชื่อมกันได้ลงตัว
- Deploy ไว — container เริ่มเป็นวินาที ไม่ต้องรอบูต OS
- Scale ได้ง่าย — Kubernetes จัดการ container หลายร้อยตัวโดยอัตโนมัติ
- Consistent environment — Dev, Staging, Production ใช้ image เดียวกัน
สรุปบทนี้
Container ไม่ได้แทนที่ VM แต่เป็นเครื่องมือคนละชั้นสำหรับปัญหาคนละแบบ