Docker

ช่วงหลังเราได้ยินชื่ออย่าง Docker, Container, Kubernetes, Orchestration กันบ่อยขึ้นมาก โดย Blognone เองก็เคยนำเสนอข่าวในหัวข้อเหล่านี้อยู่บ่อยครั้ง แต่ก็ยังมีความสับสนในเรื่องนี้อยู่มาก เพราะเป็นแนวคิดที่ยังค่อนข้างใหม่และมีความแตกต่างจากระบบเซิร์ฟเวอร์แบบเดิมๆ สูง

บทความชุดนี้จึงมีเป้าหมายเพื่ออธิบายและทำความเข้าใจกับแนวคิดเหล่านี้ ใครที่รู้เรื่องนี้ดีอยู่แล้วสามารถข้ามไปได้เลยครับ

ภาพโดย Chanaka จาก Pexels

Virtualization มีข้อจำกัด

คำว่า "คอนเทนเนอร์" (container) เป็นเทคนิคการจัดการแพ็กเกจซอฟต์แวร์ประเภทหนึ่ง ที่มีความสัมพันธ์กับเทคนิค virtualization ที่อยู่ในโลกองค์กรมานาน ดังนั้นการอธิบายว่าคอนเทนเนอร์คืออะไร จึงมักถูกเปรียบเทียบว่าแตกต่างกับ virtualization อย่างไร

เทคนิค virtualization คือการสร้างคอมพิวเตอร์เสมือน (virtual machine หรือ VM) ที่มีทั้งซีพียู แรม สตอเรจ ระบบปฏิบัติการ ฯลฯ ขึ้นมารันบนคอมพิวเตอร์จริงๆ อีกทีหนึ่ง โดยตัวระบบปฏิบัติการของคอมพิวเตอร์เสมือน (Guest OS) จะไม่รู้ว่าตัวเองรันอยู่บน VM แต่เข้าใจว่ารันอยู่บนฮาร์ดแวร์คอมพิวเตอร์จริงๆ

วิธีการนี้ทำให้เกิดการแยกส่วน (isolation) ระหว่าง VM แต่ละตัวอย่างสมบูรณ์ สามารถรันระบบปฏิบัติการที่แตกต่างกันระหว่าง Guest OS กับ Host OS ได้ แต่ข้อเสียคือใช้ทรัพยากรซ้ำซ้อน ทำงานช้า เปลืองพื้นที่เก็บ OS และซอฟต์แวร์ต่างๆ ที่มักจะใช้เหมือนกันใน VM ทุกตัว

ภาพประกอบจาก Docker

Container สร้างมาเพื่อแก้ไขข้อจำกัดของ Virtualization

คอนเทนเนอร์จึงถูกสร้างขึ้นมาเพื่อแก้ปัญหาข้างต้น โดยมีฮาร์ดแวร์และ OS เพียงชุดเดียวกัน ลดความซ้ำซ้อนของการใช้ทรัพยากรลง ส่วนตัวแอพพลิเคชันและซอฟต์แวร์ซึ่งเป็นจุดที่แตกต่างกันไปก็จะมี "container" (เทียบได้กับ VM) มาครอบเพื่อแบ่งส่วนทรัพยากรไว้ไม่ให้ยุ่งกัน

จุดเด่นของคอนเทนเนอร์จึงเป็นเรื่องการใช้ทรัพยากรที่น้อยกว่า virtualization มาก อิมเมจของคอนเทนเนอร์อาจมีขนาดเพียงกี่ไม่กี่สิบ MB ในขณะที่อิมเมจของ VM ต้องใช้พื้นที่ระดับหลาย GB นอกจากนี้ ระยะเวลาที่ใช้บูต, พลังซีพียูและปริมาณแรมที่ต้องใช้ ก็ลดลงตามไปด้วย ส่งผลให้เซิร์ฟเวอร์หนึ่งเครื่องสามารถยัดคอนเทนเนอร์จำนวนมากกว่าการรัน VM ที่ให้ผลแบบเดียวกันถึง 2-3 เท่าตัว

บางครั้ง คอนเทนเนอร์ถูกเรียกชื่อในทางเทคนิคว่า Operating-system-level virtualization หรือการสร้าง VM ที่ระดับ OS โดยเราไม่ต้องสร้างเครื่องคอมพิวเตอร์เสมือนขึ้นมาทั้งตัว

ข้อเสียของคอนเทนเนอร์ก็ย่อมเป็นความยืดหยุ่นที่น้อยกว่า virtualization แบบดั้งเดิม โดยเฉพาะไม่สามารถใช้ OS ที่แตกต่างกันระหว่าง Guest และ Host ได้ (เพราะจุดเด่นของคอนเทนเนอร์คือการแชร์ OS ก็อปปี้เดียวกัน)

ภาพจาก Docker

ประวัติย่อของ Container

แนวคิดของคอนเทนเนอร์ไม่ใช่เรื่องใหม่ ในโลกของยูนิกซ์เกิดแนวคิดนี้ขึ้นมาตั้งแต่ปี 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

ตัวอย่างการใช้งาน Container

รูปแบบการนำคอนเทนเนอร์ไปใช้งานมีหลากหลาย แต่ที่พบบ่อยคือการนำแอพพลิเคชันองค์กรในแบบเดิมๆ (ซึ่งมักเป็นแอพที่เขียนด้วยเทคโนโลยียุคก่อนอย่าง Java, .NET หรือ PHP) มาใส่ไว้ในคอนเทนเนอร์ เพื่อมารันบนโครงสร้างพื้นฐานยุคใหม่ที่เป็นคลาวด์ แทนที่การใช้เซิร์ฟเวอร์แบบดั้งเดิมที่เริ่มล้าสมัย ช่วยให้การย้ายขึ้นคลาวด์ราบรื่นกว่าเดิม

นอกจากนี้ เทคโนโลยีคอนเทนเนอร์ยังช่วยแก้ปัญหาเรื่อง system dependency ระหว่างแอพแต่ละเวอร์ชัน แต่ละสถานะ (เช่น dev/test/production) เพราะทุกอย่างที่จำเป็นถูกรวมมาในอิมเมจให้หมดแล้ว มันจึงมีประโยชน์ในแง่กระบวนการเปลี่ยนโค้ดที่เขียน ไปสู่การดีพลอยใช้งานจริงบนเซิร์ฟเวอร์ปลายทาง หรือที่เราเรียกกันว่า CI/CD อีกด้วย

การใช้งานคอนเทนเนอร์อีกแบบหนึ่งที่พบบ่อยในช่วงหลัง คือการแยกแอพพลิเคชันยุคเดิมที่เขียนมาเป็นก้อนใหญ่ๆ (monolithic) ให้กลายเป็นไมโครเซอร์วิส (microservice) ที่มีขนาดเล็กลง จัดการได้สะดวกขึ้น สามารถสเกลเซอร์วิสบางตัวหากต้องการรับโหลดมากขึ้น

การนำคอนเทนเนอร์ของแอพพลิเคชันที่แยกเป็นไมโครเซอร์วิส ไปรันบนโครงสร้างพื้นฐานยุคคลาวด์ที่สเกลตัวเองได้ง่ายขึ้น จึงมีความซับซ้อนสูงตามไปด้วย และกลายเป็นหน้าที่ของซอฟต์แวร์ที่เรียกว่า orchestration (เหมือนวาทยากรนำวงออเคสตร้า) อย่าง Kubernetes หรือ Apache Mesos ที่จะกล่าวถึงในบทความตอนต่อไป

ข้อมูลอ้างอิงจาก

Hiring! บริษัทที่น่าสนใจ

Carmen Software company cover
Carmen Software
Hotel Financial Solutions
Next Innovation (Thailand) Co., Ltd. company cover
Next Innovation (Thailand) Co., Ltd.
We are web design with consulting & engineering services driven the future stronger and flexibility.
KKP Dime company cover
KKP Dime
KKP Dime บริษัทในเครือเกียรตินาคินภัทร
Kiatnakin Phatra Financial Group company cover
Kiatnakin Phatra Financial Group
Financial Service
Fastwork Technologies company cover
Fastwork Technologies
Fastwork.co เว็บไซต์ที่รวบรวม ฟรีแลนซ์ มืออาชีพจากหลากหลายสายงานไว้ในที่เดียวกัน
Thoughtworks Thailand company cover
Thoughtworks Thailand
Thoughtworks เป็นบริษัทที่ปรึกษาด้านเทคโนโยลีระดับโลกที่คว้า Great Place to Work 3 ปีซ้อน
Iron Software company cover
Iron Software
Iron Software is an American company providing a suite of .NET libraries by engineer for engineers.
CLEVERSE company cover
CLEVERSE
Cleverse is a Venture Builder. Our team builds several tech companies.
Nipa Cloud company cover
Nipa Cloud
#1 OpenStack cloud provider in Thailand with our own data center and software platform.
Bangmod Enterprise company cover
Bangmod Enterprise
The leader in Cloud Server and Hosting in Thailand.
CIMB THAI Bank company cover
CIMB THAI Bank
MOVING FORWARD WITH YOU - CIMB is the leading ASEAN Bank
Bangkok Bank company cover
Bangkok Bank
Bangkok Bank is one of Southeast Asia's largest regional banks, a market leader in business banking
MuvMi (Urban Mobility Tech Co.,Ltd.) company cover
MuvMi (Urban Mobility Tech Co.,Ltd.)
Shape the future of urban mobility towards affordable, clean, and safe solutions
T.N. Digital Solution Co., Ltd. company cover
T.N. Digital Solution Co., Ltd.
TNDS has been involving in every first move of banking’s major digital transformation.
KBTG - KASIKORN Business-Technology Group company cover
KBTG - KASIKORN Business-Technology Group
KBTG - "The Technology Company for Digital Business Innovation"
Siam Commercial Bank Public Company Limited company cover
Siam Commercial Bank Public Company Limited
"Let's start a brighter career future together"
Icon Framework co.,Ltd. company cover
Icon Framework co.,Ltd.
Global Standard Platform for Real Estate แพลตฟอร์มสำหรับธุรกิจอสังหาริมทรัพย์ครบวงจร มาตรฐานระดับโลก
REFINITIV company cover
REFINITIV
The Financial and Risk business of Thomson Reuters is now Refinitiv
H LAB company cover
H LAB
Re-engineering healthcare systems through intelligent platforms and system design.
The Gang Technology Co., Ltd. company cover
The Gang Technology Co., Ltd.
We're a Digital Agency that helps our customers transform their business into digital with ease.
LTMH company cover
LTMH
LTMH มุ่งเน้นการพัฒนาผลิตภัณฑ์ที่สามารถช่วยพันธมิตรของเราให้บรรลุเป้าหมาย
Seven Peaks company cover
Seven Peaks
We Drive Digital Transformation
Wisesight (Thailand) Co., Ltd. company cover
Wisesight (Thailand) Co., Ltd.
The Best Choice For Handling Social Media · High Expertise in Social Data · Most Advanced and Secure
MOLOG Tech company cover
MOLOG Tech
We are Modern Logistic Platform, Specialize in WMS, OMS and TMS.
Data Wow Co.,Ltd company cover
Data Wow Co.,Ltd
We enable our clients to realize increased productivity by solving their most complex issues by Data
LINE Company Thailand company cover
LINE Company Thailand
LINE, the world's hottest mobile messaging platform, offers free text and voice messaging + Call
LINE MAN Wongnai company cover
LINE MAN Wongnai
Join our journey to becoming No.1 food platform in Thailand

ผมสงสัยคำนี้ครับ
"ข้อเสียของคอนเทนเนอร์ก็ย่อมเป็นความยืดหยุ่นที่น้อยกว่า 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

ถ้าเป็นของ Mac มันจะรัน VM แล้วค่อยรัน docker บนนั้นอีกรอบครับ (สังเกตว่าจะ refer ไปที่ port ของ host machine ตรงๆ ไม่ได้ ต้องผ่าน url พิเศษ​)
เข้าใจว่าของ Windows ก็จะใช้เทคนิคเดียวกันครับ

เทคนิคเดียวกันหมดครับ ไม่ว่าจะอีกกี่ OS ก็ตาม เพราะข้อจำกัดหลักของ Container คือต้องทำงานบน Linux Kernel เท่านั้น ดังนั้นทางเดียวที่จะรันบน Host อื่นได้คือต้องเอา Linux มาแทรกกลาง และปัจจุบันนอกจากการรัน VM แล้วก็ไม่มีวิธีอื่นครับ

สร้าง 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 ก็ใช้ในกลุ่มช่างซะส่วนมาก

มันใช้งานจริงได้เยอะครับ ผมเข้าใจว่า 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 ที่จะต้องหาก่อนว่าโปรแกรมพังจากอะไร (และมักจะหาไม่เจอ ฮา)

    container จริง ๆ ก็คือ process ปรกติตามธรรมดาไม่อะไรพิเศษไปกว่า process ปรกติครับ (โดยลองใช้ docker run -d nginx เสร็จแล้วลอง docker ps และ ps ax เทียบกันก็จะเห็น process ngixn ปรากฎขึ้นมา) เพียงแต่อาศัยความสามารถของ os kernel ในการจำกัดไม่ให้ process ใช้งานได้เพียง 2 ส่วนคือ  1. การแยกส่วน I/O ต่าง ๆ พวก file system, network resource และอื่น ๆ ไม่ให้ติดต่อกับ real resource  โดยตรง แต่ให้ติดต่อกับ function พิเศษที่จะ redirect os call ไปหา virtual resource ที่เตรียมไว้ครับ จึงทำให้เสมือนกับว่า container ทำงานโดยที่ไม่เกี่ยวข้องกับระบบจริง ๆ 2. จำกัดการใช้งาน resource ให้ตามที่กำหนดไว้ตั้งแต่ตอนเริ่ม process ทำให้ process ตัวนี้ไม่สามารถจะ consume resource ได้เกินกว่าที่กำหนดไว้ 
    ฉะนั้นเอาจริง ๆ แล้ว container ก็คือ process ที่ถูกจำกัดการเรียก os call ไว้แค่นั้นเอง นอกนั้นก็ยังเป็น process ตามปรกติ ซึ่งจะไม่เหมือนกับ VM คือพวกนั้นจะแยก process ต่างหากสำหรับ VM และเมื่อมีการสร้าง process จะก็ถูกจำกัดให้อยู่ภายใต้ VM ซึ่งพวกนี้นั้นจะต้องอาศัยความสามารถของ processor เป็นหลักครับ ให้สามารถสร้าง os เสมือนให้ทำงานได้ถ้า processor ไม่ support ก็จะใช้ VM ไม่ได้ ส่วน container นั้นต้อง อาศัย kernel ของ OS เป็นหลัก (ซึ่งจุดนี้เองทำให้ container มี dependency ติดกับ os) ถ้าไม่ support ก็ใช้ได้ไม่
    ซึ่ง ณ ปัจจุบัน os kernel ที่ support function พวกนี้คือ linux ครับ ส่วน kernel ของ windows นั้น เพิ่งจะ support ที่ windows server 2016 (แต่ก็ไม่ใช่ว่าเราจะสามารถ shared container นั้นระหว่าง linux กับ windows ได้น่ะครับ) ดังนั้นการที่จะ run container บน windows หรือ macos ได้จึงต้องอาศัยตัวช่วยคือ สร้าง linux vm สักตัวหนึ่งขึ้นมา เพื่อให้ทำงานแทนในการสร้าง container ขึ้นมา 

ซึ่ง docker ตอนเริ่มต้นก็อาศัย virtualbox ในการสร้าง linux vm บนทั้ง windows และ macos โดยใช้ tool พวก docker tool box แต่ปัจจุบัน docker ใช้ HyperV บน windows และ HyperKit บน macos