EP2 Docker ทีเล่น ทีจริง

Supphachoke Suntiwichaya
NECTEC
Published in
5 min readSep 10, 2017

หวังว่าติดตั้ง Docker กันเรียบร้อยทุกคนแล้วนะครับ ว่าแล้วก็มาเริ่มกันแบบง่ายๆ ทีละขั้นๆ เปิด terminal ขึ้นมาโดยพลัน Windows ก็เรียก cmd มานะครับ

เพื่อให้คุ้นชินกับ command line คำสั่งแรกลองเลย

$ docker version 
docker version

ต่อไปนี้เวลาเราจะทำงานกับ Docker ต้องพิมพ์คำสั่ง docker แล้วตามด้วยสิ่งที่ต้องการใช้ เช่น docker version ก็เป็นการสั่งให้ docker แสดงข้อมูลของรุ่นที่ใช้อยู่ ลอง check ดูว่าเป็นรุ่นล่าสุดตามที่บอกในเว็บหรือเปล่า สำหรับคนใช้ linux อาจจะต้องใช้ sudo นำหน้า หรือ จะเป็น root ก่อน หรือ จะใช้ user ที่มี group ที่สามารถใช้ docker ได้ (ยิ่งอธิบายมือใหม่ยิ่งงง) ถ้าง่ายสุดก็

$ sudo su - 

เข้าเป็น root ตามคำสั่งด้านบนแต่ถ้าขยันก็ใช้

$ sudo docker version
Docker บน Ubuntu Linux

ทีนี้ถ้าเราอยากรู้ว่าคำสั่งต่างๆ มีอะไรบ้างก็แค่สั่ง

$ docker help

แล้วก็อ่านดูว่าแต่ละ option ทำอะไรบ้างในอนาคตจะได้นึกออกเวลาจะใข้งานจริงๆ

อย่างที่เกริ่นไว้ใน EP1 ว่าจะใช้ Docker จะต้องมี image ก่อนลองตรวจดูว่าในเครื่องเรามี image หรือยัง

$ docker images
docker images

ใครที่เพิ่งจะติดตั้ง docker แล้วมี image อยู่ก็ผีหลอกละครับ ฮาๆ งั้นเรามาลองดึง image แรกมาใช้กัน

ตัวอย่างผมจะดึงเอา image ชื่อ alpine ลงมาจาก server ของ docker (registry repo) alpine เป็น linux ตัวเล็กๆ ที่ถูกนำมาใช้ใน docker image อย่างแพร่หลาย ขนาดไม่กี่ MB เองครับ คำสั่งคือ docker pull

$ docker pull alpine
docker pull

การดึง image ทำได้สองแบบ แบบแรกก็เหมือนตัวอย่างคือ pull ลงมาก่อน แบบที่สองคือ สั่ง run เลยซึ่งจะพูดในหัวข้อต่อไป เมื่อเรา pull image มาเรียบร้อยเราลองตรวจสอบด้วยคำสั่ง docker images อีกครั้ง

$ docker images

คราวนี้เราก็จะเห็นมีรายการของ image ขึ้นมาหนึ่งรายกายคือ alpine นั่นเอง ซึ่งเราจะรู้ว่า image ของเรามีข้อมูลอะไรบ้างดังนี้

REPOSITORY       TAG       IMAGE ID        CREATED             SIZE

REPOSITORY คือ ที่เก็บ และ ชื่อของ image ถ้าเราดึงมาไว้ที่เครื่องเราแล้วก็จะมีเฉพาะชื่อเฉยๆ แต่ในกรณีที่เราอ้างไปยัง repository อื่นๆ เราอาจจะเห็นชื่อยาวๆ อยู่ข้างหน้าชื่อ image เช่น localhost:5000/mrchoke/caddy_laravel เป็นต้น

TAG คือตัวที่ระบุ tag ของ IMAGE ID ส่วนใหญ่จะระบุเป็น version หรือ ชื่ออื่นๆ ก็ได้ ถ้าไม่ระบุจะเป็น latest ใช้ร่วมกับชื่อ REPOSITORY เวลาสั่ง pull push rmi (ลบ) เช่น

$ docker pull alpine:3.6

IMAGE ID คือ Unique ID ของ image สามารถใช้ตอนสั่ง rmi เพื่อลบ image ได้เช่น

$ docker rmi 7328f6f8b418หรือ$ docker rmi alpine:latest

CREATED คือ วันที่สร้าง images อาจจะใช้เป็นตัวชี้วัดได้ถึงความทันสมัยของ image นั้นๆ นอกจากเราต้องการใช้ตัวที่มันไม่มีอัปเดทแล้วจริงๆ

SIZE คือขนาด ของ IMAGE บนเครื่องเรา อันนี้จะต่างกับที่แสดงบน hub.docker.com นะครับเพราะขนาดที่เห็นบน hub จะโดนบีบอัดแล้ว

เมื่อเรามี image แล้วคราวนี้เรามาใช้ image ที่มีอยู่ดูครับว่าเราจะใช้งานได้อย่างไรบ้าง

การใช้งาน docker image เบื้องต้น

คำสั่งที่จะแนะนำในส่วนนี้จะเป็นคำสั่งรวมๆ อาจจะไม่แยกทีละคำสั่งนะครับ แต่จะยกตัวอย่างแล้วอธิบายเอา

การใช้คำสั่งที่อยู่ใน image การใช้คำสั่งลักษณะนี้สามารถนำไปประยุกต์ใช้ในกรณีที่เราต้องการใช้คำสั่งที่ต้อง run เฉพาะบน linux รุ่นใดรุ่นหนึ่งที่ไม่ใช่ Linux ที่เราใช้อยู่ หรือ เราใช้ Mac หรือ Windows อยู่แต่ต้องการใช้คำสั่งที่อยู่บน Linux เราก็ใช้วิธีการนี้ได้ตัวอย่าง เช่น

$ docker run --rm alpine ip addr show eth0

จากตัวอย่างจะมี 5 ส่วน คือ

  1. คำสั่ง docker
  2. command คือ run คำสั่ง run จะเป็นการนำ image มาใช้งานเรียกว่า container
  3. command option คือ --rm ในที่นี่ต้องการให้หลังจาก run เสร็จแล้วให้ลบ container ทิ้งด้วย ซึ่งถ้าเราไม่ใส่ option นี้ container ก็จะค้างอยู่เรื่อยๆ
  4. image ตรงนี้ image ชื่อว่า alpine ถ้าไม่ระบุ tag ก็จะใช้ latest โดยอัตโนมัติ ถ้า docker หา image ที่เราระบุบนเครื่องไม่เจอก็จะไปถามบน docker hub ถ้าเจอก็จะดึงลงมาให้ แต่ถ้าเรา pull มาก่อนก็จะนำมาใช้ได้ทันที
  5. คือคำสั่งที่จะ run ใน container ในตัวอย่างจะ run คำสั่ง ip addr คือแสดง ip ของ container นั่นเอง

จากในรูปตัวอย่างจะเห็นความแตกต่างระหว่างมีและไม่มี --rm ซึ่งจะมีคำสั่งใหม่เพิ่มขึ้นมาคือ

$ docker ps -a

docker ps ใช้สำหรับดู container ที่เราสร้างไว้ ถ้า มี -a คือ ดูทั้งหมดทั้งที่ stop อยู่ และ ทำงานอยู่ ถ้าไม่มี -a ก็จะแสดงเฉพาะที่กำลังทำงานอยู่ ในตัวอย่างผมใช้ -a เพราะเมื่อเราสั่งคำสั่ง ip addr show eth0 เสร็จมันก็จะ exit ทันทีนั่นเอง

และ อีกคำสั่งคือการลบ container ด้วยคำสั่ง

$ docker rm container-id หรือ container-name

การลบนั้นไม่ยุ่งยากแต่ให้จำว่าถ้าเราลบ container ที่ stop อยู่ หรือ สถานะเป็น exit เราสามารถลบได้เลย แต่ก็สามารถบังคับลบ โดยใช้ option -f ได้เช่นกันแต่ก็ไม่แนะนำเท่าไหร่เพราะอาจจะทำให้เราลบพลาดไปโดน container ที่กำลังใช้งานจริงๆ อยู่

$ docker stop abc$ docker rm abc$ docker rm -f def

การ run แบบ background

ก่อนหน้านี้เป็นการ run แบบทีเดียวจบ แต่ถ้าเรานำไปใช้งานเป็น service จริงๆ ส่วนใหญ่จะใช้ลักษณะ run ค้างไว้ หรือ run แบบ background

ตัวอย่างที่จับต้องได้คงหนีไม่พ้นการยกตัวอย่าง nginx ลองสั่งตามดังนี้ครับ

$ docker run -d -p 8000:80 --name web nginx

หลังจากนั้นก็ลองเข้าเว็บทาง web browser หรือคำสั่ง curl ก็ได้

$ curl http://localhost:8000

ถ้าไม่มีอะไรผิดพลาดเราก็จะได้หน้าต้อนรับของ nginx ขึ้นมา ว้าวว!!! มันไม่เห็นยากอย่างที่เราเข้าใจเลย โดนเพื่อนขู่มาซะเยอะ ส่วน option ที่เพิ่มมามีดังนี้

  • -d หรือ detach เป็นการสั่ง run container แบบ background นั่นเอง run แบบนี้เมื่อสั่งเสร็จ docker จะคืนค่า container id ถ้าพิมพ์คำสั่งไม่ผิดนะ
  • -p 8000:80 เป็นการกำหนด port ที่จะใช้เชื่อมต่อกับเครื่อง host ตรงนี้เราก็รู้ก่อนว่า image ที่เราใช้เวลาสร้าง container จะ expose port อะไรออกมาบ้าง และ เราจะได้ port ไหน ซึ่งไม่จำเป็นต้องใช้ทุก port เสมอไป ตัวอย่างเป็นการ map container port 80 ออกมายัง host ที่ port 8000 ซึ่งเวลาเล่นกับ docker ส่วนใหญ่เราต้องเล่นกับ port นี่แหละ การ run แต่ละครั้ง port จะต้องไม่ซ้ำกันนะครับ ส่วนใครที่ไม่ยากมานั่งคิด port ก็ใช้ -P แทนก็ได้เป็นการ random port ให้เรา
  • --name เป็นการตั้งชื่อให้กับ container ที่เราสร้างขึ้นมาผมแนะนำให้เราตั้งไว้ให้เป็นนิสัย เพราะเวลาเราจัดการมันจะง่าย จริงๆ ถ้าไม่ระบุมันจะ random ชื่อให้ซึ่งก็จะเป็นการยากสำหรับการจดจำ

คราวนี้ลองตรวจสอบ container กันหน่อยว่ามีจริงไหม

$ docker ps
docker ps

จากคำสั่ง docker ps แนะนำให้สังเกตตรง PORTS และ NAME จะเห็นว่าที่อธิบายเรื่อย port ไปข้างบน image ของ nginx จะ expose ออกมา 2 ports คือ 443 และ 80 ผมเลือกใช้แค่ 80 ส่วน 443 ไม่ได้ map ออกมา และ NAME ก็จะเป็นที่ตั้งไว้คือ web เวลาเราจะจัดการต่อจากนี้ก็ใช้ชื่อ web จัดการ

เมื่อเรา run ได้ container ชื่อว่า web มาแล้วเราอยากเข้าไปยัง container นี้คล้ายๆ กับ ssh หรือ telnet หรือจะให้ใกล้เคียงสุดคือการ chroot เข้าไปสามารถทำได้ง่ายๆ ดังนี้

$ docker exec -it web bash
docker exec

จากตัวอย่างการใช้ docker exec ด้านบน ผมใช้ option สองตัวคือ -it คือ i ทำงานแบบ interactive สามารถพิมพ์คำสั่งได้ และ t คือจำลอง tty ให้เราด้วย และ run bash เพื่อทำงานนั่นเอง เมื่อเข้าไปได้แล้วเราก็สามารถเข้าไปจัดการหรือดูการตั้งค่าต่างๆ ได้ ในตัวอย่างผมก็เข้าไปเปลี่ยนค่าใน index.html ให้เป็นคำว่า Hello เมื่อเสร็จแล้วก็กด Ctrl + d ออกมา แล้วลองเรียกกับ curl ดูการเปลี่ยนแปลง

$ docker exec web ls -l /

หรือเราจะไม่เข้าไปข้างในแต่ใช้ในลักษณะ run คำสั่งคล้ายๆ ตัวอย่างข้างบนที่ใช้ docker run ก็ได้ แต่จะต้องสั่งกับ container ที่กำลัง run แบบ background อยู่นะครับลองเล่นดู

อีกคำสั่งที่จำเป็นมากๆ คือการดู log การทำงานของ container ถ้า image ที่ทำมาดีๆ ก็จะมี log ออกมาให้เราได้วิเคราะห์กัน ถ้าต้องการเฝ้ามองแบบต่อเนื่องก็ให้ใส่ -f ไปด้วย

$ docker logs webหรือ $ docker logs -f web

เมื่อทำงานเสร็จแล้วก็ถึงเวลาฆ่ามันทิ้ง คือถ้าเรามั่นใจและขี้เกียจเราก็สั่ง

$ docker rm -f web

แต่เพื่อความเป็นนิสัยให้เรา stop ก่อน ซึ่งถ้าเราเกิดเปลี่ยนใจเราสามารถ start กลับมาได้

$ docker stop web$ docker start web$ docker restart web$ docker stop web$ docker rm web

หรือในบางครั้งเรามีการแก้ config บางอย่างจำเป็นต้อง restart container ก็สามารถสั่ง restart ได้เช่นกัน

EP2 คงมีเนื้อหาคร่าวๆ เท่านี้ก่อนละกัน ถ้าใครเห็นแนวทางผมว่าสามารถต่อยอดได้มากมายละ เพราะคำสั่งที่ใช้ๆ ก็วนๆ อยู่ประมาณนี้ จริงๆ ก็มีคำสั่งอื่นๆ อีกเอาไว้อธิบายประกอบตัวอย่าง EP ต่อๆ ไปนะครับ ซึ่งตั้งใจว่า จะแนะนำแบบยกตัวอย่างให้ดูแล้วอธิบายไปเรื่อยๆ เนื้อหาอาจจะไม่ต่อเนื่องกัน รอพบกันใหม่ Byeๆ

--

--