Docker ฉบับรวบรัด 2020

somprasongd

Somprasong Damyos

Posted on August 4, 2020

Docker ฉบับรวบรัด 2020

Docker เป็นเครื่องมือที่มาเปลี่ยนวิธีการติดตั้งโปรแกรม จากเดิมที่จะทำการติดตั้งบน Virtual Machines หลายๆ เครื่อง ก็เปลี่ยนมาติดตั้งบน Containers แทน แถมยังใช้งานง่าย สร้าง template (Docker image)ไว้ครั้งเดียว ก็จะสามารถติดตั้งโปรแกรมที่ทำงานเหมือนเดิมได้ตลอด และยังสามารถแจกจ่าย Docker image นี้ได้โดยใช้ docker registry อย่างเช่น Docker Hub ซึ่งก็มี Docker image ทั้งจากทาง official และที่คนอื่นๆ ทำเอาไว้แล้ว เราสามารถเอามาใช้งานต่อได้เลย ถือว่าสะดวกมากๆ


หัวข้อ

  1. ทำความรู้จักกับ Docker
  2. การติดตั้ง Docker
  3. รัน Docker Container
  4. สร้าง Docker Image
  5. ทำความเข้าใจ Docker Network ุ6. Docker Volume คืออะไร
  6. ทุกอย่างจะง่ายขึ้นด้วย Docker Compose

1. ทำความรู้จักกับ Docker

ในบทความนี้อยากให้ทำความเข้าใจอยู่ 2 เรื่อง

  • เรื่องแรกคือ Docker ต่างจาก Virtual Machines อย่างไร

Picture from https://docs.docker.com/get-started/

จากรูปข้างบน จะเห็นว่าจากเดิมถ้าใช้ VM จะต้องสร้างใหม่เพื่อรันโปรแกรมๆ หนึ่ง ซึ่งจะทำให้เปลืองทรัพยากรมาก ต่างจาก Docker ที่ทุกโปรแกรมจะรันเป็น containers อยู่บน Docker เพียงตัวเดียวทำให้สามารถใช้งานทรัพยากรทั้งหมดร่วมกันได้

ตัวอย่างถ้าต้องติดตั้งโปรแกรมตามนี้

Alt Text

ถ้าติดตั้งบน VM จะสร้าง VM ขึ้นมาถึง 7 ตัว

Alt Text

แต่ถ้าติดตั้งบน Docker ทุกอย่างถูกรันเป็น container อยู่บนเครื่องเดียวกัน

Alt Text

  • เรื่องที่สอง การทำงานของ Docker นั้นมี architecture เป็นแบบ client-server โดยที่ client (cli) จะส่งคำสั่งผ่าน Rest Api ไปยัง server (Docker daemon) ว่าต้องการทำอะไร

Alt Text

ซึ่งจะเห็นว่า Docker นั้นจะมีองค์ประกอบอยู่ด้วยกัน 4 ส่วนคือ

  1. Container
  2. Image
  3. Network
  4. Volume

และเมื่อมีการสั่งรันจะมี workflow คือ Docker daemon จะดูที่เครื่องตัวเองก่อนว่ามี image นั้นแล้วหรือยัง ถ้ายังไม่มีจะไปดึงมาจาก Registry มาเก็บไว้ก่อน แล้วค่อยรัน image นั้น เป็น container

Alt Text

2. การติดตั้ง Docker

Docker นั้นรองรับการติดตั้งทั้ง Linux, Mac และ Windows 10 โดยสามารถดูได้จาก Get Docker

Windows 10 Home ก็สามารถติดตั้ง Docker Desktop ได้ผ่านทาง WSL2

หรือจะลองเล่นผ่าน Play with Docker ก็ได้

3. รัน Docker Container

เริ่มจาก Docker Hub กันก่อน ซึ่งก็คือ Registry ที่เก็บรวบรวม images ต่างๆ เอาไว้ และเราสามารถดึงมาใช้งานได้ทันที โดยใช้คำสั่ง docker container COMMAND ผ่านทาง cli

Alt Text

วิธีรัน Docker Container

ใช้คำสั่ง docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]

$ docker container run --rm alpine echo "Hello World"

Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
Hello World
Enter fullscreen mode Exit fullscreen mode

มาทำความเข้าใจ

Alt Text

--rm คือ options ที่เอาไว้บอกว่าให้ลบ container นี้ทันทีที่จบการทำงาน เนื่องจากโดยปกติ
alpine คือ ชื่อของ image ที่ต้องการจะรัน โดยถ้าไม่ระบุเลขเวอร์ชัน ระบบจะเอาตัวล่าสุด (latest) มาให้เสมอ ซึ่งวิธีการระบุคือ alpine:3.12 แบบนี้คือบอกว่าให้ใช้ image เวอร์ชัน 3.12
echo คือ คำสั่งที่จะรันเมื่อ container นั้นๆ เริ่มการทำงาน ซึ่งจะไม่ระบุ ก็จะใช้ คำสั่ง default ที่ถูระบุเอาไว้ใน image ตัวนั้นๆ แทน
"Hello World" คือ argument ของคำสั่งที่ระบุก่อนหน้านี้

ซึ่งจะสังเกตได้ว่าเมื่อรันคำสั่งนี้ครั้งแรก ในเครื่องจะยังไม่มี image ชื่อ alpine เวอร์ชัน latest ตัว Docker จะทำการดึง (pull) image มาจาก Registry มาเก็บไว้ในเครื่องก่อนที่จะรัน แต่ถ้าลองรันคำสั่งนี้อีกครั้งจะพบว่าสามารถทำงานได้เลย

$ docker container run --rm alpine echo "Hello World"
Hello World
Enter fullscreen mode Exit fullscreen mode

โหมดการทำงาน

คำสั่ง docker container run นั้น โดยปกติ เมื่อทำงานเสร็จก็จบหยุดการทำงานไปเลย แต่จริงๆ แล้วยังมีโหมดการทำงานอีก 2 โหมด คือ

  • Interactive mode คือ เราสามารถเข้าไปใช้งานภายใน container ได้ โดยใช้ option -it เช่น ถ้าต้องการจากเข้าไปสร้างไฟล์ชื่อ hello.txt
$ docker container run -it alpine sh
/ # ls
bin etc lib mnt root sbin sys usr dev home media proc run srv tmp var
/ # touch hello.txt
/ # ls
bin etc home media proc run srv tmp var dev hello.txt lib mnt root sbin sys usr
/ # exit
Enter fullscreen mode Exit fullscreen mode

แต่ถ้าลองรันคำสั่งเดิมอีกครั้ง จะพบว่าไม่มีไฟล์ hello.txt นั่นก็เพราะว่าทุกครั้งที่สั่ง docker container run จะได้ container ใหม่เสมอ

$ docker container run -it alpine sh
/ # ls
bin etc lib mnt root sbin sys usr dev home media proc run srv tmp var
/ # exit
Enter fullscreen mode Exit fullscreen mode

วิธีดูว่ามี container อะไรที่กำลังรันอยู่บ้างใช้คำสั่ง docker container ls หรือถ้าต้องการดูทั้งหมดรวมกับที่หยุดทำงานไปแล้วใช้คำสั่ง docker container ls -a

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
d4e4e2d06bc1        alpine              "/bin/sh"           30 seconds ago      Exited (0) 27 seconds ago                       lucid_blackburn
6b161b84dd2f        alpine              "/bin/sh"           33 seconds ago      Exited (0) 30 seconds ago                       magical_swartz
Enter fullscreen mode Exit fullscreen mode

จะเห็นว่าชื่อของ container นั้นจะถูกสุ่มตั้งชื่อมาให้ ถ้าต้องการที่จะกำหนดชื่อให้ใช้ option --name

$ docker container run --name my_container_name alpine echo "Hello World"
Hello World
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
e7f5de85e4ff        alpine              "echo 'Hello World'"    14 seconds ago      Exited (0) 13 seconds ago                       my_container_name
d4e4e2d06bc1        alpine              "/bin/sh"           30 seconds ago      Exited (0) 27 seconds ago                       lucid_blackburn
6b161b84dd2f        alpine              "/bin/sh"           33 seconds ago      Exited (0) 30 seconds ago                       magical_swartz
Enter fullscreen mode Exit fullscreen mode

วิธีลบ container ที่ไม่ได้ใช้งาน ใช้คำสั่ง docker container rm ตามด้วย id หรือ name และสามารถลบได้ครั้งละมากกว่า 1 ตัว เช่น

$ docker container rm d4e4e2d06bc1 my_container_name
d4e4e2d06bc1
my_container_name
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
6b161b84dd2f        alpine              "/bin/sh"           33 seconds ago      Exited (0) 30 seconds ago                       magical_swartz
Enter fullscreen mode Exit fullscreen mode

ถ้าต้องการลบทุก container ที่หยุดทำงานแล้วใช้คำสั่ง docker container prune

  • Background mode คือ การสั่งให้ container นั้นๆ ยังคงทำงานอยู่เบื้องหลังเมื่อสั่งรัน โดยใช้ option -d
$ docker container run -d --name alpine alpine sleep 6000
f0f9ee6d40b4f596612d93f73d26a8cc88484514d743b1950998a23710e3ec80
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f0f9ee6d40b4        alpine              "sleep 6000"        55 seconds ago      Up 54 seconds                           alpine
Enter fullscreen mode Exit fullscreen mode

จะเห็นว่าสถานะยังเป็น Up คือ ยังทำงานอยู่นั้นเอง และเมื่อทำงานอยู่ในโหมดนี้ ถ้าต้องการรันคำสั่งใน container ทำได้โดยใช้คำสั่ง docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]

$ docker container exec alpine ls
bin etc lib mnt root sbin sys usr dev home media proc run srv tmp var
Enter fullscreen mode Exit fullscreen mode

การใช้ร่วมกับ interactive mode

$ docker container exec -it alpine sh
/ # ls
bin etc lib mnt root sbin sys usr dev home media proc run srv tmp var
/ # exit
Enter fullscreen mode Exit fullscreen mode

ถ้าต้องการหยุดการทำงาน ใช้คำสั่ง docker container stop CONTAINER
ถ้าต้องการใช้งานใหม่อีกครั้ง (จะทำงานตามคำสั่งที่รันไว้ครั้งแรก) ใช้คำสั่ง docker container start CONTAINER

$ docker container stop alpine
alpine
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS               NAMES
f0f9ee6d40b4        alpine              "sleep 6000"        14 minutes ago      Exited (137) 13 seconds ago                       alpine
$ docker container start alpine
alpine
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f0f9ee6d40b4        alpine              "sleep 6000"        14 minutes ago      Up 2 seconds                            alpine
Enter fullscreen mode Exit fullscreen mode

Bind mount a volume

โดยปกติถ้าเราสามารถสร้างไฟล์ภายใน container ได้ แต่ทุกครั้งที่จะแก้ไขจะต้องเข้าไปแก้ไขข้างใน container หรือถ้าลบ container นั้นทิ้งไปแล้วไฟล์นั้นๆ ก็จะหายไปด้วย ซึ่งสามารถแก้ไขได้โดยการสร้างไฟล์ที่เครื่องของเรา แล้วค่อยทำการ binding volume เข้าไปใน container ก็จะแก้ปัญหานี้ได้

# Step 1: สร้างไฟล์ host/hello.txt ไว้ที่เครื่องของเราเอง
$ mkdir host
$ echo "Hello from host" >> host/hello.txt

# Step 2: รัน container และ binding volume จาก host ไปที่ container
$ docker container run -d -v $(pwd)/host:/container --name alpine2 alpine sleep 600

# Step 3: เข้าไปของใน container และแก้ไข container/hello.txt
$ docker container exec -it alpine3 sh
/ # cd container/
/container # ls
hello.txt
/container # cat hello.txt
Hello from host
/container # echo "Edit from container" >> hello.txt
/container # exit

# Step 4: ลองดูที่ไฟล์ host/hello.txt จะพบว่าได้ถูกแก้ไขไปด้วย
$ cat host/hello.txt
Hello from host
Edit from container

# Step 5: ให้แก้ไขที่ไฟล์ host/hello.txt
$ echo "Edit from host" >> host/hello.txt 

# Step 6: ให้เข้าไปใน container อีกครั้ง แล้วดูที่ไฟล์ ก็จะถูกแก้ไขด้วยเหมือนกัน
$ docker container exec -it alpine3 cat container/hello.txt
Hello from host
Edit from container
Edit from host
Enter fullscreen mode Exit fullscreen mode

ทั้งหมดนี้ค่อนข้างครอบคลุมการใช้งานทั่วไปแล้วในส่วนของ Container แล้ว ถัดไปจะเป็นการสร้าง Image ขึ้นมาใช้งานเอง

4. สร้าง Docker Image

5. ทำความเข้าใจ Docker Network

ุ##6. Docker Volume คืออะไร

7. ทุกอย่างจะง่ายขึ้นด้วย Docker Compose

💖 💪 🙅 🚩
somprasongd
Somprasong Damyos

Posted on August 4, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related