4. Docker Images
Mục lục
- 1. Image là gì?
- 2. Pull image & Image Registry
- 3. Đặt tên và tag image
- 4. Image gồm nhiều layer chồng lên nhau
- 5. Digest — pull image theo hash bất biến
- 6. Multi-architecture image
- 7. Xóa image
Đúng như đã hẹn ở cuối Phần 3: giờ mổ xẻ kỹ khái niệm image — nó thực chất gồm những gì, vì sao lại là nhiều layer chứ không phải 1 khối, và vì sao không nên tin tưởng mù quáng vào tag.
1. Image là gì?
Nói ngắn gọn: Docker image là 1 bản đóng gói chỉ-đọc, chứa sẵn OS rút gọn + ứng dụng + toàn bộ dependency cần để chạy nó — pull về, docker container run là có ngay 1 container sống, không cần cài đặt gì thêm.
💡 Hình dung: với dân từng quản trị VM, Docker image giống 1 VM template đã tắt máy — sẵn sàng nhân bản ra bao nhiêu VM (container) cũng được mà bản thân template không hề thay đổi. Với dân developer, image giống 1 class trong lập trình hướng đối tượng — container chính là instance được khởi tạo từ class đó, mỗi instance có state (dữ liệu runtime) riêng dù dùng chung 1 bản định nghĩa gốc.
Bạn bắt đầu bằng cách pull image từ 1 image registry — phổ biến nhất là Docker Hub, dù các registry khác vẫn tồn tại. Thao tác pull tải image về Docker host cục bộ, sẵn sàng để khởi chạy 1 hoặc nhiều container từ đó.
Image được ghép từ nhiều layer chỉ-đọc (read-only) xếp chồng lên nhau, hiển thị ra ngoài như 1 object thống nhất duy nhất. Bên trong image là 1 bản OS đã rút gọn tối đa, cùng toàn bộ file/dependency cần để chạy ứng dụng — vì container hướng tới nhanh và nhẹ, image thường cũng rất nhỏ gọn.
Image là build-time, container là run-time
Vì image giống 1 container đã dừng (hay 1 class, với dân dev) — thực tế bạn hoàn toàn có thể dừng 1 container rồi tạo ra 1 image mới từ chính nó. Từ đó có thể xem image là build-time construct, còn container là run-time construct.
Dùng docker container run hoặc docker service create để khởi chạy 1 hoặc nhiều container từ cùng 1 image. Nhưng khi đã có container chạy từ 1 image, 2 khái niệm này trở nên phụ thuộc lẫn nhau — không thể xóa image cho tới khi container cuối cùng dùng nó đã dừng và bị hủy. Cố xóa 1 image đang được container dùng sẽ báo lỗi:
$ docker image rm <image-name>
Error response from daemon: conflict: unable to remove repository reference \
"<image-name>" (must force) - container <container-id> is using its referenced image <image-id>
Vì sao image thường nhỏ gọn?
Mục đích duy nhất của container là chạy 1 ứng dụng/service — image dùng để tạo container đó phải chứa đủ mọi file OS và ứng dụng cần thiết, nhưng vì container hướng tới nhanh/nhẹ nên image build ra thường bị lược bỏ tối đa phần không cần thiết. Ví dụ: Docker image không đi kèm 6 loại shell khác nhau để chọn — thường chỉ có đúng 1 shell tối giản, hoặc không có shell nào cả. Image cũng không chứa kernel — mọi container trên cùng 1 Docker host dùng chung kernel của host. Vì vậy hay nói image chỉ chứa "vừa đủ OS" (chủ yếu là file/filesystem object liên quan tới OS).
Image Alpine Linux chính thức chỉ khoảng 4MB — ví dụ cực đoan cho thấy image có thể nhỏ tới đâu. Một ví dụ điển hình hơn là image Ubuntu chính thức, khoảng 120MB. Image gốc Windows thường nặng hơn hẳn image gốc Linux do cách vận hành riêng của Windows OS — ví dụ image .NET của Microsoft nặng hơn 2GB khi pull và giải nén, còn image Windows Server 2016 Nano Server hơn 1GB.
2. Pull image & Image Registry
Docker host mới cài sạch chưa có image nào trong local repository. Trên Linux, local repository thường nằm ở /var/lib/docker/<storage-driver>; trên Windows là C:\ProgramData\docker\windowsfilter. Kiểm tra bằng lệnh đã thấy thoáng qua ở Phần 3:
$ docker image ls
# Output minh họa (host mới cài nên bảng chỉ có dòng tiêu đề, chưa có image nào)
REPOSITORY TAG IMAGE ID CREATED SIZE
Tải image về host gọi là pull:
$ docker image pull ubuntu:latest
$ docker image pull alpine:latest
# Output minh họa
latest: Pulling from library/ubuntu
a2318d6c47ec: Pull complete
Digest: sha256:9a0bdde4188b896a372804be2384015e90e3f84906b750c1a53539b585fbbe7
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
latest: Pulling from library/alpine
59bf1c3509f3: Pull complete
Digest: sha256:eece025e...
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
(Output minh họa — mỗi dòng Pull complete ứng với 1 layer trong image, digest cụ thể chỉ mang tính ví dụ.)
Image Registry, Repository, và Image
Docker image được lưu trong image registry — phổ biến nhất là Docker Hub (hub.docker.com), ngoài ra còn có registry bên thứ 3 hoặc registry riêng on-premises, nhưng Docker client mặc định luôn trỏ về Docker Hub.
Một registry chứa nhiều repository, mỗi repository lại chứa nhiều image. Ví dụ: 1 registry có thể chứa 3 repository, mỗi repository chứa 1 hoặc nhiều image bên trong.
💡 Hình dung: registry giống 1 siêu thị lớn (Docker Hub), repository giống từng quầy hàng riêng trong siêu thị đó (quầy
nginx, quầyredis...), còn image chính là từng phiên bản sản phẩm cụ thể bày trên quầy (nginx:1.25,nginx:latest...) — cùng 1 quầy nhưng nhiều phiên bản khác nhau để chọn.
Repository chính thức và không chính thức
Docker Hub phân biệt official repository (đã được Docker, Inc. kiểm duyệt — code cập nhật, chất lượng cao, an toàn, có tài liệu đầy đủ, theo đúng best practice) và unofficial repository (không đảm bảo an toàn, không đảm bảo có tài liệu hay theo best practice — không có nghĩa nội dung xấu, chỉ là cần cẩn trọng hơn khi dùng, kể cả với image chính thức).
Repository chính thức dễ nhận ra vì nằm ở top-level namespace của Docker Hub, ví dụ: nginx, busybox, redis, mongo. Repository không chính thức nằm trong namespace cấp 2, gắn với tên tài khoản/tổ chức, ví dụ myteam/webapp.
Lưu ý: "namespace" ở đây là khái niệm khác hẳn kernel namespace đã nói ở Phần 3 (PID namespace, network namespace...) — ở đây chỉ đơn giản là 1 tiền tố phân cấp trong tên repository trên Docker Hub, không liên quan gì tới việc cách ly tiến trình. Cùng 1 từ nhưng 2 ngữ cảnh hoàn toàn khác nhau, khá phổ biến trong hệ sinh thái container nên cần phân biệt rõ.
3. Đặt tên và tag image
Với image từ repository chính thức, cú pháp đơn giản là tên repository và tag cách nhau bằng dấu ::
docker image pull <repository>:<tag>
Ví dụ:
$ docker image pull mongo:3.3.11 # pull image tag `3.3.11` từ repo chính thức `mongo`
$ docker image pull redis:latest # pull image tag `latest` từ repo chính thức `redis`
$ docker image pull alpine # không chỉ định tag -> mặc định pull tag `latest`
# Output minh họa
3.3.11: Pulling from library/mongo
9251b1d1010d: Pull complete
Status: Downloaded newer image for mongo:3.3.11
latest: Pulling from library/redis
a9edb18cadd1: Pull complete
Status: Downloaded newer image for redis:latest
latest: Pulling from library/alpine
59bf1c3509f3: Pull complete
Status: Downloaded newer image for alpine:latest
(Output minh họa — mỗi khối 3 dòng ứng với đúng 1 lệnh pull phía trên, theo thứ tự; ID layer cụ thể chỉ mang tính ví dụ.)
2 điều cần nhớ:
- Nếu không chỉ định tag, Docker mặc định hiểu là tag
latest. - Tag
latestkhông có phép màu gì đặc biệt — không đảm bảo đó là image mới nhất trong repository! Ví dụ image mới nhất trong repoalpinethường được gắn tagedgechứ không phảilatest. Luôn cẩn trọng khi dùng taglatest.
Pull image từ repo không chính thức tương tự, chỉ cần thêm tiền tố tên user/tổ chức trên Docker Hub:
$ docker image pull myteam/webapp:v2
# Output minh họa
v2: Pulling from myteam/webapp
9251b1d1010d: Pull complete
Status: Downloaded newer image for myteam/webapp:v2
docker.io/myteam/webapp:v2
(Output minh họa — cấu trúc giống hệt pull từ repo chính thức, chỉ khác tên repository có thêm tiền tố myteam/.)
Muốn pull từ registry bên thứ 3 (không phải Docker Hub), thêm tiền tố DNS name của registry đó, ví dụ Google Container Registry (GCR): docker pull gcr.io/<namespace>/<repo>:<tag> — có thể cần tài khoản riêng và đăng nhập trước khi pull được từ registry bên thứ 3.
1 image có thể mang nhiều tag
Tag chỉ là giá trị alpha-numeric tùy ý, lưu như metadata gắn kèm image — nên 1 image hoàn toàn có thể mang nhiều tag cùng lúc. Pull toàn bộ image trong 1 repository bằng cờ -a:
$ docker image pull -a myteam/webapp
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
myteam/webapp v2 6ac2...ad 12 months ago 211.6 MB
myteam/webapp latest 9b91...29 12 months ago 211.6 MB
myteam/webapp v1 9b91...29 12 months ago 211.6 MB
Chú ý cột IMAGE ID: chỉ có 2 ID duy nhất dù pull về 3 tag — vì latest và v1 trỏ chung 1 IMAGE ID, tức chỉ là 2 tag của cùng 1 image. Đây cũng là ví dụ thực tế của cảnh báo phía trên: trong trường hợp này, latest lại đang trỏ về image cũ hơn so với v2 — bằng chứng latest không đảm bảo là bản mới nhất.
💡 Hình dung: tag giống 1 tờ giấy nhớ (sticky note) dán lên đúng "hộp" image nào đó — dán được, gỡ ra dán sang hộp khác cũng được, không tốn công sao chép lại hộp. Nhiều tờ giấy nhớ hoàn toàn có thể cùng dán chung 1 hộp, giống hệt
latestvàv1đang cùng trỏ về 1IMAGE IDtrong ví dụ trên.
4. Image gồm nhiều layer chồng lên nhau
Một Docker image thực chất chỉ là 1 chuỗi layer chỉ-đọc, liên kết lỏng lẻo với nhau — Docker chịu trách nhiệm xếp chồng các layer này lại và trình bày ra ngoài như 1 object thống nhất.
Cách dễ nhất để thấy các layer: nhìn lại output của docker image pull — mỗi dòng kết thúc bằng Pull complete tương ứng 1 layer trong image (ví dụ image ubuntu:latest gồm 5 layer thì sẽ có 5 dòng Pull complete). 2 lệnh sau cho cái nhìn chi tiết hơn.
docker history cho thấy lịch sử build của image — mỗi dòng ứng với 1 instruction trong Dockerfile:
$ docker history alpine:latest
# Output minh họa
IMAGE CREATED CREATED BY SIZE
02674b9cb179 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:4d3c... in / 5.6MB
(Output minh họa — cấu trúc và tên cột đúng theo lệnh thật, số liệu chỉ mang tính ví dụ.)
docker historykhông phải danh sách layer chính xác tuyệt đối — vì một số instruction trong Dockerfile (MAINTAINER,ENV,EXPOSE,ENTRYPOINT...) không tạo layer mới, chỉ thêm metadata vào image. Đó là lý do 1 số dòng ở trên cóSIZE=0B: dòng đó chỉ là metadata, không phải 1 layer filesystem thật.
Muốn xem chính xác danh sách layer thật (theo SHA256 hash), dùng docker image inspect và lọc đúng phần RootFS.Layers:
$ docker image inspect alpine:latest --format '{{json .RootFS.Layers}}'
# Output minh họa
["sha256:9b18e9b68314...", "sha256:a3f3e8ee3b8b..."]
(Output minh họa — số lượng và giá trị hash thật sẽ khác tùy image, nhưng luôn là danh sách hash SHA256, mỗi hash ứng đúng 1 layer thật.)
Mọi Docker image đều bắt đầu từ 1 base layer, mỗi lần thêm thay đổi/nội dung mới, 1 layer mới lại được thêm lên trên. Ví dụ đơn giản hóa: tạo image dựa trên Ubuntu 16.04 (layer 1), thêm gói Python (layer 2), thêm 1 bản vá bảo mật (layer 3) — image cuối cùng có 3 layer.
Quan trọng: image cuối cùng là tổ hợp của tất cả layer. Nếu 1 layer phía trên có file trùng tên với file ở layer phía dưới, file ở layer trên sẽ che (obscure) file layer dưới trong view thống nhất — đây chính là cách 1 phiên bản file mới được thêm vào image dưới dạng 1 layer mới, mà không cần sửa trực tiếp layer cũ.
💡 Hình dung: layer giống 1 chồng giấy bóng kính (transparency) đặt xếp lên nhau trên máy chiếu — mỗi tờ vẽ thêm hoặc sửa đè lên đúng vị trí cần thay đổi. Nhìn từ trên xuống chỉ thấy 1 hình ảnh thống nhất, nhưng thực chất là nhiều tờ rời xếp chồng; tờ trên cùng luôn che đúng phần nó vẽ đè lên tờ dưới.
Việc xếp chồng và trình bày các layer thành 1 filesystem thống nhất do storage driver của Docker đảm nhiệm — cụ thể, storage driver dựa trên kỹ thuật copy-on-write (CoW): khi 1 file ở layer dưới cần sửa, storage driver không sửa trực tiếp file gốc (vì layer là read-only), mà copy file đó lên layer ghi-được (writable layer) trên cùng rồi mới sửa bản copy — file gốc ở layer dưới vẫn nguyên vẹn. Đây là lý do nhiều container có thể cùng chạy từ 1 image mà không đụng nhau: chúng chia sẻ chung các layer read-only, chỉ khác nhau ở phần đã copy-on-write riêng của mỗi container.
Trên Linux, overlay2 hiện là driver mặc định và được khuyến nghị trên hầu hết distro. Các driver cũ hơn từng phổ biến ở thời sách gốc viết — AUFS, devicemapper, btrfs, zfs — nay phần lớn đã bị deprecate hoặc gỡ bỏ hẳn khỏi Docker Engine hiện tại, chỉ còn giá trị tham khảo lịch sử. Trên Windows, driver duy nhất được hỗ trợ là windowsfilter, hiện thực layering và CoW trên nền NTFS.
Chia sẻ layer giữa các image
Nhiều image hoàn toàn có thể dùng chung layer với nhau — giúp tiết kiệm cả dung lượng lẫn hiệu năng. Ví dụ pull cả 3 tag latest/v1/v2 của cùng 1 repository, các dòng log ghi Already exists chính là dấu hiệu Docker nhận ra layer đó đã có sẵn cục bộ, không cần tải lại — vì 3 image gần như giống hệt nhau nên chia sẻ phần lớn layer chung.
5. Digest — pull image theo hash bất biến
Pull image theo tag là cách phổ biến nhất, nhưng có 1 vấn đề: tag có thể thay đổi (mutable) — hoàn toàn có thể vô tình gắn nhầm tag, hoặc gắn cùng 1 tag cho 2 image khác nhau. Ví dụ: image orderapi:1.5 đang chạy production có bug, bạn fix xong rồi push lại với đúng tag 1.5 cũ — giờ không còn cách nào phân biệt hệ thống nào đang chạy bản có bug, hệ thống nào đang chạy bản đã vá, vì cả 2 đều mang chung 1 tag!
Digest giải quyết đúng vấn đề này. Từ Docker 1.10, mọi image đều có 1 content hash (gọi là digest) — vì đây là hash của chính nội dung image, nội dung đổi thì digest cũng đổi theo, nên digest bất biến (immutable).
💡 Hình dung: tag giống tên gọi 1 căn nhà theo địa chỉ ("nhà số 5") — chủ cũ bán nhà, chủ mới dọn vào, địa chỉ "nhà số 5" vẫn vậy dù bên trong đã hoàn toàn khác. Digest giống số CMND/căn cước của đúng người chủ cũ — cố định, không đổi, và không bao giờ trỏ nhầm sang người khác dù người đó có đổi tên hay đổi địa chỉ.
Mỗi lần docker image pull, digest luôn xuất hiện trong kết quả trả về. Xem digest của image đã có cục bộ bằng cờ --digests:
$ docker image pull alpine
$ docker image ls --digests alpine
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
alpine latest sha256:3dcd...f73a 4e38e38c8ce0 10 weeks ago 4.8 MB
Biết digest rồi, có thể pull chính xác đúng image đó bất kể tag đổi thế nào:
$ docker image rm alpine:latest
$ docker image pull alpine@sha256:c0537...7c0a7726c88e2bb7584dc96
# Output minh họa
Untagged: alpine:latest
Deleted: sha256:4e38e38c8ce0b8d9041a7e1304ec941820ff82171ca24e4d6d3ee555e77c0537
alpine@sha256:c0537...: Pulling from library/alpine
59bf1c3509f3: Pull complete
Digest: sha256:c0537...7c0a7726c88e2bb7584dc96
Status: Downloaded newer image for alpine@sha256:c0537...7c0a7726c88e2bb7584dc96
(Output minh họa — docker image rm echo lại đúng ID vừa xóa, docker image pull theo digest cho output gần giống pull theo tag, chỉ khác dòng đầu ghi rõ digest thay vì tag.)
Tại thời điểm sách gốc viết, chưa có lệnh Docker gốc nào lấy được digest của 1 image trực tiếp từ registry từ xa — cách duy nhất là pull theo tag rồi ghi lại digest trả về. Docker hiện tại đã có docker manifest inspect, xem được digest thẳng từ registry mà không cần pull trước:
$ docker manifest inspect alpine:latest
# Output minh họa
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"digest": "sha256:3dcd...f73a",
"platform": { "architecture": "amd64", "os": "linux" }
}
]
}
(Output minh họa — cấu trúc field đúng theo lệnh thật, giá trị digest cụ thể chỉ mang tính ví dụ.)
Vì sao còn có thêm "distribution hash"?
Mỗi image được nhận diện bằng 1 crypto ID (hash của config object), mỗi layer cũng có crypto ID riêng (hash của nội dung layer) — đổi nội dung image/layer sẽ làm đổi luôn crypto hash tương ứng, nên image và layer đều bất biến.
Nhưng khi push/pull, các layer được nén lại để tiết kiệm băng thông và dung lượng lưu trữ ở registry — mà nén tức là thay đổi nội dung, nên content hash sẽ không khớp nữa sau khi push/pull! Để giải quyết, mỗi layer còn có thêm 1 distribution hash — hash của chính bản đã nén — dùng để xác minh layer không bị can thiệp trong quá trình truyền tải. Mô hình content-addressable storage này giúp tăng đáng kể tính bảo mật (xác minh được dữ liệu sau push/pull) và tránh trùng ID nếu ID được sinh ngẫu nhiên.
6. Multi-architecture image
Docker hỗ trợ image đa nền tảng, đa kiến trúc (multi-platform, multi-architecture) — nghĩa là 1 repository + tag duy nhất có thể ẩn chứa nhiều bản image khác nhau cho từng kiến trúc (ví dụ Linux x64 và Linux PowerPC). Cùng chạy docker container run myapp:1.0, máy Linux x64 và máy ARM sẽ tự động pull về đúng bản image khớp kiến trúc của mình — không cần biết trước hay tự chọn tag riêng cho từng kiến trúc.
Cơ chế này dựa trên Registry API hỗ trợ thêm fat manifest bên cạnh image manifest thông thường: fat manifest liệt kê các kiến trúc mà 1 image hỗ trợ, còn image manifest liệt kê layer thực sự cấu thành image đó cho từng kiến trúc. Khi pull image trên 1 máy Linux x64, Docker client gọi API, kiểm tra fat manifest xem có entry cho Linux x64 không — nếu có, lấy đúng image manifest tương ứng rồi pull layer theo crypto ID từ blob store của registry (blob store: nơi registry lưu trữ dữ liệu layer thô, định danh theo crypto ID chứ không theo tên file).
💡 Hình dung: fat manifest giống 1 tờ thực đơn ghi "món phở" có sẵn cả bản "không cay" và "cay" — khách gọi món "phở", đầu bếp tự nhìn khẩu vị khách (kiến trúc máy) rồi mang đúng bản phù hợp ra, khách không cần tự chỉ định phiên bản nào.
7. Xóa image
Xóa 1 image bằng docker image rm (rm = remove):
$ docker image rm 02674b9cb179
# Output minh họa
Untagged: alpine:latest
Deleted: sha256:02674b9cb17967f2d5619ce33afc9cf1e57c8ceec93ac0f735a4646379857603
Deleted: sha256:59bf1c3509f33380f2d5219cf58d02c161caab7383c7cff6e0aa0f1b81b4d02f
(Output minh họa — 1 dòng Untagged cho tag bị gỡ, cộng thêm 1 dòng Deleted cho mỗi layer bị xóa hẳn khỏi local storage (chỉ xóa layer nào không còn image khác dùng chung).)
Nếu image đang được 1 container dùng (dù đang chạy hay đã dừng), lệnh xóa sẽ thất bại — phải dừng và xóa container liên quan trước. Đây chính là hệ quả trực tiếp của điều đã nói ở Phần 1: image và container phụ thuộc lẫn nhau — không thể xóa image cho tới khi container cuối cùng dùng nó đã dừng và bị hủy.
Xóa toàn bộ image trên host bằng cách kết hợp với docker image ls -q (chỉ in ra ID):
$ docker image rm $(docker image ls -q) -f
# Output minh họa
Untagged: ubuntu:latest
Deleted: sha256:2e6e20c8d7364b312d3f...
Untagged: alpine:latest
Deleted: sha256:02674b9cb17967f2d5619...
Untagged: myteam/webapp:v2
Deleted: sha256:6ac2f0b5a8d4e1c9b03f...
(Output minh họa — 1 cặp Untagged/Deleted cho mỗi image trên host; docker image ls -q trả về toàn bộ Image ID, -f bỏ qua cảnh báo container đang tham chiếu (force).)
Trên Windows, lệnh kết hợp kiểu này chỉ chạy được trong PowerShell, không chạy được ở CMD.
Theo kinh nghiệm vận hành thực tế, phần lớn lỗi liên quan tới image mà kỹ sư mới hay gặp đều xoay quanh 2 hiểu lầm đã nói ở trên: tưởng latest luôn là bản mới nhất, và quên rằng image/container ràng buộc chặt với nhau nên xóa nhầm thứ tự sẽ luôn bị chặn lại. Nắm vững cơ chế layer + digest không chỉ giúp đọc hiểu output các lệnh docker image nhanh hơn, mà còn là nền tảng bắt buộc để hiểu đúng cách Docker build image hiệu quả (multi-stage build, layer caching) ở phần sau.
Đã biết rõ về image — nhưng image chỉ là bản thiết kế nằm yên. Phần tiếp theo mới là lúc bản thiết kế đó thực sự "sống dậy": container.
Danh sách lệnh chính
| Lệnh | Công dụng |
|---|---|
docker image pull <repo>:<tag> | Tải image về từ registry (mặc định Docker Hub); không ghi tag thì mặc định latest |
docker image ls | Liệt kê image trong local cache; thêm --digests để xem SHA256 digest |
docker image inspect <image> | Xem chi tiết đầy đủ metadata + layer của image |
docker image rm <image> | Xóa image; không xóa được nếu còn container (Up hoặc Exited) đang tham chiếu tới nó |
Nguồn tham khảo
Nguồn gốc: Bài viết lấy cảm hứng từ sách "Docker Deep Dive" — tác giả Nigel Poulton (bản phát hành version 4, 3/10/2017), Part 2: The Technical Stuff — chapter 6 "Images". Nội dung được viết lại theo cách hiểu và ví dụ riêng, không sao chép nguyên văn hay dịch sát nguyên bản. Muốn đọc bản đầy đủ hoặc ủng hộ tác giả, có thể mua sách tại leanpub.com/dockerdeepdive.
Đính chính/cập nhật (fact-check):
docker manifest inspectcho phép xem digest/manifest thẳng từ registry từ xa mà không cần pull trước — tính năng experimental từ khoảng Docker 18.03, mặc định bật sẵn (không cần bật experimental) từ Docker 20.10 — 2018–2020, Docker CLI reference — docker manifest- Storage driver
devicemapperđã bị gỡ bỏ hoàn toàn khỏi Docker Engine từ bản 25.0;aufsđang ở trạng thái deprecated, khuyến nghị chuyển sangoverlay2— 2024, Docker Engine — Deprecated features overlay2là storage driver mặc định hiện tại trên các distro Linux được hỗ trợ — Docker Engine — OverlayFS storage driver