Thế nào là Docker Volume? Tại sao ta lại cần Docker Volume? Ta dùng Docker Volume khi nào?
Volume là cơ chế ưa thích để tạo ra và sử dụng dữ liệu của Docker. Trong khi việc bind mounts bị phụ thuộc vào cấu trúc thư mục của host machine, thì Volume bị quản lý hoàn toàn bởi Docker.
Dữ liệu trong volume là một thư mục đặc biệt được chỉ định bên trong một hoặc nhiều container bằng việc bỏ ổ lưu trữ của Docker và tương tác trực tiếp với file hệ thống.
Docker Volume cung cấp một vài tính năng hữu ích cho persistent và shared data:
Docker Volume được khởi tạo khi container được tạo ra. Nếu image nền của container chứa dữ liệu ở một vị trí chỉ định, dữ liệu đã tồn tại đó sẽ được copy sang một vùng nhớ khác trên volume vừa được khởi tạo.
Dữ liệu volume được chia sẻ và sử dụng giữa nhiều container.
Các thay đổi trên volume sẽ được chia sẻ với file hệ thống của host.
Các thay đối trên volume sẽ xảy ra khi bạn cập nhật một image.
Dữ liệu cố định trên volume dù container có tự xóa.
Dữ liệu trên volume được thiết kế cho persist data, không phụ thuộc vào lifecycle của container. Docker không bao giờ tự động xóa volume khi bạn xóa container đó, cũng như sẽ không garbage collect những volume không được dung bởi container.
Làm việc với Docker Volumes
Không có cách nào để trực tiếp tạo ra một “data volume” trong Docker, nên thay vì đó chúng ta tạo ra một container data volume với một volume gắn liền với nó. Đối với bất kỳ container khác sau đó bạn muốn kết nối với data volume này, sử dụng tùy chọn Docker –volumes-from để lấy volume từ container này và áp dụng chúng vào các container hiện tại.
Đầu tiên, tạo một container data volume mới để lưu trữ volume của chúng ta:
docker create -v /tmp --name datacontainer ubuntu
Điều này tạo ra một container tên datacontainer dựa trên ubuntu image trong thư mục /tmp.
Bây giờ, nếu chúng ta chạy một container Ubuntu mới với tùy chọn –volumes-from và chạy bash như chúng ta đã làm trước đó, bất cứ thứ gì chúng ta để ở thư mục /tmp sẽ được lưu vào thư mục /tmp volume của container datacontainer của chúng ta.
Đầu tiên,start ubuntu image:
docker run -t -i --volumes-from datacontainer ubuntu /bin/bash
Tùy chọn dòng lệnh -t chạy terminal trong container. Tùy chọn -i tạo các kết nối tương tác.
Tạo ra một tập tin trong / tmp:
echo "I'm not going anywhere" > /tmp/hi
Gõ exit để trở về với máy chủ của bạn. Bây giờ, chạy lại lệnh trên:
docker run -t -i --volumes-from datacontainer ubuntu /bin/bash
Lần này tập tin hi đã có:
cat /tmp/hi
Bạn sẽ thấy:
Output of cat /tmp/hi
I'm not going anywhere
Bạn có thể thêm bao nhiêu –volumes-from tùy bạn muốn (ví dụ, nếu bạn muốn lắp ráp một container sử dụng dữ liệu từ nhiều data containers). Bạn cũng có thể tạo ra nhiều data container volume như bạn muốn.
Với phương pháp này bạn chỉ có thể chọn path gắn kết bên trong container (/ tmp trong ví dụ của chúng ta) khi bạn tạo data volume container.
Chia sẻ dữ liệu giữa các máy chủ và các Docker container
Một công việc phổ biến khác của Docker containers là chia sẻ file giữa máy chủ và Docker containers. Điều này hoạt động khác với ví dụ cuối cùng. Không cần tạo ra một “data-only” container. Bạn có thể chạy một container của Docker image bất kỳ và ghi đè lên một trong các thư mục của nó các nội dung của một thư mục trên hệ thống máy chủ.
Một ví dụ thực tế , bạn muốn sử dụng Docker Nginx image nhưng bạn muốn giữ một bản sao vĩnh viễn các file log của Nginx để phân tích sau đó. Theo mặc định, log Docker Nginx image được ghi vào thư mục /var/log/nginx, nhưng đây là /var/log/nginx trong container Docker Nginx. Thông thường không thể truy cập từ các hệ thống tập tin host.
Hãy tạo ra một thư mục để lưu trữ các bản ghi của chúng ta và sau đó chạy một bản sao của Nginx image với một volume chia sẻ để Nginx viết các logs của nó tới hệ thống tập tin máy chủ của chúng ta thay vì vào /var/log/nginx bên trong container:
mkdir ~/nginxlogs
Sau đó start container:
docker run -d -v ~/nginxlogs:/var/log/nginx -p 5000:80 -i nginx
lệnh chạy này có chút khác biệt nên chúng ta sẽ chia ra phân tích:
v ~/nginxlogs: /var/log/nginx - Chúng tôi thiết lập một volume liên kết thư mục /var/log/nginx trong container Nginx vào thư mục ~/nginxlogs trên máy chủ.
-d - Bỏ process và chạy ở chế độ nền. Nếu không, chúng tôi sẽ chỉ được xem một Nginx trống và sẽ không thể sử dụng terminal cho đến khi chúng ta kill Nginx.
-p 5000: 80 - Thiết lập một cổng chuyển tiếp. Các container Nginx sẽ lắng nghe trên cổng 80 theo mặc định, và kết nối công 80 của Nginx container đến cổng 5000 trên hệ thống máy chủ.
Nếu bạn chú ý, bạn cũng có thể nhận thấy một sự khác biệt với các lệnh chạy trước. Cho đến bây giờ chúng ta đã xác định một lệnh vào cuối mỗi lệnh chạy của chúng ta (thường là / bin/bash) để cho Docker chạy terminal. Bởi vì Nginx image là một image Docker chính thức, và tác giả đã thiết lập các chạy các lệnh bắt đầu Nginx một cách tự động.
Vì vậy, bây giờ chúng ta có một bản sao của Nginx chạy bên trong một container Docker trên máy tính của chúng ta, và máy chủ của chúng ta có cổng 5000 map trực tiếp với cổng 80 của bản sao của Nginx. Hãy sử dụng curl kiểm tra nhanh:
curl localhost:5000
Bạn tạo 1 file HTML và chạy trên Nginx.Khi bạn xem thư mục ~/nginxlogs trên máy chủ và hãy nhìn vào các tập tin access.log bạn sẽ thấy một thông báo đăng nhập từ Nginx:
cat ~/nginxlogs/access.log
Bạn sẽ thấy một cái gì đó tương tự như:
172.17.42.1 - - [23/Oct/2015:05:22:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-"
Nếu bạn thực hiện bất kỳ thay đổi vào thư mục ~/nginxlogs, bạn sẽ có thể nhìn thấy chúng từ bên trong container Docker.