ช่วงหลังเราได้ยินชื่ออย่าง Docker, Container, Kubernetes, Orchestration กันบ่อยขึ้นมาก โดย Blognone เองก็เคยนำเสนอข่าวในหัวข้อเหล่านี้อยู่บ่อยครั้ง แต่ก็ยังมีความสับสนในเรื่องนี้อยู่มาก เพราะเป็นแนวคิดที่ยังค่อนข้างใหม่และมีความแตกต่างจากระบบเซิร์ฟเวอร์แบบเดิมๆ สูง
บทความชุดนี้จึงมีเป้าหมายเพื่ออธิบายและทำความเข้าใจกับแนวคิดเหล่านี้ ใครที่รู้เรื่องนี้ดีอยู่แล้วสามารถข้ามไปได้เลยครับ
คำว่า "คอนเทนเนอร์" (container) เป็นเทคนิคการจัดการแพ็กเกจซอฟต์แวร์ประเภทหนึ่ง ที่มีความสัมพันธ์กับเทคนิค virtualization ที่อยู่ในโลกองค์กรมานาน ดังนั้นการอธิบายว่าคอนเทนเนอร์คืออะไร จึงมักถูกเปรียบเทียบว่าแตกต่างกับ virtualization อย่างไร
เทคนิค virtualization คือการสร้างคอมพิวเตอร์เสมือน (virtual machine หรือ VM) ที่มีทั้งซีพียู แรม สตอเรจ ระบบปฏิบัติการ ฯลฯ ขึ้นมารันบนคอมพิวเตอร์จริงๆ อีกทีหนึ่ง โดยตัวระบบปฏิบัติการของคอมพิวเตอร์เสมือน (Guest OS) จะไม่รู้ว่าตัวเองรันอยู่บน VM แต่เข้าใจว่ารันอยู่บนฮาร์ดแวร์คอมพิวเตอร์จริงๆ
วิธีการนี้ทำให้เกิดการแยกส่วน (isolation) ระหว่าง VM แต่ละตัวอย่างสมบูรณ์ สามารถรันระบบปฏิบัติการที่แตกต่างกันระหว่าง Guest OS กับ Host OS ได้ แต่ข้อเสียคือใช้ทรัพยากรซ้ำซ้อน ทำงานช้า เปลืองพื้นที่เก็บ OS และซอฟต์แวร์ต่างๆ ที่มักจะใช้เหมือนกันใน VM ทุกตัว
ภาพประกอบจาก Docker
คอนเทนเนอร์จึงถูกสร้างขึ้นมาเพื่อแก้ปัญหาข้างต้น โดยมีฮาร์ดแวร์และ OS เพียงชุดเดียวกัน ลดความซ้ำซ้อนของการใช้ทรัพยากรลง ส่วนตัวแอพพลิเคชันและซอฟต์แวร์ซึ่งเป็นจุดที่แตกต่างกันไปก็จะมี "container" (เทียบได้กับ VM) มาครอบเพื่อแบ่งส่วนทรัพยากรไว้ไม่ให้ยุ่งกัน
จุดเด่นของคอนเทนเนอร์จึงเป็นเรื่องการใช้ทรัพยากรที่น้อยกว่า virtualization มาก อิมเมจของคอนเทนเนอร์อาจมีขนาดเพียงกี่ไม่กี่สิบ MB ในขณะที่อิมเมจของ VM ต้องใช้พื้นที่ระดับหลาย GB นอกจากนี้ ระยะเวลาที่ใช้บูต, พลังซีพียูและปริมาณแรมที่ต้องใช้ ก็ลดลงตามไปด้วย ส่งผลให้เซิร์ฟเวอร์หนึ่งเครื่องสามารถยัดคอนเทนเนอร์จำนวนมากกว่าการรัน VM ที่ให้ผลแบบเดียวกันถึง 2-3 เท่าตัว
บางครั้ง คอนเทนเนอร์ถูกเรียกชื่อในทางเทคนิคว่า Operating-system-level virtualization หรือการสร้าง VM ที่ระดับ OS โดยเราไม่ต้องสร้างเครื่องคอมพิวเตอร์เสมือนขึ้นมาทั้งตัว
ข้อเสียของคอนเทนเนอร์ก็ย่อมเป็นความยืดหยุ่นที่น้อยกว่า virtualization แบบดั้งเดิม โดยเฉพาะไม่สามารถใช้ OS ที่แตกต่างกันระหว่าง Guest และ Host ได้ (เพราะจุดเด่นของคอนเทนเนอร์คือการแชร์ OS ก็อปปี้เดียวกัน)
ภาพจาก Docker
แนวคิดของคอนเทนเนอร์ไม่ใช่เรื่องใหม่ ในโลกของยูนิกซ์เกิดแนวคิดนี้ขึ้นมาตั้งแต่ปี 2000 จากแนวคิด jails ของ FreeBSD จากนั้นในปี 2004 ระบบปฏิบัติการ Solaris ของบริษัท Sun Microsystems ก็มีฟีเจอร์แบบเดียวกันโดยใช้ชื่อว่า Zones (หรือ Solaris Containers) ฝั่งลินุกซ์เองก็นำไอเดียนี้มาสืบสานต่อในโครงการอย่าง OpenVZ หรือ LXC (Linux Containers)
แต่คอนเทนเนอร์กลายมาเป็นเรื่องแพร่หลายในวงกว้างจาก Docker ที่เริ่มต้นในปี 2013 ซึ่งช่วงแรกยังอิงอยู่บนโครงการยุคก่อนหน้าอย่าง LXC หรือ libvirt แต่ภายหลัง Docker ก็พัฒนาส่วนต่างๆ ขึ้นมาเอง (libcontainer) จนสมบูรณ์พร้อมใช้งาน ทำให้แนวคิดคอนเทนเนอร์ "จุดติด" และได้รับการยอมรับในวงการอย่างรวดเร็ว มีตัวอย่างการใช้งานจากบริษัทใหญ่ๆ อย่างกูเกิลที่พัฒนาฟีเจอร์ของ Google Compute Engine ให้รองรับอย่างรวดเร็ว
ถึงแม้ Docker จะถูกสร้างขึ้นมาเพื่อลินุกซ์ แต่ความนิยมของมันทำให้ระบบปฏิบัติการฝั่งวินโดวส์ ทำให้ไมโครซอฟท์เข้ามาร่วมวงตั้งแต่ปี 2014 และสำเร็จลุล่วงใน Windows Server 2016
ความสำเร็จของ Docker ทำให้เกิดคู่แข่งขึ้นบ้าง เช่น Rocket หรือ rkt ของบริษัท CoreOS (ปัจจุบันถูก Red Hat ซื้อไปแล้ว) ทำให้โลกคอนเทนเนอร์แยกออกเป็นสองส่วน แต่ภายหลังก็หาทางออกได้ ด้วยการออกมาตรฐานกลางภายใต้การดูแลของ Open Container Initiative (OCI) (ภายหลังยังพัฒนาต่อมาเป็นโครงการ containerd และ runc ซึ่งจะไม่กล่าวถึงในที่นี้)
ภาพจาก Docker
รูปแบบการนำคอนเทนเนอร์ไปใช้งานมีหลากหลาย แต่ที่พบบ่อยคือการนำแอพพลิเคชันองค์กรในแบบเดิมๆ (ซึ่งมักเป็นแอพที่เขียนด้วยเทคโนโลยียุคก่อนอย่าง Java, .NET หรือ PHP) มาใส่ไว้ในคอนเทนเนอร์ เพื่อมารันบนโครงสร้างพื้นฐานยุคใหม่ที่เป็นคลาวด์ แทนที่การใช้เซิร์ฟเวอร์แบบดั้งเดิมที่เริ่มล้าสมัย ช่วยให้การย้ายขึ้นคลาวด์ราบรื่นกว่าเดิม
นอกจากนี้ เทคโนโลยีคอนเทนเนอร์ยังช่วยแก้ปัญหาเรื่อง system dependency ระหว่างแอพแต่ละเวอร์ชัน แต่ละสถานะ (เช่น dev/test/production) เพราะทุกอย่างที่จำเป็นถูกรวมมาในอิมเมจให้หมดแล้ว มันจึงมีประโยชน์ในแง่กระบวนการเปลี่ยนโค้ดที่เขียน ไปสู่การดีพลอยใช้งานจริงบนเซิร์ฟเวอร์ปลายทาง หรือที่เราเรียกกันว่า CI/CD อีกด้วย
การใช้งานคอนเทนเนอร์อีกแบบหนึ่งที่พบบ่อยในช่วงหลัง คือการแยกแอพพลิเคชันยุคเดิมที่เขียนมาเป็นก้อนใหญ่ๆ (monolithic) ให้กลายเป็นไมโครเซอร์วิส (microservice) ที่มีขนาดเล็กลง จัดการได้สะดวกขึ้น สามารถสเกลเซอร์วิสบางตัวหากต้องการรับโหลดมากขึ้น
การนำคอนเทนเนอร์ของแอพพลิเคชันที่แยกเป็นไมโครเซอร์วิส ไปรันบนโครงสร้างพื้นฐานยุคคลาวด์ที่สเกลตัวเองได้ง่ายขึ้น จึงมีความซับซ้อนสูงตามไปด้วย และกลายเป็นหน้าที่ของซอฟต์แวร์ที่เรียกว่า orchestration (เหมือนวาทยากรนำวงออเคสตร้า) อย่าง Kubernetes หรือ Apache Mesos ที่จะกล่าวถึงในบทความตอนต่อไป
ข้อมูลอ้างอิงจาก
Comments
Blognone jobs ใช้แล้วนะครับ ;)
ขอบคุณมากๆเลยครับ สำหรับบทความและความรู้ดีๆ
..: เรื่อยไป
ติดตามครับ
ทำให้ภาพชัดขึ้น...
ขอบคุณมากเลยครับ แล้วเรื่อง license นี่ยังคิดตามจำนวน Guest เหมือนเดิมใช่ไหมครับ
?
Docker, Container, Kubernetes, Orchestration มันคืออะไร? ใช้ยังไง?
ผมสงสัยคำนี้ครับ
"ข้อเสียของคอนเทนเนอร์ก็ย่อมเป็นความยืดหยุ่นที่น้อยกว่า virtualization แบบดั้งเดิม โดยเฉพาะไม่สามารถใช้ OS ที่แตกต่างกันระหว่าง Guest และ Host ได้ (เพราะจุดเด่นของคอนเทนเนอร์คือการแชร์ OS ก็อปปี้เดียวกัน)"
ปัจจุบันผมก็ run redhat container บน windows ได้น่ะครับ ขอ clarify ครับ
มันต้องมีตัวช่วยนิดหน่อยครับ หลักๆ คือบนวินโดวส์ต้องมีเคอร์เนลลินุกซ์ด้วย
Running Docker Linux containers on Windows requires a minimal Linux kernel and userland to host the container processes. This is exactly what the LinuxKit toolkit was designed for: creating secure, lean and portable Linux subsystems that can provide Linux container functionality as a component of a container platform.
Source
งงเหมือนกัน เพราะผมลง docker บน Mac ก็โหลด image ของ Ubuntu มาใช้งานได้?
ถ้าเป็นของ Mac มันจะรัน VM แล้วค่อยรัน docker บนนั้นอีกรอบครับ (สังเกตว่าจะ refer ไปที่ port ของ host machine ตรงๆ ไม่ได้ ต้องผ่าน url พิเศษ)
เข้าใจว่าของ Windows ก็จะใช้เทคนิคเดียวกันครับ
onedd.net
แล้วบนวินโดวส์ก็ก็เจอปัญหา Hyper-V ตีกับ Virtual Box ต้องเลือกอย่างใดอย่างหนึ่ง... เหอะ เหอะ
iPAtS
เทคนิคเดียวกันหมดครับ ไม่ว่าจะอีกกี่ OS ก็ตาม เพราะข้อจำกัดหลักของ Container คือต้องทำงานบน Linux Kernel เท่านั้น ดังนั้นทางเดียวที่จะรันบน Host อื่นได้คือต้องเอา Linux มาแทรกกลาง และปัจจุบันนอกจากการรัน VM แล้วก็ไม่มีวิธีอื่นครับ
ขอบคุณสำหรับบทความครับ
แต่ผมก็ยังงงกับ container อยู่ดี ไม่เข้าใจว่ามันทำงานยังไง เอาอะไรมาทำได้บ้าง
สร้าง Apache2 Container เชื่อมต่อกับ MySQL 5.5 Container
วันดีคืนดีอยากเปลี่ยนเป็น MySQL 8.0 ก็สามารถ new MySQL 8.0 ขึ้นมาอีกชิ้นนึงได้เลย จากนั้นก็ setting พร้อมกับ config Apache2 Container เดิมมาที่ MySQL 8.0 ได้ง่าย
สามารถ config Apache2 + PHP5.x ไว้แจกให้เพื่อนไปใช้ เพื่อให้สภาพแวดล้อมในการพัฒนาที่เหมือนกันแน่นอนได้ (ลดปัญหา ฉันใช้ xampp php5, เธอใช้ Appserv php7 แล้วรันฟังก์ชันเดียวกันทำไมทำงานไม่ได้ ประมาณนี้
ส่วนการติดตั้ง บน Windows ก็ลง Docker แล้วก็พิมพ์ command ตาม docs ตัวอย่าง แปปเดียวก็น่าจะใช้งานได้
การแบ่งสรรทรัพยากร ส่วนสนับสนุนที่ใช้งานร่วมกันได้อย่างพวกไลบรารี ไฟล์บางตัวที่เหมือนกันทุกอย่างให้กับแอปพลิเคชัน ไม่ต้องสร้างเครื่องจำลองใหม่ที่ทำงานซ้ำซ้อน เชื่องช้า และกินพื้นที่มาก ในขณะที่ Container เกือบจะรันใกล้ชิดกับตัว OS (Container แค่ควบคุมทรัพยากรให้กับแอปพลิเคชันที่รัน)
ผมมองว่า Container คือการรักษา Runtime Environment ของตัวโปรแกรมเราให้มีลักษณะเดิมไม่เปลี่ยน แม้ว่าจะไปรันอยู่บนเครื่องของ Developer, Server ที่รัน Linux Distro ไหนก็แล้วแต่, หรือแม้กระทั่งเครื่องของ QA เครื่องที่รัน Test และอื่น ๆ โดยที่ยังรันโปรแกรมอยู่บน OS ของระบบนั้น แทนที่จะต้อง Ship ตัว OS ไปด้วย
Runtime Environment ก็เป็นได้ตั้งแต่ Script Interpreter (Nodejs, PHP, และอื่น ๆ) Runtime (Java, .Net, Go), 3rd party library (C/C++) รวมถึงไฟล์คอนฟิกต่าง ๆ แม้แต่เน็ตเวิร์คพอร์ท ตัวโปรแกรมเราก็จะยังเห็นเป็นพอร์ตที่เราตั้งไว้
คือตัวโปรแกรมเราจะเห็น Resource ทั้งหมดเท่าที่จำเป็น และเท่าที่เราระบุไว้ อะไรที่มากกว่านั้นก็จะไม่เห็น และจะเห็นในรูปแบบเดียวกันหมด ไม่ว่าจะไปรันที่ไหน เป็นเสมือนโลกส่วนตัวของโปรแกรมนั้น
ซึ่งพอทุกอย่างมันอยู่ในสภาพปิดทั้งหมด ก็ทำให้เรา deploy ตัว Container ไปที่ไหนก็ได้ เพราะตัว container ไม่รับรู้ว่าโลกภายนอกเป็นอย่างไร มันจะทำงานกับสิ่งที่เราระบุไว้
อย่างเราก็ไม่ต้องมาคิดว่า เอ๊ะ คอนฟิกไฟล์อยู่ใน /var หรืออยู่ใน /etc/config เราระบุไปเลยว่าอยู่ใน /etc/config ซึ่งเราก็สร้างไฟล์นี้ใน location นี้ภายใน image file ตัวโปรแกรมเราก็จะไปอ่านจากตรงนี้ โดยที่ไฟล์นี้จะไม่มีอยู่จริงในเครื่อง host ที่มันทำงานอยู่
ความแตกต่างระหว่าง Container กับ VM ก็คือ VM มันต้องมี OS และต้อง Allocate Resource จำนวนนึงให้มันอย่างเด็ดขาด อย่าง VM จะระบุไปเลยว่า ขอ RAM 2GB นะ หรือขอ Disk 50GB ในกรณีของ Container เนี่ยก็จะเหมือนรันโปรแกรมอยู่ในเครื่อง Host ตามปรกติ
มองเห็นภาพแล้ว แต่ส่วนมากที่เห็นคุยๆกันก็ใช้งานในกลุ่มพัฒนาซะส่วนมาก
มันออกแบบมาโดยนักพัฒนาเพื่อนักพัฒนาครับ ลดปัญหาในการเซ็ต environment ในการพัฒนา
คนในวงการอื่นๆ โดนทั่วไปแล้วไม่มีเหตุผลอะไรจะต้องมาสัมผัสกับความซับซ้อนที่เพิ่มขึ้นนี้อ่ะครับ
โดยมากในระดับ end user ก็ได้ใช้งานจากแอพที่รันอยู่บนระบบ container โดยไม่รู้ตัวเยอะครับ
อย่างว่าอ่ะครับ เหมือนบอกว่า welding machine ก็ใช้ในกลุ่มช่างซะส่วนมาก
จริงๆ ก็ทำมาสำหรับ devops/infra/dev แหละครับ เพราะมันทำให้คนทำงานได้ต่อเนื่องขึ้น
onedd.net
มันใช้งานจริงได้เยอะครับ ผมเข้าใจว่า service หลายๆ อย่าง สไตล์ serverless อย่าง lambda ของ amazon ก็รันบน docker นะครับ
แล้วพวก ci/cd service ของ bitbucket มันก็รันบน docker เหมือนกัน
เพราะ ตัวมัน start เร็วกว่า vm เยอะ เลยสามารถ scale ได้ง่าย ไม่ต้องรอ vm boot
เพราะ Docker เกิดมาเพื่อ Microservice ตั้งแต่ต้นครับ และกลุ่มที่จะคุยเรื่องการทำ microservice มันก็มีไม่กี่สายงานหรอกครับ หลักๆคือ DevOps
เอาจริง ๆ Docker นี่ ทำให้ภาระ SCM ลดลงนะ นึกสภาพการดูแล Microservice โดยไม่ใช้ VM หรือ Container เลยนี่ SCM จะเป็นกลุ่มที่รับภาระหนักกว่าเพื่อน
ลำพัง Developer น่าจะอยากเขียนโค๊ดมากกว่า และก็มีข้ออ้างเวลามันพังว่า "ก็มันรันบนเครื่องผมได้นี่นา" อยู่แล้ว ถ้ามันพังก็เป็นภาระของ SCM ที่จะต้องหาก่อนว่าโปรแกรมพังจากอะไร (และมักจะหาไม่เจอ ฮา)
ยังไงของ Windows ก็ต้องรันบน Hyper-V อยู่ดีนิ ถ้าใช้บน Windows มันก็ไม่เป็น container เต็มตัวซินะ
แต่ก็รัน container host VM แค่ชุดเดียวแม้จะวาง container ไปหลายตัวไงครับ (ไม่ใช่ Windows Host นะ)
ผมเห็นคนรันบน WSL ได้นะ
ซึ่ง docker ตอนเริ่มต้นก็อาศัย virtualbox ในการสร้าง linux vm บนทั้ง windows และ macos โดยใช้ tool พวก docker tool box แต่ปัจจุบัน docker ใช้ HyperV บน windows และ HyperKit บน macos