Docker ซดดิสต์ไปเท่าไหร่นะ

Teerayut Hiruntaraporn
3 min readJun 13, 2021

--

เรื่องนี้เป็น update สักหน่อย เพราะเหมือนกับก่อนหน้านี้ เราจะเช็คแค่ docker images ก็จะเห็นเกือบทุกสิ่ง ที่ควรจะเคลียร์และ

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

ทีนี้ข้อสังเกตที่เห็นว่ามันมีความผิดปกตินอกจากเรื่อง photoshop แล้ว ก็ยังมีในช่วงที่ทำการเทรนน้องๆ ที่พึ่งเข้ามาใหม่ แล้วพอว่า หลังจาก build docker แล้ว ตัว source images มันไม่อยู่ใน docker images อย่างที่เคย

เลยต้องแอบมานั่งดูหน่อย ว่าจะจัดการยังไง

ดูภาพรวมด้วย docker system df

อย่างแรกสุด นอกเหนือจาก docker images ที่ค่อนข้างจะชัดเจนแล้ว เราควรจะดูภาพรวมของการใช้พื้นที่ โดยใช้ docker system df โดยคำสั่งนี้จะแสดงรายละเอียดการใช้ข้อมูลภายในระบบของ docker ซึ่งจะแยกเป็นส่วนต่างๆ ให้สวยงาม

#docker system df 
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 19 0 4.603GB 4.603GB (100%)
Containers 0 0 0B 0B
Local Volumes 64 0 1.329GB 1.329GB (100%)
Build Cache 148 0 3.776GB 3.776GB

เราจะเห็นว่า มันจะแบ่งส่วนประกอบเป็น

  • Images คือ image ต่างๆ ที่เราเอามาใช้ในการเปิด container นี่เอง
  • Containers คือ ส่วนของ container ที่เราเปิดไว้ หรือปิด ไว้แต่ยังไม่ได้ลบ
  • Local Volumes คือ ส่วนของ volume หรือที่เก็บข้อมูลเวลาเราใช้ container แต่ตรงนี้ส่วนตัวไม่ค่อยได้ไปยุ่งกับมันมากนัก
  • Build Cache คือส่วนพื้นที่ที่ใช้เก็บข้อมูลในการ build ต่างๆ ถ้ามัน build เร็ว ก็เพราะมันเก็บไว้ตรงนี้นี่แหละ และปัจจุบันก็เข้าใจว่า มันน่าจะเอา image ที่เป็นต้นแบบมาใส่ ตรงนี้ด้วย

เคลียร์ Container ที่ไม่ได้ใช้ ด้วย docker rm

ปัญหาแรกสุดคือการที่เราใช้งาน container เสร็จแล้ว ไม่ยอมเคลียร์ทิ้ง เช่น ถ้าเราสั่ง redis ขึ้นมา ด้วยคำสั่ง

docker run -it redis:6.2.1-alpine

ปรากฏว่า เราลืม bind port แล้วเราก็กด Ctrl+C แล้วสั่งใหม่

สิ่งที่เกิดขึ้นคือ ตัว container เดิมก็จะอยู่ใน state ปิด แต่ไม่ได้ถูกลบออกจาก เครื่องเรา

$docker ps -a 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e5d164aae9a1 redis:6.2.1-alpine "docker-entrypoint.s…" About a minute ago Exited (0) 26 seconds ago zen_euclid

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

$docker rm e5d164aae9a1 (หรือใช้ชื่อแทน เช่น zen_euclid)

แต่ถ้ามันเยอะๆ หล่ะ ถ้าทุกตัวเรามั่นใจว่าไม่ได้ใช้แล้วนะครับใช้ docker container prune เพื่อทำการลบ container ที่ไม่ได้ใช้แล้วทั้งหมดได้เลย

$docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
e5d164aae9a15554931652712cadf1180d4be614e9b123b0c7dc559b8ec9dd8a

สิ่งที่เกิดขึ้นคือ มันจะลบ container ที่ปิดแล้ว “ทั้งหมด” ไป

ดังนั้นใครที่ใช้ลักษณะของการ เปิด/ ปิด container ที่มีอยู่แล้วเป็นประจำ ไม่แนะนำให้ใช้ท่านี้ครับ

เคลียร์ Image ที่ไม่ได้ tag ด้วย docker image prune

ต่อมาถ้าเราเห็นว่า image ใดไม่ได้ใช้ เราก็เคลียร์มันทิ้งก่อนครับ

โดยเราก็ลิสต์รายการ image ออกมาก่อนว่ามีอะไรบ้างโดยใช้ docker images

$docker imagesREPOSITORY                   TAG                IMAGE ID       CREATED         SIZE
<none> <none> 2f6a9033f594 6 days ago 1.33GB
redis 6.2.1-alpine 5812dfe24a4f 3 months ago 32.3MB

จากนั้นก็เลือกตัวที่จะลบครับ เช่นถ้าเราต้องการลบ redis ที่มีขนาด 32.3MB ก็จะใช้ docker rmi ในการลบ image นั้นๆ

$docker rmi redis:6.2.1-alpine

แต่อยากให้สังเกตว่า มันจะมี image ที่เขียนว่า <none> ซึ่งเป็น image ที่อาจจะโดยแย่ง tag ไปจาก image ที่เป็นปัจจุบัน ลักษณะนี้เรียกว่า dangling image ครับ

ซึ่ง image แบบนี้เราคงไม่ได้ใช้ต่อแล้ว ก็สามารถลบได้เช่นเดียวกัน

ทีนี้ถ้าจะลบ dangling image ทุกตัว ก็สามารถใช้คำสั่ง docker image prune ได้ครับ

$docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

เคลียร์ build cache ด้วย docker builder prune

ทีนี้เข้ามาในส่วนของ builder cache บ้าง เราสามารถดูรายละเอียดว่า เรามี builder cache ไว้ประมาณไหนบ้าง จากการใช้ docker buildx du ครับ

$docker buildx du    
ID RECLAIMABLE SIZE LAST ACCESSED
st3w68rn1h9gighpatx0mc951 true 410.53MB
cg0bch7t022zkl42xep50s817 true 356.14MB
qc8hkib1m70gf71qg9shgtd2c true 253.23MB
vqggev5mo5zbh2fm6d3bzf15a* true 225.62MB
r94rdl9prvxn4ndfk9oenwmx1 true 210.43MB
6ll6cwzw0ocqcqq1m57ucfz2r true 200.51MB
qo9lwwb3925cx3af1lc8qg062 true 200.49MB
smqsufde47jb0h5zh91v30xh4 true 128.15MB
u1jv5jmr4sks6bfemu7b2v422* true 127.66MB
k0t801ztaxononw5lhakg2asq true 116.98MB
t0wqldl2u8dpl3g4o74w5h5jy true 115.50MB
63eiwqzo1avt750elq4oicy1r true 114.70MB
zz5w1x4frcytejp329op0eo8n* true 113.34MB
zh89in5xtanwbu0mzlpuyzlyr true 109.48MB
.
.
.
Shared: 441.55MB
Private: 6.64GB
Reclaimable: 7.08GB
Total: 7.08GB

จะสังเกตว่าแอบเยอะ เพราะพึ่งรู้ว่ามี เลยเกิดไว้เยอะพอสมควร

ทีนี้การลบ cache สิ่งที่เกิดขึ้นคือ เมื่อ build ใหม่มันจะช้าลง เพราะไม่มี cache เก็บไว้แล้ว แต่ไม่น่าเป็นกังวลสักเท่าไหร่

ดังนั้นเราจะทำการเคลียร์ build cache ทิ้งโดยใช้ docker builder prune ครับ

$docker builder prune
WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
Deleted build cache objects:
.
.
.
Total reclaimed space: 6.637GB

ได้พื้นที่กลับมาเป็นขโยง

เคลียร์ local volume ด้วย docker volume prune

สุดท้ายในส่วนของ local volume กลุ่มชุดคำสั่งก็จะคล้ายๆ กันครับ คือ แสดงด้วย

$docker volume ls
DRIVER VOLUME NAME
local 1c1962320dcdc57f015b69285c9443fb98016942e101ed9ca5093340182e0784
local 1d772a772d83e0ad8237db8b6d983bfe84c08f74adda4e17aa874f0c09311d5b
.
.
.

และลบด้วย

$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
7b01f42f353cee2da9cd0af129c9d312e0161a237336bf48ab314d10fbb22044
16091f6a02ca5d0944ad643a89110b012b2d02d68910a2b98f7f54b693a2528a
.
.
.
Total reclaimed space: 1.329GB

ล้างบางด้วย docker system prune

ในบางสถานการณ์ เราอาจจะต้องการล้างบางทิ้งทั้งกะปิ ทีนี้มันเลยมีตัวเลือกง่ายๆ ขึ้นมานั่นคือคำสั่ง docker system prune ซึ่งคำสั่งนี้ทำงาน อยู่ 2 แบบคือ

  • แบบธรรมดา ก็รันแบบธรรมดาเลยครับ
$docker system prune 
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N]
  • แบบล้างโคตร มี -a เพิ่ม
$docker system prune -a 
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N]

สิ่งที่อยากให้สังเกตความแตกต่างนะครับ

prune แบบธรรมดา จะลบเฉพาะ dangling images และ build cache

ขณะที่ -a จะลบ image ที่ไม่ได้ถูกใช้ใน container ขณะนั้น และ build cache ทั้งหมด

ดังนั้นในการเลือกใช้ก็ควรเลือกอยากระมัดระวัง ให้เหมาะกับสถานการณ์ครับ ซึ่งโดยปกติ เราก็มักจะไม่เล่นขนาด -a สักเท่าไหร่

สุดท้ายก็หวังว่าจะมีประโยชน์กับ คนที่ทำงานโดย docker แล้วที่เต็ม อย่างไม่ทราบสาเหตุ นะครับ _ _!

--

--

Teerayut Hiruntaraporn
Teerayut Hiruntaraporn

No responses yet