– 7 มกรา 2558 –

เนื่องจาก blog นี้ ติดอันดับ 1 แต่ผมไม่ค่อยตั้งใจเขียน อยากให้ไปอ่านอันอื่นมากกว่านะครับ คำแนะนำของผมสำหรับคนที่สนใจ docker คือ ให้ download fedora ตัวล่าสุด แล้ว install cockpit แล้วลองเล่น เจ้า Docker ดูครับ เข้าใจง่าย แล้วก็ใช้งานง่ายมากๆครับ แต่ limited feature นะ

(นิยามนี้คิดขึ้นมาเอง) Docker เป็นโปรแกรมที่ช่วยจำลอง environment ที่เรากำหนด ไปรันทำงานอยู่บน Linux ตัวไหนก็ได้ที่รองรับ docker ! แปลเป็นภาษาคนได้ว่ามันเป็น Virtual Machine นี่แหละ แต่ความแตกต่างของ Docker กับ VM (KVM,Xen,VMware,Virtualbox) ก็คือมันทำงานอยู่บน container ที่มีชื่อเรียกว่า LXC ซึ่งเป็น VM แบบ OS-Level นั่นเอง ถ้าใครรู้จัก Solaris Zones/Container, FreeBSD Jails, OpenVZ, Virtuozzo, WPAR มันคือพวกเดียวกันนี่แหละครับ ซึ่ง Docker เองเค้าก็บอกว่าตัวเค้าเนี่ยไม่ได้ผูกกับ LXC แค่ตัวเดียวนะ แต่ในอนาคตก็ยังจะขยายไปยัง VM แบบอื่นๆด้วย

การทำงานกับ Docker นั้นให้คิดว่ามันเป็น VM ที่มี snapshot ที่จะ Rollback กลับมาจุดเริ่มต้นทุกครั้ง หากเราไม่ commit แค่ประโยคนี้ก็งงแล้วใช่มั้ยละครับ เอาให้งงไปอีกก็ คิดซะว่ามันเป็น service แบบ stateless ไม่จดจำอะไรทั้งสิ้นถ้าเราไม่บอกมัน ผมขอข้ามการ install ไปเลยละกันเนื่องจากมันแค่ apt-get install docker.io / yum install docker เท่านั้นเอง

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

เราจะเริ่มจากการโหลด image จาก repository กลางลงมาในเครื่องด้วยคำสั่ง

docker pull ubuntu

ซึ่งจะเป็นการ download repository ที่มีชื่อว่า ubuntu ลงมาทั้งหมด หากต้องการใส่ version ก็ให้ต่อท้ายไปว่า ubuntu:14.04

หลังจากนั้นถ้ารัน docker images ก็จะเป็นการแสดง image ทั้งหมดที่เรามี

images

การทำงานกับ docker สามารถใช้ image ID หรือ ชื่อของ image ก็ได้

เราลองมารัน docker แบบให้เข้าใจกันเลย

snapshot

คำสั่งแรกคือผมทำการรัน image “c4ff…” นี้ขึ้นมา แล้วส่งคำสั่ง echo “hello” > hello.txt; cat hello.txt ได้ผลลัพธ์ว่า hello ซึ่งถูกต้อง แต่พอผมรัน cat hello.txt กลายเป็นว่าหาไฟล์ไม่เจอ เพราะว่าอะไร?

ทุกๆครั้งที่เรารันคำสั่ง docker run มันจะป็นการสร้าง container (vm) ขึ้นมาใหม่จาก image (snapshot) ที่เรามีอยู่

ps-a

จะเห็นได้ว่าผมรันซ้ำไปซ้ำมาเพื่อมาเขียน blog นี้ คำถามก็คือแล้วเราจะ save การเปลี่ยนแปลงนี้อย่างไร คำตอบก็คือเราต้อง commit การเปลี่ยนแปลงเหล่านี้ให้กลายเป็น image นั่นเอง

stop

จะเห็นได้ว่าผมยังไม่เข้าใจ docker ขนาดผม commit แล้วมันก็ยังหายไป 555 หรือมันรันได้คำสั่งเดียวก็รู้ เอาเป็นว่าช่างมันครับ ผมพาไปดู dockerfile ดีกว่าเข้าใจง่ายกว่าเยอะ

คิดซะว่า docker file นั้นเป็นตำราทำอาหาร อยากใช้หม้อรุ่นไหน ใส่น้ำเท่าไหร่ ใส่เครื่องอะไรบ้าง แล้วต้องเสริฟยังไง เราสามารถเขียนลงไปใน dockerfile ได้เลย แล้วเราก็นำตำรานี้ไปรันผ่าน docker แล้วก็จะได้ image มาหนึ่งตัว สามารถไปแจกจ่ายให้คนที่ต้องการใช้งานได้

# sshd
#
# VERSION               0.0.1

FROM     ubuntu:12.04
MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.com"

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' |chpasswd

EXPOSE 22
CMD    ["/usr/sbin/sshd", "-D"]

ไม่ต้องมี่คำอธิบายใดๆสำหรับ 4 – 5 บรรทัดแรก สองบรรทัดสุดท้ายทำหน้าที่ในการ map port 22 กับ port ของ host ที่จะถูกกำหนดให้เองตอนรัน container สมมุติมัน return มาเป็น port 4578 เราก็สามารถ ssh root@hostname -p 4578 ได้เลย

นอกจากการ map port แล้ว docker ก็ยังสามารถ map path ใน host ไปยัง container ได้อีกเช่นกัน ซึ่งทำให้การ run application นั้นทำได้ง่ายขึ้นมากไม่ต้อง scp code เข้าไป สามารถสั่ง compile จาก container และ run ได้เลย

ข้อเสียของ docker เท่าที่อ่านเจอคือถึงแม้จะมี private repository การ upload image ก็ยังใช้เวลานานมาก และปัญหาเรื่องของ filesytem AUFS ที่ช้ากว่าปกติ (ไม่แน่ใจว่าเปลี่ยนไปใช้ BTRFS จะไวขึ้นหรือไม่) การเชื่อมต่อระหว่าง container ด้วยกันก็ยังมีปัญหา ว่า restart แล้ว ip เปลี่ยนคุยกันไม่ได้ เป็นต้น (ไปตามอ่านดูได้ที่นี่ และ ที่นี่)

น่าจะพอเห็นภาพกันพอสมควรแล้วว่า docker มันไม่ได้ออกแบบมาไว้เพื่อการพัฒนาโปรแกรม แต่มันถูกออกแบบมาเพื่อรันโปรแกรม ใน environment ที่แตกต่างกันบน host เดียวกัน และไม่ควรมีความเกียวข้องซึ่งกันและกัน เช่น application A ต้องการ Ruby version 1.8.7 application B ต้องการ 1.9.3 การสร้าง container ขึ้นมาแล้วลง dependency ของแต่ละ application นั้นมีความปลอดภัยและเข้าใจได้ง่ายกว่าการลงทั้งหมดอยู่บน host เดียวกัน ซึ่งลักษณะการนำเอาไปใช้งานน่าจะคิดถึงพวก PaaS ไม่ว่าจะเป็น Heroku หรือ Openshift ก็ตาม น่าจะเหมาะกับการใช้ docker มากที่สุด ส่วน dev/admin ทั่วๆไปแบบผม ผมขอใช้ container ธรรมดาไปก่อนละกัน (ตอนนี้ใช้ OpenVZ กับ FreeBSD Jails บน production)