Docker¶
Tham khảo¶
Khái niệm cơ bản¶
Bức tranh chung về VM và container xem ở Virtualization Overview. Nhiều container cùng nhau xem Docker Compose.
- Image: bản đóng gói chỉ đọc gồm filesystem và metadata (lệnh mặc định, biến môi trường...). Image được tạo từ nhiều layer xếp chồng, layer giống nhau được dùng chung và cache lại giữa các image.
- Container: một tiến trình (hoặc nhóm tiến trình) chạy từ image, có thêm một lớp ghi (writable layer) ở trên cùng. Xóa container thì lớp ghi này mất theo, dữ liệu cần giữ phải đặt ở volume hoặc bind mount.
- Registry: nơi lưu và phân phối image (Docker Hub, GHCR, registry riêng...). Image được định danh bằng
repo:tag.
Container dùng chung kernel của host và được cô lập bằng namespace và cgroups (chi tiết ở Container Internals), nên khởi động nhanh và nhẹ hơn VM nhưng độ cô lập yếu hơn một hypervisor (xem Hypervisor & Hyper-V). Hệ quả thực tế: container Linux chỉ chạy được kernel Linux của host, và các cờ như --privileged làm yếu đáng kể lớp cô lập này.
Cài đặt¶
Cài đặt Docker Engine trên Ubuntu: https://docs.docker.com/engine/install/ubuntu/
Chạy container¶
docker run/start/attach¶
Script dưới đây tạo container từ image ubuntu:20.04 nếu chưa tồn tại, ngược lại thì start (nếu đang Exited) và attach vào container đã có. Container dùng chung user, thư mục $HOME và thư mục làm việc hiện tại với host nên rất tiện cho việc build (ví dụ Petalinux/Yocto).
#!/bin/bash
WRDIR=`pwd`
echo $WRDIR
docker_image_version=20.04
docker_repo=ubuntu
container_name=${docker_repo}_${docker_image_version}
if ! docker ps -a | grep -q $container_name; then
docker run -t -i -h vubuntu-docker --name=$container_name \
--privileged=true --net=host \
-u `id -u`:`id -g` \
-v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro \
-v /etc/shadow:/etc/shadow:ro -v $HOME:$HOME \
-v /lib/modules:/lib/modules -v /dev:/dev \
-v /mnt:/mnt \
-v $WRDIR:$WRDIR \
-w $WRDIR $docker_repo:$docker_image_version /bin/bash
elif docker ps -a | grep $container_name | grep -q Exited; then
docker start $container_name
docker attach $container_name
else
docker attach $container_name
fi
docker detach¶
Thoát khỏi container nhưng vẫn để container chạy: Ctrl + P rồi Ctrl + Q.
docker exec¶
Mở thêm một shell trong container đang chạy:
Build image¶
Dockerfile mẫu và lưu ý khi build cho môi trường Petalinux/Yocto xem Docker cho môi trường build.
Quản lý container và image¶
Xem trạng thái¶
docker ps # container đang chạy
docker ps -a # tất cả container, kể cả Exited
docker images # image trên máy
docker logs -f <container>
docker inspect <container>
Dừng và xóa¶
Copy file giữa host và container¶
Dọn dung lượng¶
Build Yocto/Petalinux tạo ra image và layer rất lớn, nên dung lượng đĩa dễ đầy.
docker system df # xem dung lượng Docker đang chiếm
docker image prune # xóa image dangling
docker container prune # xóa container đã dừng
docker system prune -a # xóa tất cả thứ không được dùng (cẩn thận)
Warning
docker system prune -a xóa mọi image không có container nào đang dùng, kể cả image đã mất nhiều giờ để build. Hãy docker push hoặc docker save trước nếu cần giữ lại.
Volume và bind mount¶
Dữ liệu trong lớp ghi của container sẽ mất khi container bị xóa. Có hai cách chính để giữ dữ liệu hoặc chia sẻ với host:
| Bind mount | Named volume | |
|---|---|---|
| Cú pháp | -v /host/path:/container/path |
-v myvol:/container/path |
| Vị trí lưu | Đường dẫn bất kỳ trên host | Do Docker quản lý (/var/lib/docker/volumes) |
| Dùng khi | Chia sẻ source code, thư mục build với host | Dữ liệu của ứng dụng (database...) |
Một số lưu ý với bind mount:
- File tạo trong container mang UID/GID của user chạy trong container. Nếu chạy bằng root thì file trên host sẽ thuộc root. Đây là lý do script ở trên dùng
-u $(id -u):$(id -g), kèm mount/etc/passwdvà/etc/groupđể container nhận ra user host. - Thêm
:rođể mount chỉ đọc, ví dụ-v /etc/passwd:/etc/passwd:ro. - Trên host bật SELinux (Fedora/RHEL) cần thêm
:zhoặc:Z. - Mount cả
$HOMErất tiện nhưng container có thể đọc/ghi mọi thứ trong đó (kể cả~/.ssh), chỉ nên dùng trên máy dev tin cậy.
Docker Hub¶
Tạo account Docker Hub bằng tài khoản GitHub. Đẩy image lên Docker Hub:
Ví dụ: