Coding Gun

Docker Image คืออะไร?

Docker image คือ packages ของ software ที่เตรียมไว้ให้คุณนำไปใช้ run application(ต้องนำไปสร้างเป็น container ก่อนถึงจะ run application ได้)

เราจะนำ Docker Image มาจากไหน

เราจะนำ docker image มาใช้งานเราจะมีทางเลือกอยู่ 2 ทางคือ

  1. นำ Image ที่คนอื่นเค้าเตรียมไว้ให้ ซึ่งเราจะต้อง pull image ลงมาจาก container registry ซึ่ง Container registry จะมีอยู่ 2 ประเภทคือ

    • Public เป็น container registry ที่เปิดให้เราเอา image ของเค้าลงมาใช้ได้เลย container registry ที่เราจะรู้จักกันมาที่สุดคือ docker hub แต่นอกจากนี้เรายังสามารถ เลือก image จาก vender เจ้าอื่นๆได้อีกมากมาย
    • Private เป็น container registry ที่อยู่ภายในองค์กร ซึ่งอาจเเป็น Server ที่อยู่ในองค์กร หรืออยู่บน Cloud ก็ได้

    คำสั่งที่เราใช้ในการ Download image ลงมาจาก container registry คือ

    $ docker pull [ชื่อ image]
    
  2. เราสามารถ Build image ของเราเองได้การเขียน Dockerfile และ run คำสั่ง

    $ docker build -t [ชื่อ image] .
    

    อ่านวิธีการเขียน Dockerfile แบบละเอียดๆ ได้ที่บทความนี้

จาก Image สู่ Container

เราจะไม่สามารถทำงานกับ Docker Image ได้ เราต้องนำ Docker Image นั้นไปสร้างเป็น Container ก่อนจึงจะสามารถใช้งานได้ ซึ่งจะเป็นดังรูป

จาก docker image สู่ container

เราสามารถสร้าง container กี่ตัวก็ได้จาก Image ตัวเดียวกันเนื่องจากการทำงานของ container จะเป็น layer ดังนั้น layer ด้านล่างจะเป็น read-only จะเป็น software ที่มีการทำงานเหมือนเดิมตลอดเวลา ดังนั้น Container ทุกตัวสามารถ re-use ใช้ Image ตัวเดียวกันได้ ส่วน layer ของ container จะเป็นส่วนที่มีการเปลี่ยนแปลงเราสามารถ read-write ได้

Docker Image จะถูกกำหนดรูปแบบของ Image ด้วน OCI(Open Container Initiative) ดังนั้นเราสามารถนำ Docker Image ไปสร้าง Container ด้วย container run-time ตัวอื่นๆได้

Docker commands สำหรับจัดการกับ Docker Image

docker จะมีคำสั่งสำหรับการทำงานกับ docker image อยู่เยอะมากๆ โดยจะแยกออกเป็นกลุ่มต่างๆ ดังนี้

คำสั่งสำหรับการ Build Docker Image

เราสามารถ build docker image ขึ้นมาเองด้วยคำสั่ง โดยจะระบุการสิ่งที่มีใน docker image นี้ด้วย Dockerfile หลังจากเขียน Dockerfile แล้วเราก็จะเข้า run คำสั่งนี้ใน path ที่มี Dockerfile

$ docker build -t <image_name> .

ถ้าเกิดปัญหาระหว่างการ build ให้ลองกลับไปเริ่มต้น build ใหม่ตั้งแต่ต้น ด้วย parameter –no-cache ซึ่งจะเหมือนกับการ clear cache ในกระบวนการ build

$ docker build -t <image_name> . –no-cache

ในกรณีที่เรามี Dockerfile มากกว่า 1 ไฟล์ เช่น Docker ของ Bach-End ที่เป็น NodeJS เราอาจตั้งชื่อว่า node.dockerfile เราจะบอกให้ใช้ node.dockerfile ในการ build ด้วย parameter -f

$ docker build -t <image_name> . –f node.dockerfile

คำสั่งที่ใช้ในการดึง Docker Image

เราสามารถดึงเอา image ทั้งหมดที่อยู่บนเครื่องนี้ออกมาดูด้วยคำสั่ง

$ docker images
# หรือ 
$ docker image ls # ถ้าใช้ ls คำว่า image จะไม่เติม s

ถ้าต้องการค้นหาตามชื่อ image ต่อท้ายด้วยชื่อ image แบบนี้

$ docker images ubuntu

และถ้าต้องการค้นหาตาม tag ให้ต่อท้ายด้วย : แล้วตามด้วย tag ที่ต้องการค้นหา เช่น

$ docker images ubuntu:rolling

ค้นหา Dangling Image

ในกรณีที่เราต้องค้นหา image ที่เป็น dangling image ซึ่งหมายถึง image ที่ไม่ได้ใช้แล้ว เกิดจากการที่ เราทำการ build image ขึ้นมาใหม่แต่ไม่ได้เปลี่ยนชื่อหรือตั้งชื่อใหม่ docker จะ build image นั้นขึ้นมาในชื่อเดิม ทำให้ image ใน version ก่อนหน้าถูกเปลี่ยนเป็น dangling image(ชื่อของ image จะกลายเป็น )

$ docker images --filter "dangling=true"

image ที่ Build ขั้นมาแล้วแต่ไม่ได้นำไปสร้าง container เราจะเรียกว่า Unused image ซึ่งไม่ใช่ Dangling image

ค้นหาตามช่วงเวลา

เราสามารถค้นหา image ตามเวลาที่เกิดก่อนหรือหลังได้

ตัวอย่าง ตอนนี้เรามี image อยู่ 3 ตัวคือ

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
image1              latest              eeae25ada2aa        4 minutes ago        188.3 MB
image2              latest              dea752e4e117        9 minutes ago        188.3 MB
image3              latest              511136ea3c5a        25 minutes ago       188.3 MB

เรียงลำดับตามการ buid image ดังนี้

  1. image3 เกิดมานานสุด 25 นาที
  2. image2 เกิดก่อน image1 แต่เกิดหลัง image3
  3. image1 เกิดหลังสุด เพิ่งจะมีอายุ 4 นาที

ถ้าเราต้องการ image ที่เกิดก่อน image1 เราจะ filter ด้วย before=image1

$ docker images --filter "before=image1"

ผลลัพธ์จะออกมาแบบนี้

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
image2              latest              dea752e4e117        9 minutes ago        188.3 MB
image3              latest              511136ea3c5a        25 minutes ago       188.3 MB

แต่ถ้าเราต้องการ image ที่เกิดหลังจาก image3 เราจะ filter ด้วย since=image3

$ docker images --filter "since=image3"

ผลลัพธ์จะออกมาแบบนี้

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
image1              latest              eeae25ada2aa        4 minutes ago        188.3 MB
image2              latest              dea752e4e117        9 minutes ago        188.3 MB

จัดรูปแบบของผลลัพธ์ที่ออกมาจากคำสั่ง docker images

เราสามารถเลือก column ในการแสดงผล ด้วย parameter –format

docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}'

ในตัวอย่างนี้จะเปลี่ยนการแสดงผล 2 columns คือ

เราควรจะใช้ Image ที่มีขนาดเล็ก เพราะขนาดของ Image ยิ่งใหญ่ยิ่งมี application เยอะ ยิ่งมีความเสี่ยง

คำสั่งที่ใช้ในการลบ Docker Image

เราสามารถลบ image ที่ต้องการได้ด้วยคำสั่ง

$ docker rmi [ชื่อ image]

ใช้ร่วมกับคำสั่ง docker images ในหัวข้อก่อนหน้าได้ (คำสั่งใช้ได้เฉพาะบน MacOS และ Linux)

# ลบทุกๆ image ที่มีอยู่ในเครื่อง
$ docker rmi $(docker images -q)

หรือถ้าต้องการลบเฉพาะ Dangling image ก็สามารถใส่ parameter -f เพิ่มเข้าไปแบบนี้

# ลบเฉพาะ Dangling image เท่านั้น
$ docker rmi $(docker images -f "dangling=true" -q)

parameter -q เป็นการใช้ quiet mode คือ command ที่ใส่ -q เข้าไปจะ return แค่ id กลับมาเท่านั้น เช่น

$ docker images -q

ผลลัพธ์จะออกมาเป็นแบบนี้ ผลลัพธ์จะออกมาแต่ Image ID เท่านั้น

5628e5ea3c17
5d3887e514fe
289dc403af49

เราจะใส่ -q เข้าไปในทุกๆ sub expression

คำสั่งที่ใช้ในการลบ Docker Image ที่ไม่ได้ใช้(Prune)

การ prune คือการลบสิ่งที่ไม่ต้องการออก ตามความหมายของคำว่า prune ซึ่งแปลว่า ตัด,แต่ง ซึ่ง docker image prune จะมี parameters ต่างๆ ดังนี้

ลบ Unused Image

ถ้าเราต้องการลบ Image ที่ไม่ได้ใช้งานซึ่งประกอบไปด้วย

ดังนั้นถ้าต้องการลบ image ที่ไม่ได้ใช้ออกทั้งหมดให้ใช้คำสั่ง

$ docker image prune -a

เราต้องคอย prune -a บ่อยๆ จะได้นำพื้นที่ใน disk กลับมาใช้งานให้คุ้มค่า

Force

ถ้าต้องการลบเลยโดยไม่ต้อง confirm ให้ใส่ -f หรือ –force

$ docker image prune -f

การ Prune แบบมีเงื่อนไข

เวลาเรา prune เราไม่จำเป็นต้องลบออกทั้งหมดเราสามารถเลือก image ที่ต้องการ prune โดยใช้ –filter ต่อท้ายเข้าไปแบบนี้ เช่น

ต้องการให้ prune image ที่สร้างขึ้นมา ก่อนวันที่ 4 ธันวาคม 2023

$ docker image prune --filter "until=2023-12-04T00:00:00"

ต้องการให้ prune image ที่สร้างขึ้นมามากกว่า 10 วันแล้ว(240 ชั่วโมง)

$ docker image prune -a --force --filter "until=240h"

ต้องการให้ prune image ที่มี label ชื่อ deprecated โดยที่ไม่ได้สนใจว่า deprecated จะมีค่าเป็นอะไร

$ docker image prune --filter="label=deprecated"

ต้องการให้ prune image ที่มี label ชื่อ maintainer โดยที่ maintainer ต้องมีค่าเป็น john

$ docker image prune --filter="label=maintainer=john"

ต้องการให้ prune image ที่ไม่มี label ชื่อว่า maintainer

$ docker image prune --filter="label!=maintainer"

ต้องการให้ prune image ที่มี label ไม่ได้มี maintainer เป็น john

$ docker image prune --filter="label!=maintainer=john"

นอกจากเราจะลบ image ออกแล้วเราควรลบสิ่งที่ไม่ได้ใช้ออกทั้งหมด ดังนั้นเราสามารถลบสิ่งที่ไท่ได้ใช้ออกทั้งหมดด้วยคำสั่ง

$ docker system prune -a
# หรือ
$ docker system prune --all

โดยที่ืคำสั่ง docker system prune จะลบสิ่งต่างๆ ดังต่อไปนี้

ซึ่งจะเห็นว่า prune -a จะไม่ได้รวม volume เข้ามาด้วย(volume ที่ไม่ได้ใช้จะไม่ถูกลบออก) ดังนั้นถ้าเราต้องการลบ volume ออกด้วยให้เพิ่ม -v หรือ –volumes ต่อท้ายเข้าไปแบบนี้

$ docker system prune -a -v
# หรือ
$ docker system prune --all --volumes

อ่านต่อเพิ่มเติมได้ที่

Phanupong Permpimol
Follow me