Natcha Luang - Aroonchai

Trust me I'm Petdo

Bangkok, Thailand

[Docker] รู้จักกับ Docker และวิธีใช้งานเบื้องต้น

ในยุคที่ cloud เข้าถึงและจับต้องได้แล้วแบบนี้ การทำงานอะไรก็ง่ายดายและสะดวกรวดเร็วไปหมดทุกอย่าง แม้แต่การติดตั้ง server ซึ่งนักพัฒนาอย่างเรา ๆ ก็ไม่จำเป็นต้องปวดหัวกับการ setup ระบบอะไรให้ยุ่งยากมากมายอีกต่อไป เมื่อมี container ที่บรรจุสิ่งที่เราต้องการมาพร้อมแล้ว เพียงแต่ update application ที่เราพัฒนาใส่ลงไป container ก็พร้อมจะทำงานได้เลยทันที

ลองมาดูวิธีติดตั้งและใช้งานหนึ่งใน container ชื่อดังก้องโลกอย่าง Docker กันดีกว่าครับ

สารบัญ

Container คืออะไร?

ก่อนจะไปขั้นตอนการใช้งาน สิ่งที่เราต้องรู้ก็คือเทคโนโลยีที่เรากำลังจะใช้งานอยู่นี้มันคืออะไร? หลายคนอาจจะเพิ่งเคยได้ยินด้วยซ้ำสำหรับคำว่า container

พูดถึง container ถ้าจะเปรียบเทียบง่าย ๆ ให้นึกภาพตู้ container ที่อยู่ตามท่าเรือต่าง ๆ เริ่มแรกมันก็เป็นแค่ container เปล่า ๆ เท่านั้นยังไม่มีข้อมูลอะไร ทีนี้เราติดตั้ง OS ให้มัน จากนั้นติดตั้ง web server ลงไป เสร็จแล้วเขียน config ให้เริ่มการทำงานตามที่กำหนด แล้วก็ปิด container อัพโหลดขึ้นไปวางไว้บน cloud พร้อมที่จะรอให้คนเอามันไปใช้งาน

คนที่จะเอา container ไปใช้งาน ก็ไม่จำเป็นต้องรู้ว่าข้างใน container มันมีการทำงานเป็นอย่างไร รู้แค่ว่าต้องเชื่อมต่อกับ container ทางไหนหรือเมื่อ run container แล้วจะได้ผลลัพธ์เป็นอะไรออกมาเท่านั้น​ และในทางการดูแลรักษาระบบมันเป็นอะไรที่สะดวกสบายมาก ๆ การอัพเกรดระบบทั้งหมด สามารถเสร็จสิ้นได้ด้วยการ pull image มาลงแทนของเดิม และไม่ต้องสนใจเรื่อง dependency ต่าง ๆ เลยสักนิด เพราะมันเป็นภาระของผู้ deploy container ไปแล้ว

ที่สำคัญ container แต่ละตัวมันสามารถเอามา link กันได้อีกด้วย output ของ container ตัวนึงสามารถส่งมาเป็น input ให้กับอีก container นึงได้เลยผ่านการเชื่อมต่อด้วย TCP ธรรมดา ๆ นี้ล่ะ

ผมจะยกตัวอย่างการใช้งานจริงกับ container ให้ดูสักเคส เริ่มจากปัญหาคือผมมี server ที่ run ระบบที่ legacy มาก ๆ คือยังใช้งาน PHP 5.2 แถมเขียนด้วย old school style อีกต่างหาก ดังนั้นการย้ายระบบงานเดิมที่ไม่มีใครรู้ว่าทำงานยังไงไปยังระบบใหม่ เวอร์ชันใหม่แถมไม่มี test อีกต่างหาก นี้มันนรกชัด ๆ ระบบไม่สามารถ downtime ได้นานแถมการ migrate ยังไม่สามารถทำได้เนื่องจากติดปัญหาฐานข้อมูลที่ legacy อีกเช่นกัน (แถมผู้พัฒนายังไม่ยอมให้ใครเข้าไปช่วย migrate อีกต่างหาก) มีทางเดียวในเมื่อต้อง deploy server ขึ้นใหม่แต่เราไม่สามารถ (และไม่จำเป็น) ที่จะติดตั้ง PHP 5.2 ลงระบบใหม่ได้ (เรามีแพลนว่าจะใช้ 5.6 เป็น standard) ดังนั้นจึงเห็นว่าทางออกคือการ deploy PHP 5.2 ใน container จากนั้นก็ย้ายระบบเดิมเข้ามาทำงานใน container แทนซะ เรียบร้อยปัญหาถูกแก้ได้อย่างง่ายดาย

ถ้าเห็นภาพการทำงานของ container แล้วตามผมมาทางนี้เลยครับ ผมจะแนะนำให้คุณรู้จักกับ Docker หนึ่งใน container เทคโนโลยีระดับโลก (อิอิ)

ติดตั้ง Docker

เนื่องจากบทความเดิมตอนผมเขียนนั้นยังใช้ Ubuntu 14.04LTS Desktop เป็น OS หลัก แต่ในตอนนี้ผมได้ทดสอบติดตั้งบน Windows และ Mac ด้วยแล้วก็เลยเขียนแยกของแต่ละ OS ไว้ ต้องบอกว่าตอนนี้ Docker ติดตั้งได้ง่ายขึ้นมากกว่าเดิมเยอะแล้ว แต่ข้อจำกัดอันสำคัญก็คือยังต้องทำงานอยู่บน Linux เป็นหลัก ดังนั้นการติดตั้งบน Linux จึงทำงานได้เต็มประสิทธิภาพที่สุด ส่วนของ Windows และ Mac การทำงานยังต้องอาศัย VirtualBox เพื่อ run Linux อยู่ครับ

Mac และ Windows

การติดตั้ง Docker บน OS ทั้งสองตัวนี้ต้องติดตั้งผ่าน Docker Toolbox ก่อนอื่นให้ดาวน์โหลดจาก ลิงค์นี้ จากนั้นก็กดติดตั้งตามปกติได้เลย และเมื่อติดตั้งเสร็จเรียบร้อยแล้วจะมีโปรแกรมชื่อว่า Kitematic ด้วยเราสามารถล็อกอินบัญชี Docker Hub ได้ด้วย

ให้เปิด Kitematic ขึ้นมาโปรแกรจะ auto start VirtualBox ให้เราโดยอัตโนมัติครับ

Kitematic (beta)

ทีนี้เราสามารถเรียก CLI เพื่อใช้งานคำสั่ง Docker ได้โดยคลิกที่เมนู Docker CLI ด้านซ้ายล่าง

Docker CLI

Linux

การติดตั้ง Docker บน Linux จะผ่านคำสั่ง CLI ของแต่ละ distro และสำหรับ Ubuntu สามารถติดตั้งผ่านทาง apt-get ได้โดยเพิ่ม repository source ก่อน

$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ sudo /bin/sh -c 'echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" >> /etc/apt/source.list'
$ sudo apt-get update && sudo apt-get install docker-engine

รอจนเสร็จก็สามารถใช้งาน Docker บน Linux ได้แล้วครับ

Build container

ต่อมาเราจะทดลอง build container สำหรับ run Go กัน โดยที่ผมจะใช้ net/http เพื่อทำ server สำหรับ response "Hello, world!"

Pull image

จัดการ pull image สำหรับ Go ด้วยคำสั่ง

$ sudo docker pull golang:latest

คำสั่งนี้จะดาวน์โหลด image Linux ที่ติดตั้ง Go compiler เวอร์ชันล่าสุด สามารถดูเวอร์ชันอื่น ๆ ได้ที่ Docker Hub

เรียกดูรายการ image ทั้งหมดที่มีอยู่ในเครื่อง

$ sudo docker images

สร้าง Go project

สมมติตั้งชื่อ folder ว่า golang-docker ข้างในจะมีไฟล์อยู่ 2 ไฟล์ดังนี้

  • Dockerfile
  • main.go

main.go

package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(rw, "Hello, world!")
  })

  http.ListenAndServe(":8080", nil)
}

Dockerfile

FROM golang:latest

RUN mkdir -p /go/src/golang-docker
ADD . /go/src/golang-docker

WORKDIR /go/src/golang-docker

RUN go build -o /go/bin/golang-docker .
CMD ["/go/bin/golang-docker"]

คำสั่ง FROM golang:latest คือให้ใช้งาน image golang ที่มี tag เวอร์ชันว่า latest และคำสั่ง RUN สำหรับใช้ run Linux command ที่ตามหลังนั่นเองครับ

Deploy container

เราต้องทำการ deploy container จาก project เพื่อให้เป็น container ของเราเอง โดยใช้คำสั่ง

$ sudo docker build -t golang-docker .

ด้วยคำสั่งนี้จะทำให้ Docker เข้าไปอ่านไฟล์ Dockerfile และทำงานตามคำสั่งที่อยู่ข้างใน จากนั้นจะทำการสร้าง container ขึ้นมาชื่อว่า golang-docker ตามในคำสั่งด้านบน

ถ้าเราเรียกดู image ก็จะเห็นว่ามีรายการ image ที่เราสร้างไว้เมื่อสักครู่มาแล้ว

$ sudo docker images

ตัวอย่างผลลัพธ์

REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
golang-docker       latest              eca336a5d631        11 minutes ago

Run

สุดท้ายเราจะสั่ง run container ที่เราสร้างขึ้นเมื่อสักครู่ด้วยคำสั่ง

$ sudo docker -it --rm --publish 8080:8080 golang-docker

คำสั่งนี้จะสั่งรัน golang-docker และ map port 8080 ของ host เข้ากับ 8080 ของ container ครับ

และอย่างที่ได้ติดตั้งไว้ตอนต้นเมื่อเราสั่ง run container โปรแกรม Kitematic ก็จะแสดงรายการของ container ของเราแบบนี้

Kitematic - Container

Comments