วิวัฒนาการของ Development Environment


       ก่อนอื่นขอเกริ่นก่อนเลยว่าเรื่องนี้เป็นเรื่องที่ผมอยากเขียนมาซักพักแล้วเหตุผลเพราะว่าเรื่องนี้เป็นเรื่องที่ส่งผลกระทบกับชีวิตผมในฐานะ Developer มากและผมสังเกตุเห็นได้ชัดเลยว่าโลกกำลังเปลี่ยนไปในบล็อกนี้ผมจะเล่าให้ฟังว่าคำว่า Development Environment มันเปลี่ยนแปลงไปอย่างไรตลอด หลายปีที่ผ่านมาตามที่ผมสังเกตุเห็น

       ในอดีตสมัยที่โลกยังไม่รู้จักคำว่า Virtualization การจะติดตั้งระบบอะไรซักอย่างหนึ่งจำเป็นต้องทำด้วยมือในเครื่องจริงๆ ลำดับการทำงานจะประมาณว่า ลงระบบปฏิบัติการ, ลงโปรแกรม, คอนฟิกให้มันทำงานได้ แล้วก็เสร็จหลังจากนี้จะเป็นการดูแลรักษาซึ่งถ้าโชคดีแก้ได้ก็รอดตัวไป แต่ถ้าเครื่องพังไม่ว่าด้วยเหตุผลอะไรก็ตาม สิ่งที่เกิดขึ้นตามมาก็คือ เราต้องมาทำลำดับข้างบนซ้ำใหม่อีกรอบ ซึ่งถ้าเป็นระบบที่มีความซับซ้อนมากๆ ต้องเสียเวลาไปไม่ใช่น้อยกับการที่ต้องมานั่งไล่ติดตั้งอะไรต่างๆ ลงในเครื่องให้ครบทุกอย่างจนเสร็จแถมยังไ่ม่รับประกันว่าจะใช้งานได้เหมือนก่อนหน้านี้รึเปล่า

       หลังจากนั้นพระเจ้า (จริงๆ ก็ไม่เชิงพระเจ้าหรอก) ก็ประทานสิ่งที่เรียกว่า Virtualization มาให้หรือระบบเสมือน พูดง่ายๆ ก็คือ เราสามารถสร้างระบบคอมพิวเตอร์อีกระบบหนึ่งแยกต่างหากอยู่ภายในเครื่องเราได้ นอกจากนั้นแล้วยังเก็บสำเนาหรือ box ไว้ได้เผื่อไว้ใช้ในกรณีทำอะไรซักอย่างจนเครื่องพังได้ ฟังดูดีใช่มั้ยครับ ข้อเสียอย่างเดียวของ Virtual Machine ก็คือ มันกินทรัพยากรเครื่องสูงมากเนื่องจากต้องรันอยู่บน VM ของตัวเองที่มีระบบปฏิบัติการเป็นของตัวเอง ถ้ามีหลายๆ เครื่องต้องทำงานพร้อมๆ กันแน่นอนครับว่าตัวเครื่อง Host ก็ต้องอืดไม่ทางใดก็ทางหนึ่ง แต่ถึงแม้จะมีข้อเสียขนาดนี้คนส่วนใหญ่ก็ยังคงใช้งานอยู่อย่างหลากหลาย โดยมีเจ้าใหญ่ๆ อยู่ 2 เจ้าคือ Virtualbox และ VMWare

http://www.vagrantup.com/
       ปัจจุบันแน่นอนว่าคนเราไม่ยอมทำอะไรซ้ำๆ หลายๆ รอบหรอกครับมันน่าเบื่อ สิ่งที่เกิดขึ้นตามมาเราเรียกกันว่า Provisioner พูดง่ายๆ ก็คือตัวจัดการ VM เหล่านี้ให้มันใช้ง่ายยิ่งขึ้น จากแต่ก่อนกว่าจะเปิด Virtualbox สร้างเครื่องขึ้นมา บูต Shell เข้าไปจัดการต้องคลิกตั้งไม่รู้กี่ที่ Provisioner จะเตรียม command ไว้ให้ในการทำสิ่งเหล่านี้แทบทั้งหมดนอกจากนั้นแล้วการตั้งค่าการทำงานต่างๆ ของเครื่อง VM นั้นจะถูกเก็บไว้ในไฟล์ๆ เดียวที่บางครั้งเราเรียกว่า Dotfile เพื่อสะดวกในการจัดการ ซึ่งถ้าใช้ร่วมกับ Version Control ด้วยแล้วนั้นจะยิ่งมีประสิทธิภาพมากขึ้นไปอีก โดยในปัจจุบันมี Provisioner อยู่หลากหลายเจ้าไม่ว่าจะเป็น Vagrant, Puppet, Chef แต่ผมจะพูดถึงแค่ Vagrant เพราะเคยใช้จริงๆ จังตัวนี้ตัวเดียว

       ใน Vagrant เมื่อเราทำการติดตั้งเสร็จแล้ว (ซึ่งไม่ยากเลยครับลง Virtualbox เสร็จแล้วลง Vagrant ตาม Installation Guide ง่ายๆ ก็เสร็จละ) เราจะได้กลุ่มของคำสั่งขึ้นมาชุดหนึ่ง ตามที่อยู่ข้างล่างนี้ สมมติผมต้องการจะสร้าง Ubuntu 12.04 64 bit เป็น VM ขึ้นมาเครื่องนึงสามารถทำได้โดย

1. สร้าง Vagrantfile ขึ้นมาโดยพิมพ์คำสั่ง vagrant init ใน directory ที่เราต้องการจะสร้างเครื่องนั้นโดยหน้าตาของ Vagrantfile จะประมาณภาพข้างล่างนี้


2. แก้ไข Vagrantfile ให้ใช้ box ที่เราต้องการโดยเปลี่ยนจาก base เป็น hashicorp/precise64 เสร็จแล้วทำการเซฟไฟล์

3. ใช้คำสั่ง vagrant up เพื่อสั่งให้ VM ทำงาน

       แค่ 3 ขั้นตอนง่ายๆ แค่นี้ก็ได้ VM หนึ่งเครื่องมาใช้งานโดยไม่ต้องเสียเวลาติดตั้ง OS ให้เสียเวลาเหมือนแต่ก่อนอีกแล้วครับ ถ้าอยากเข้าไปใช้งานเครื่องก็เพียงพิมพ์แค่ vagrant ssh เราก็จะเข้ามาอยู่ใน shell ของเครื่องดังกล่าวแล้วครับ นอกจากนั้นแล้วตัว Vagrant ยังทำการ map ตัว share folder พื้นฐานไว้ให้โดยจะอยู่ใน directory เดียวกับ Vagrantfile แต่ถ้ามองในเครื่อง VM จะอยู่ที่ /vagrant

       ไม่ใช่แค่ฝั่ง Infrastructure เท่านั้นนะครับที่ทุกอย่างเริ่มจะง่ายขึ้นทางฝั่ง Developer ในภาษาสมัยใหม่นั้นก็ไม่ต่างกันในแต่ละภาษาต่างก็มีระบบจัดการ package/module ที่ช่วยให้การทำงานแยก Environment ง่ายขึ้นไม่ว่าจะเป็น Virtualenv (Python) , RVM (Ruby) หรือ NPM (Node.JS) แต่ผมขอละรายละเอียดไว้แล้วกันถ้าสนใจไปหาอ่านเองได้ครับ เข้าใจไม่ยากหรอก
http://www.docker.com/
       ในอนาคตอันใกล้ทุกสิ่งมีเกิดก็ต้องมีดับ มีมาแล้วก็มีไปถึงแม้ว่า Provisioner จะทำให้เราใช้งาน VM ได้ง่ายขึ้นแต่ในขณะเดียวกันข้อจำกัดของ VM นั้นก็ยังมีอยู่คือกิน Resource เยอะมากเนื่องจากต้องขี่อยู่บน OS ของตัวเอง สิ่งที่โลกกำลังปรับตัวเข้าไปหาจากที่ผมสังเกตุเห็นและเจอกับตัวเองด้วยคือเรากำลังจะกลับไปหาความเร็วส์ ซึ่งสิ่งที่จะช่วยให้เราไปหาได้เราเรียกมันว่า Docker ครับ

       หน้าเว็บของ Docker นั้นอธิบายไว้ว่ามันคือ "An open platform for distributed applications for developer and sysadmins." แปลว่าอะไรก็พยายามทำความเข้าใจมันเองนะครับ เท่าที่ผมเข้าใจ Docker แก้ปัญหา Resource ที่ VM มีอยู่ได้อย่างมีประสิทธิภาพด้วยการย้ายจากการขี่อยู่บน OS ในเครื่อง VM อีกทีมาไว้บน OS บนเครื่อง Host โดยมี Docker layer คอยจัดการแยก Process หรือ Container เหล่านี้ไม่ให้มาทำอะไรเครื่อง Host ที่มันรันอยู่ได้ นอกจากนั้นแล้วอีกปัญหาหนึ่งที่ Docker แก้ปัญหาคือ Setup step ที่มีความซับซ้อนโดยใช้แนวคิดที่คล้ายกับ Provisioner (หรือบางคนก็มองว่ามันก็คือ Provisioner ด้วย) คือเก็บ Setup step ไว้ในไฟล์เดียวที่เราเรียกว่า Dockerfile ซึ่งหน้าตาประมาณข้างล่างนี้ ซึ่งก็เหมือนกับ Provisioner คือเราสามารถใช้ Version Control มาช่วยจัดการไฟล์พวกนี้ได้ทำให้เราทำงานได้อย่างมีประสิทธิภาพมากยิ่งขึ้น
ตัวอย่าง Dockerfile นี้เป็น Setup step ของ HHVM ครับ
       ก่อนที่จะไปลึกมากกว่านี้ต้องอธิบายเสริมอีกอย่างว่า สิ่งที่ Docker มองเห็นเครื่องนั้นมี 2 อย่างคือ Image และ Process ซึ่งสองอย่างนี้ไม่เหมือนกัน Image เราจะมองว่ามันเป็นฐานของ Process ที่สร้าง (build) ขึ้นมาจาก Dockerfile ซึ่งจากที่อธิบายไว้ในย่อหน้าที่แล้ว Dockerfile จะมี Step ในการบอกว่าเราจะติดตั้งอะไรไว้บ้างใน Image นี้ ในขณะที่ Process คือ สถานะของ Image ที่กำลังรันอยู่ซึ่งก็แบ่งเป็น 2 mode หลักๆ ที่ใช้บ่อยๆ คือ Interactive mode (-i) คืออยู่ในสถานะที่เราสั่งให้มันรันแล้วรันคำสั่งอะไรสักอย่างหนึ่งแล้วจบการทำงานมันก็จะลบตัวเองออกจากเครื่อง อีก mode หนึ่งคือ Daemon mode (-d) ใน Mode นี้ตัว Process ที่ถูกสร้างจะถูกสั่งให้รันใน Background โดยจะไม่ปิดตัวเองในทันที

ความแตกต่างระหว่าง Docker และ VM
ภาพจาก: http://www.docker.com/whatisdocker/
       เขียนมาตัั้ง 3 ย่อหน้ายังไม่เขียนวิธีใช้เลย จริงๆ แล้ว Docker ใช้ไม่ยากครับ แต่เข้าใจ Concept จริงๆ ของมันยากมาก (ในตอนแรก) แต่ถ้าเข้าใจแล้วจะสบายวิธีที่ง่ายที่สุดที่จะเข้าใจ Concept คือไปเล่น Docker tutorial ผมว่าน่าจะครอบคลุมการใช้งานพื้นฐานเกือบทั้งหมดแล้ว ในส่วนของการติดตั้งนั้นถ้าใช้ Ubuntu ก็ไม่ยากครับเพียงแค่ sudo apt-get install docker แต่ช้าก่อน... ผมได้เรียนรู้มาจากพี่ที่ผมรู้จักที่ทำงานเกี่ยวกับ Docker มาก่อนผมว่าถ้าลงด้วยวิธีนั้นเราจะไม่ได้ Docker เวอร์ชั่นล่าสุดมาใช้ (ถ้าคุณอยู่ใน Ubuntu 14.04 เหมือนผม) ซึ่งวิธีที่จะทำให้เราได้เวอร์ชั่นล่าสุดมาใช้งานนั้นก็เพียงลงตามวิธีของ Ubuntu 13.10 ตามลิงค์นี้ครับ https://docs.docker.com/installation/ubuntulinux/#ubuntu-raring-1304-and-saucy-1310-64-bit
     
       หลังจากนี้เป็นความเห็นส่วนตัวและบ่น ถ้าไม่อยากอ่านก็จบแต่เพียงเท่านี้ก็ได้ครับ เท่าที่ผมเห็นและได้ยินมาปัญหาหลักๆ ของการใช้ทั้ง Provisioner ต่างๆ รวมถึง Docker คือ มันมีท่าหลากหลายมากในการจะสร้าง Environment ขึ้นมาซักเครื่องไม่ว่าจะเป็นใช้ Vagrant สร้างแล้วสั่งให้ Chef ลง Package ที่จำเป็นหรือสั่ง Shell script ที่เราเตรียมไว้ หรือยัดทุกอย่างไว้ใน Dockerfile อย่างเดียว หรือจะใช้ Python หรือภาษา Script อื่นๆ ไปสั่งให้ Docker ทำงานในการสร้าง container ฯลฯ ก็ต้องคอยดูต่อไปครับว่าจะมีวิธีการหรือมาตรฐานอะไรที่จะออกมาแก้ปัญหาเหล่านี้หรือไม่ ก็หมดแล้วครับ จริงๆ มันมีเทคโนโลยีอีกหลายตัวที่เกี่ยวกับเรื่องพวกนี้ แต่ผมไม่รู้จักและไม่เคยผ่านตาใช้มาก่อนเลยขอไม่พูดถึงไว้ตรงนี้ละกันครับ แล้วค่อยเจอกันใหม่เอนทรี่หน้าสวัสดีครัชช

Further reading
http://www.vagrantup.com/
http://puppetlabs.com/
http://www.getchef.com/chef/
https://www.npmjs.org/
http://rvm.io/
https://pypi.python.org/pypi/virtualenv
http://www.docker.com/

Comments