Mở file để mount và chạy là làm gì năm 2024

Bizfly Cloud luôn gợi ý bạn sử dụng một ổ rootdisk (lưu trữ hệ điều hành) và một datadisk (lưu trữ web, database…). Với nhu cầu mở rộng hay giảm dữ liệu lưu trữ, bạn có thể tăng giảm dung lượng datadisk mà downtime chỉ trong vòng vài giây so với việc tăng giảm rootdisk trong vòng 1-2 phút. Hơn thế nữa, khi muốn thay thế bằng một server mới, bạn chỉ cần gỡ volume ra khỏi server cũ và gắn vào server mới.

1. Tạo file system và mount vào thư mục cần dùng

Sau khi đã gắn volume vào server, bạn cần tiến hành tạo file system và mount volume vào thư mục cần dùng để sử dụng. Ở đây tôi mount vào thư mục /data. Tại terminal (cửa sổ lệnh) sau khi đã kết nối được vào server, chạy lệnh:

# fdisk -l

Disk /dev/vda: 42.9 GB, 42949672960 bytes
188 heads, 9 sectors/track, 49578 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000191bb

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        4096    83885975    41940940   83  Linux

Disk /dev/vdb: 21.5 GB, 21474836480 bytes
16 heads, 63 sectors/track, 41610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/vdb doesn't contain a valid partition table

Check xem volume vừa gắn vào device nào? Ví dụ ở đây là /dev/vdb. Thực hiện tạo file system và mount vào thư mục cần dùng:

# mkfs.ext4 /dev/vdb
# mount /dev/vdb /data

Nếu bạn ko muốn dùng Ext4 vì một lý do nào đó, Bizfly Cloud khuyến cáo bạn nên dùng Btrfs hoặc XFS vì đây là 2 filesystem đã stable cũng như có khả năng resize khi bạn muốn tăng dung lượng Volume.

2. Cấu hình mount trong /etc/fstab

Để cấu hình server tự động nhận volume sau khi reboot, cấu hình file /etc/fstab theo yêu cầu bạn cần dùng, chúng tôi gợi ý một cách đơn giản nhất. Đầu tiên, lấy UUID của volume:

# blkid
/dev/vda1: UUID="2941549e-cb5f-4a51-9c78-08f21cd7f919" TYPE="ext4"
/dev/vdb: UUID="60d49769-daa6-4438-bb7c-c20a6377768c" TYPE="ext4"

UUID của volume vừa gắn thêm là 60d49769-daa6-4438-bb7c-c20a6377768c, chúng ta sẽ dùng UUID này để cấu hình mount trong fstab.

Mount bằng UUID của volume sẽ đảm bảo volume của bạn luôn được mount chính xác tới thư mục cấu hình, việc sử dụng các device name như /dev/vdb sẽ không thực sự đúng trong quá trình sử dụng lâu dài với nhiều thao tác gắn, gỡ volume khỏi server vì tên này có thể thay đổi.

Thêm vào file /etc/fstab dòng lệnh:

UUID=60d49769-daa6-4438-bb7c-c20a6377768c  /data  ext4  defaults  0  0

Lưu lại file và chạy lệnh:

Nếu có lỗi phát sinh, không reboot lại server để tránh tình trạng server không thể khởi động. Kiểm tra cấu hình trong file /etc/fstab và chạy lại lệnh cho tới khi không có thông báo lỗi.

Ban đầu -v hoặc -mount flat được dùng cho standalone container và -mount flag được dùng cho swarm service. Tuy nhiên phiên bản Docker 17.06 bạn có thể sử dụng -mount flag cho standalone container. Nói chung điểm khác biệt duy nhất chính là cú pháp. Trong khi -v flag, các option được làm một thì -mount flag lại phân chia chung rõ ràng hơn với từng option các nhau bởi dấu phẩy. Trong bài viết này minh sử dụng option là -v và -mount.

Volumes

  • Về hoạt động Volumes tưng tự như Bind Mounts, những Volume được quản lý bời Docker. Trong khi Bind Mounts, file hoặc thư muc cần mount phải tồn tại trên docker host.
  • Volume khi tạo ra sẽ nằm ở thư mục /var/lib/docker/volumes/Volume khi tạo sẽ nằm ở thư mục.
  • Volume cũng support cơ chế của volume drivers, cho phép lưu trữ dữ liệu tới một server remote hoặc Cloud …
  • Bạn có thể quản lý volume sử dụng CLI hoặc API.
  • Volume hoạt động trên cả Linux và Windows container

Sử dụng Volume khi nào ?

  • Khi chia sẻ dữ liệu giữa nhiều container đang chạy.
  • Lưu dữ liệu tới một server remote hoặc cloud.
  • Khi cần backup, restore hoặc migrate dữ liệu từ Docker Host này sang Docker Host khác.
  • Cần quản lý dễ dàng và thuận tiện hơn so với bind mounts.

Ví dụ

Tạo một volume và chạy container mount với volume đó

  1. Tạo Volume

docker volume create my-volume    ## Tạo một volume
docker volume ls                  ## List danh sách volume
docker volume inspect my-volume   ## Hiển thị thông tin của Volume
ll /var/lib/docker/volumes        ## Kiểm tra volume được tạo ra

  1. Chạy container với volume

docker run -itd -v my-volume:/opt/mount_point/ centos
# Hoặc 
docker run -itd --mount type=volume,src=my-volume,dst=/opt/mount_point/ centos
# Hoặc
docker run -itd --mount type=volume,source=my-volume,target=/opt/mount_point/ centos

  1. Kiểm tra lại

docker exec my-container bash -c "echo 'This is test file' > /opt/mount_point/test.txt"
docker exec my-container bash -c "cat /opt/mount_point/test.txt"
cat /var/lib/docker/volumes/my-volume/_data/test.txt

Một số chú ý với volume

  • Nếu bạn mount một volume vào trong một thư mục của container, mà thư mục của container này đã có dữ liệu thì dữ liệu từ container sẽ được copy vào volume mount-point của docker host
  • Thông thường nếu bạn không tạo volume từ trước mà chạy container với volume mount thì Docker sẽ tự động tạo một volume và dữ liệu sẽ vẫn tồn tại ngoài vòng đời của container. Ví dụ:

docker run -itd --name webapp --mount source=webapp-vol,destination=/var/ centos

  • Volume thường là sự lựa chọn tốt hơn là sử dụng wriable layer của Container. Bởi vì sử dụng Volume không làm tăng dung lượng của container sử dụng.

bind mounts

Bind mounts trong Docker xuất hiện trước Volume. Bind mounts bị giới hạn một số các tính năng hơn so với volume. Binds mount có hiệu năng tốt nhưng bị phụ thuộc vào cấu trúc filesystem của Docker host. Khi sử dụng bind mount thì một file hoặc một folder trong docker host được mount vào trong container. File hoặc Folder này yêu cầu đường dẫn tuyệt đối. Vậy nên, trong trường hợp file hoặc folder này không tồn tại trên docker host, thì quá trình mount sẽ bị lỗi.

Sử dụng bind mounts khi nào ?

  • Khi chia sẻ file cấu hình từ docker host với container.
  • Chia sẻ thư mục source code hoặc môi trường từ docker host với container.
  • Khi cấu trúc filesystem của docker host là rõ ràng và phù hợp với các yêu cầu của bind mount.

Ví dụ

Chạy một container với bind mounts theo hai cách:

  1. Sử dụng flag -v Khi sử dụng flag -v nếu source folder trên docker host chưa tồn tại, Docker sẽ tự động tạo mới folder

docker run -itd --name my_contanier -v /opt/docker_host_folder/:/opt/ centos
docker exec my_contanier bash -c "touch /opt/duckhang"
ll /opt/docker_host_folder

  1. Sử dụng flag –mount Khi sử dụng flag –mount, thì đảm bảo folder trên docker host đã được tồn tại, nếu không sẽ bị lỗi

mkdir -p /opt/docker_host_folder
docker run -itd --name my_contanier --mount type=bind,src=/opt/docker_host_folder,dst=/opt/ centos
docker exec my_contanier bash -c "touch /opt/duckhang"
ll /opt/docker_host_folder

Một số chú ý với binds mount

  • Khi sử dụng bind mounts và flag –mount thì phải đảm bảo file hoặc folder từ docker host đã được tồn tại.
  • Không giống như volume, nếu folder trong Container “không trống” và được mount với folder của docker host thì tất cả các file trong folder của container sẽ bị ẩn đi. Điều này giống với khi bạn save dữ liệu của mình trong /mnt, sau đó cắm USB và mount USB với thư mục /mnt thì những file dữ liệu có từ trước sẽ bị ẩn đi đến khi USB được umount. Để test trường hợp này mình có một ví dụ sau:
  • Tạo một Image từ Dockerfile đảm bảo rằng có một folder “không trống” khi chạy container.

cd ~
mkdir create_image && cd create_image
cat <<EOF > Dockerfile FROM centos:centos7
  LABEL "image-type"="duckhang-test"
  MAINTAINER duckhang
  RUN mkdir /opt/test_folder && \
      touch /opt/test_folder/test_file.txt
EOF
docker build -t image-test .
docker images

  1. Chạy một container và đảm bảo image tạo ra một container có một folder “không trống”

docker run -itd --name test_container image-test
docker exec test_
container bash -c "ls /opt/test_folder/"

  1. Chạy contaier sử dụng chính image đó với bind mounts và kiểm tra thư mục mount

mkdir /opt/docker_host_folder
docker run -itd --privileged --name another_container --mount type=bind,src=/opt/docker_host_folder,dst=/opt/test_folder/ image-test
docker exec another_container bash -c "ls /opt/test_folder/"

  1. Unmount thư mục trong container và kiểm tra lại

docker exec another_container bash -c "umount  /opt/test_folder/"
docker exec another_container bash -c "ls /opt/test_folder/"

test_file.txt

tmpfs

Volumes và bind mounts cho phép bạn chia sử dữ liệu giữa docker host và container kể cả khi container bị stop hoặc xóa đi. Nếu bạn sử dụng Docker trên Linux thì bạn có một option thứ ba là tmpfs mounts

Sử dụng tmpfs mounts khi nào ?

  • Khi bạn không muốn giữ data trên docker host hoặc trong container.
  • Khi muốn bảo mật, hoặc muốn đảm bảo hiệu suất container khi ứng dụng cần ghi một số lượng lớn dữ liệu không liên tục.
  • tmpfs mount sẽ lưu dữ liệu tạm thời trên memory. Khi container stop, tmpfs mount sẽ bị xóa bỏ.

Ví dụ

docker run -itd -v my-volume:/opt/mount_point/ centos
# Hoặc 
docker run -itd --mount type=volume,src=my-volume,dst=/opt/mount_point/ centos
# Hoặc
docker run -itd --mount type=volume,source=my-volume,target=/opt/mount_point/ centos

0

test.txt

Restart container và kiểm tra lại

docker run -itd -v my-volume:/opt/mount_point/ centos
# Hoặc 
docker run -itd --mount type=volume,src=my-volume,dst=/opt/mount_point/ centos
# Hoặc
docker run -itd --mount type=volume,source=my-volume,target=/opt/mount_point/ centos

1

Kết quả trả về là trắng tinh

Tổng kết

Như vậy trong bài viết này mình đã giới thiệu một thành phần quan trọng trong Docker đó là Docker Storage. Docker Storage có 3 option cho bạn lựa chọn là volumes, bind mounts, tmpfs mounts. Nếu có vấn đề gì thì comment ở dưới để cùng trao đổi nhé.