This page looks best with JavaScript enabled

Tìm hiểu và sử dụng docker (P2)

 ·  ☕ 11 min read  ·  🐉 Edisc
Toàn bộ series này được tham khảo từ hai nguồn chính: XuanThuLabChanelDockerDoc. Em xin chân thành cảm ơn sự cống hiến của các tác giả của những kênh nói trên.❤️❤️❤️

Lệnh Docker exec, lưu container thành image với commit, xuất image ra file

Docker exec

Thông thường, để thực thi một lệnh trong container, ta sẽ vào container bằng lệnh docker attach <container name or id>. Tuy nhiên, nếu ta đang ở host và vẫn muốn thực thi một lệnh bên trong container đang chạy, ta sẽ dùng lệnh docker exec <container id / name> [COMMAND].
Ví dụ, từ host, ta chạy lệnh ls để liệt kê tất cả các file trong container.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
❯ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6d1aa3dda644        ubuntu:latest       "/bin/bash"         3 minutes ago       Up 3 minutes                            test
❯ docker exec test ls
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

Ngoài ra cũng vẫn có thể thêm các option, ví dụ:

1
2
❯ docker exec -it test bash
root@ubuntu1:/# 

Lệnh trên yêu cầu thực thi lệnh bash và thêm option -it để có thể tương tác trực tiếp với terminal, dễ dàng thấy, nó khá giống với lệnh docker attach, tuy nhiên, khi mở các process trong container bằng htop, chúng ta sẽ thấy như sau:
docker_exec_htop
Rõ ràng, ở đây có ngoài process /bin/bash có khi tạo, container còn chạy thêm một process bash, process này chính là lệnh mà chúng ta yêu cầu thực thi từ máy host. Sau khi thực hiện lệnh docker exec -it test bash, ta gõ lệnh exit để thoát khỏi container, tuy nhiên, vì container vẫn còn process /bin/bash nên nó vẫn còn hoạt động chứ không bị tắt đi.

Docker commit

Sau khi cài docker và sử dụng, chúng ta có thể phải cài thêm nhiều phần mềm, môi trường khác nhau. Khi đó, để chia sẻ container này đi, ta cần lưu container này thành image. Để làm việc đó, ta sử dụng lệnh container commit.
Trước khi lưu container trở thành image, ta kiểm tra xem trong hệ thống có những image nào:

1
2
3
4
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB

Một điều lưu ý, muốn lưu container thành image, thì container đó phải ở trạng thái dừng (Exited).

1
2
3
4
❯ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
6d1aa3dda644        ubuntu:latest       "/bin/bash"         23 minutes ago      Exited (0) 4 minutes ago                       test
ddf68933af54        centos:latest       "/bin/bash"         16 hours ago        Exited (0) 16 hours ago                        centos_docker

Tiến hành lưu container thành images, ta dùng cú pháp: docker commit CONTAINER image:tag. CONTAINER ở đây là tên hoặc id của container.
Ví dụ, container ubuntu vừa rồi tôi đã cài thêm ping với vim, bây giờ lưu lại thành image, ta thực hiện:

1
2
3
4
5
6
7
❯ docker commit test ubuntu-pv:version1
sha256:a8e04dcf8737519e456dcedd646983a5d69d97ea85f5e3517b537b2b1a86ef0a
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-pv           version1            a8e04dcf8737        5 seconds ago       170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB

Rõ ràng, sau khi thực hiện lệnh trên, chúng ta sẽ thấy trong danh sách các images có thểm một image có thên là ubuntu-py với TAG là version1 cùng ID và các thông tin khác.

Docker save

Sau khi ta lưu container thành một image, để có thể chia sẻ image này với người khác, ta lưu image thành một file trên máy host. Việc này sẽ được thực hiện thông qua lệnh docker save --output filename.tar <image_id/name>.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
❯ ls
'IDA Freeware.desktop'   PinImage   tmp
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-pv           version1            a8e04dcf8737        6 minutes ago       170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker save --output ubuntu-pv.tar a8
❯ ls
'IDA Freeware.desktop'   PinImage   tmp   ubuntu-pv.tar

Ví dụ trên tôi đã lưu ubuntu-pv image thành ra file ubuntu-pv.tar.

Docker load

Sau khi nhận được file image.tar, để phục hồi hoặc sử dụng lại, ta sử dụng lệnh docker load -i image.tar
Ví dụ, tôi tiến hành xóa đi ubuntu-pv image hiện có trên hệ thống. Lệnh thao tác với image bạn có thể xem ở P1.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-pv           version1            a8e04dcf8737        11 minutes ago      170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker image rm -f ubuntu-pv:version1
Untagged: ubuntu-pv:version1
Deleted: sha256:a8e04dcf8737519e456dcedd646983a5d69d97ea85f5e3517b537b2b1a86ef0a
❯ docker image rm ubuntu:latest
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:adf73ca014822ad8237623d388cedf4d5346aa72c270c5acc01431cc93e18e2d
Deleted: sha256:7e0aa2d69a153215c790488ed1fcec162015e973e49962d438e18249d16fa9bd
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              300e315adb2f        6 months ago        209MB

Bây giờ, ta tiến hành phục hồi ubuntu-pv image từ file ubuntu-pv.tar đã có ở trước đó.

1
2
3
4
5
6
7
8
❯ ls
'IDA Freeware.desktop'   PinImage   tmp   ubuntu-pv.tar
❯ docker load -i ubuntu-pv.tar
Loaded image ID: sha256:a8e04dcf8737519e456dcedd646983a5d69d97ea85f5e3517b537b2b1a86ef0a
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              a8e04dcf8737        14 minutes ago      170MB
centos              latest              300e315adb2f        6 months ago        209MB

Khi phục hồi, tên của image và tag của nó sẽ là <none>. Để đặt tên và tag, ta dùng lệnh:
docker tag image_id name:tag.

❯ docker tag a8 newimage:version2
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        16 minutes ago      170MB
centos              latest              300e315adb2f        6 months ago        209MB

Chia sẻ dữ liệu trong Docker, tạo và quản lý ổ đĩa docker volume

Chia sẻ dữ liệu giữa máy host và container

Trên máy host, tôi tổ chức cây thực mục như sau:

1
2
3
4
.
├── docker
│   └── data
│       └── d.txt

Mục tiêu của chúng ta là để container có thể truy cập và thao tác với dữ liệu ở trong data, và khi container bị xóa đi, dữ liệu không bị mất.
Chúng ta tạo mới một container và trong lúc tạo sẽ chỉ rõ thực mục ánh xạ trên host và thực mục được ánh xạ ở đâu trên container.
docker run -it -v <thu/muc/tren/host>:<thu/muc/anh/xa/tren/container> <image id>

1
2
3
4
5
6
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        28 minutes ago      170MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker run -it -v /home/edisc/Desktop/docker/data:/home/shared_data a8
root@d4d24f24bbe6:/#

Chúng ta tiến hành kiểm tra:

1
2
3
4
root@d4d24f24bbe6:/# cd /home/shared_data/
root@d4d24f24bbe6:/home/shared_data# ls
d.txt
root@d4d24f24bbe6:/home/shared_data# 

Như vậy, dữ liệu đã được ánh xạ và mọi thao tác trên dữ liệu ở thư mục này sẽ được lưu vào host.

Chia sẻ dữ liệu giữa các container với nhau

Chúng ta tạo lại một container có tên là container1 ánh xạ tới dữ liệu Desktop/docker/data, và tạo một container2 muốn ánh xạ tới dự liệu này, thay vì dùng lệnh tạo như container1, ta có thể dùng --volumes-from <container_name/id>

1
2
3
4
5
6
7
8
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        36 minutes ago      170MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker run -it -v /home/edisc/Desktop/docker/data:/home/shared_data --name "container1" a8
root@b62e5d395369:/# %                                                          
❯ docker run -it --name container2 --volumes-from container1 centos
[root@e1103acb0525 /]#

Chia sẻ qua volume

Bên cạnh việc chia sẻ dữ liệu bằng cách tạo các file dữ liệu, docker còn cho phép chúng ta tạo ra những ổ đĩa, gán vào container và để chia sẻ dữ liệu giữa chúng. Cũng như file, khi container xóa thì những ổ đĩa này vẫn còn tồn tại cho đến khi chúng ta cố tình xóa nó.

Kiểm tra các ổ đĩa hiện có

Để kiểm tra các ổ đĩa hiện có, ta dùng lệnh:

1
2
❯ docker volume ls
DRIVER              VOLUME NAME

Hiện tại trên hệ thống không có ổ đĩa nào.

Tạo ổ đĩa

Để tạo một ổ đĩa mới, ta dùng lệnh: docker volume create NAMEDISK.

1
2
3
4
5
❯ docker volume create D1
D1
❯ docker volume ls
DRIVER              VOLUME NAME
local               D1

Kiểm tra thông tin ổ đĩa

Để kiểm tra thông tin ổ đĩa ta dùng lệnh docker volume inspect NAMEDISK.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
❯ docker volume inspect D1
[
    {
        "CreatedAt": "2021-06-08T10:06:13+07:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/D1/_data",
        "Name": "D1",
        "Options": {},
        "Scope": "local"
    }
]

Xóa ổ đĩa

Khi không có nhu cầu sử dụng, ta sử dụng lệnh docker volume rm NAMEDISK.

1
2
3
4
5
6
7
8
9
❯ docker volume ls
DRIVER              VOLUME NAME
local               D1
local               D2
❯ docker volume rm D1
D1
❯ docker volume ls
DRIVER              VOLUME NAME
local               D2

Gán ổ đĩa volume vào container

Ta sử dụng cú pháp:
docker run -it --mount source=DISK,target=pathContainer imageID

1
2
3
4
5
6
7
8
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        About an hour ago   170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker run -it --mount source=D2,target=/home/disk2 ubuntu:latest
root@524a1182f690:/# cd /home/disk2/
root@524a1182f690:/home/disk2#

Ta tiến hành thêm dữ liệu trong thư mục trên, sau đó xóa container đi, và thấy, ổ đĩa vẫn còn.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        About an hour ago   170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker run -it --mount source=D2,target=/home/disk2 ubuntu:latest
root@524a1182f690:/# cd /home/disk2/
root@524a1182f690:/home/disk2#
❯ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                        PORTS               NAMES
524a1182f690        ubuntu:latest       "/bin/bash"         About a minute ago   Exited (0) 23 seconds ago                         cocky_mclaren
e1103acb0525        centos              "/bin/bash"         19 minutes ago       Exited (127) 11 minutes ago                       container2
b62e5d395369        a8                  "/bin/bash"         21 minutes ago       Exited (0) 11 minutes ago                         container1
❯ docker rm 52
52
❯ docker volume ls
DRIVER              VOLUME NAME
local               D2

Vậy làm sao để truy xuất dữ liệu hiện có trên D2 hoặc kiểm tra xem có dữ liệu trên đó hay không? Để làm được điều đó, chúng ta tạo một container khác, mount tới D2 và kiểm tra.

1
2
3
4
5
❯ docker run -it --mount source=D2,target=/home/disk3 ubuntu:latest
root@ca47e1855144:/# cd /home/disk3/
root@ca47e1855144:/home/disk3# ls
data.txt
root@ca47e1855144:/home/disk3# 

Dữ liệu do container trước đã tạo và lưu vào, dữ liệu này vẫn còn mặc dù container đã xóa đi.

Tạo ổ đĩa ánh xạ tới thư mục trên máy host.

Cú pháp:
docker create --opt device =pathHOST --opt type=noe --opt o=bind DISKNAME

1
2
3
4
5
6
❯ docker volume create --opt device=/home/edisc/Desktop/docker/data --opt type=none --opt o=bind DISK1
DISK1
❯ docker volume ls
DRIVER              VOLUME NAME
local               D2
local               DISK1

Thông tin ổ đĩa có được như sau:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
❯ docker volume inspect DISK1
[
    {
        "CreatedAt": "2021-06-08T10:27:56+07:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/DISK1/_data",
        "Name": "DISK1",
        "Options": {
            "device": "/home/edisc/Desktop/docker/data",
            "o": "bind",
            "type": "none"
        },
        "Scope": "local"
    }
]

Để chạy container với tham số này ta không sử dụng tùy chọn --mount mà ta sẽ sủ dụng tùy chọn -v.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
❯ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
newimage            version2            a8e04dcf8737        About an hour ago   170MB
ubuntu              latest              7e0aa2d69a15        6 weeks ago         72.7MB
centos              latest              300e315adb2f        6 months ago        209MB
❯ docker run -it -v DISK1:/home/disk4 ubuntu:latest
root@e94027a36d5b:/# cd /home/disk4/
root@e94027a36d5b:/home/disk4# ls
c1.txt  d.txt  data_container2.txt
root@e94027a36d5b:/home/disk4# 

Vào thư mục và kiểm tra, ta vẫn thấy nó có các dữ liệu ở trên máy host. Và khi thao tác dữ liệu trên này, dữ liệu trên máy host cũng sẽ được cập nhât.

Kết luận

Trong bài học này, chúng ta đã học được từ anh XuanThuLabChanel những kiến thức như sau:
Các lệnh Docker exec, lưu container thành image với commit, xuất image ra file:

  • docker exec: thực thi một lệnh bên trong container đang chạy từ host.
  • docker commit: lưu container thành image
  • docker save: lưu image thành file.
  • docker load: chuyển file thành image.
    Chia sẻ dữ liệu trong Docker, tạo và quản lý ổ đĩa docker volume:
  • Chia sẻ dữ liệu qua tệp:
    • Container với host
    • Giữa container với nhau.
  • Chia sẻ dữ liệu qua ổ đĩa disk: các thao tác với volume thông qua lệnh docker volume kèm các option tương ứng.
    Kết thúc bài viết này, một lần nữa em xin chân thành gửi lời cảm ơn đến anh XuanThuLabChanel đã làm những bài học quý giá và bổ ích này.
Share on

Edisc
WRITTEN BY
Edisc
Cyber Security Engineer

 
What's on this Page