Ổ đĩa mạng Files Server SMB bằng Samba
Ở phần trước khi tìm hiểu về chia sẻ file, tạo ổ đĩa tại Chia sẻ dữ liệu giữa các Container , ta đã tạo các ổ đĩa mà dữ liệu ổ đĩa đó được lưu ở máy HOST. Đối với Docker nó chỉ cung cấp các Driver mặc định để tạo được ổ đĩa dạng này, trong trường hợp cần sử dụng các loại ổ đĩa mạng, đặc biệt khi cần dùng trong Service của Docker Swarm thì phải cài thêm các Plugin cho Docker: Các Plugin tại đây Volume plugins , tùy thuộc vào sử dụng dịch vụ ổ đĩa mạng nào (Azure File Storage, AWS EFS ... ) mà cần tìm hiểu cài Plugin tương ứng.
Ở phần này ta sẽ tự tạo ra một Files Server chạy bằng giao thức SMB, cụ thể sẽ sử dụng Samba Server. Trước tiên hãy thực hành kỹ để hiểu về Samba Server tại Sử dụng Samba Server .
Để tạo ra một Container chạy Samba Server, bạn có thể tham khảo Dockerfile để build ra một Image có chức năng này, tham khảo tại: Dockerfile Sambar Server , bạn có thể lấy file đó và các file cùng thư mục về để chỉnh sửa build thành Image của bạn.
Ở đây, tôi đã sử dụng file đó build thành một Image có tên ichte/samba
, nếu chưa muốn
tự build thì bạn có thể lấy ngay Image đó về để chạy:
docker pull ichte/samba
Image này khi chạy thì mặc định nó sẽ cấu hình Samba để tạo thư mục chia sẻ file Samba ở đường dẫn
/home/data/
, nên bạn hãy ánh xạ thư mục cần chia sẻ vào đường dẫn này.
Chạy Container bằng lệnh sau:
docker run -d -p 139:139 -p 145:145 -v /mycode/:/home/data/ --name samba ichte/samba
Lệnh trên tạo ra một container có:
- Tên container là
samba
bạn có thể thay bằng tên khác - Ánh xạ cổng
139, 145
đây là cổng giao thức SMB làm việc - Thư mục ánh xạ trên máy host là
/mycode/
bạn có thể thay bằng thư mục khác (có chmod 777) - Ổ đĩa có thể map bằng đường dẫn
smb://ip-host/mydata
, máy host của tôi đang có IP là192.168.99.107
vậy địa chỉ truy cập sẽ làsmb://192.168.99.107/mydata
, user để đăng nhập có tên do bạn tạo ngay sau đây.
Tạo user đăng nhập SMB
Vào lại Container samba
docker run -it samba bash
Thêm vào một group có tên smbgroup
, sau đó thêm vào user có tên testuser
và gán
group smbgroup
cho user này
groupadd smbgroup useradd testuser usermod -a -G smbgroup testuser chown -R testuser:smbgroup /home/data/
Cuối cùng chạy lệnh sau để lập password cho user testuser
smbpasswd -a testuser
Cuối cùng gõ exit
và khởi động lại container samba
docker restart samba
Bằng cách như vậy, khi container samba chạy bạn có một Files Server ở địa chỉ IP là IP máy host. Có user và IP máy, bạn có thể Map ổ đĩa vào các máy trạm chạy Windows, macOS, Linux ... xem thêm phần Map ổ đĩa mạng SMB
Ở đây ta sẽ tạo ổ đĩa Volume của Container mà nó sử dụng đến SMB
Tạo volume ổ đĩa SBM
Hiện giờ đang có:
- Ổ đĩa mạng chạy bằng Samba ở địa chỉ
192.168.99.107
(thay bằng IP của bạn) - Thư mục file là
192.168.99.107/mydata
- User đăng nhập tên là
testuser
, password do bạn thiết lập ở trên ví dụ 123456
Ta tạo một volume đặt tên là vsmb
mà nó truy cập đến SMB ở trên.
docker volume create \ --driver local \ --opt type=cifs \ --opt device=//192.168.99.107/mydata \ --opt o=username=testuser,password=123456,file_mode=0777,dir_mode=0777 \ --name vsmb
Nhớ thay đúng username, password và IP mà bạn thiết lập. Giờ trong hệ thống Docker có ổ đĩa với tên vsmb
Thử kiểm tra thông tin ổ đĩa này
docker volume inspect vsmb
Kết quả
[ { "CreatedAt": "2019-08-12T09:03:36Z", "Driver": "local", "Labels": {}, "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/vsmb/_data", "Name": "vsmb", "Options": { "device": "//192.168.99.107/mydata", "o": "username=testuser,password=123456,file_mode=0777,dir_mode=0777", "type": "cifs" }, "Scope": "local" } ]
Đó là một ổ đĩa mạng, truy cập qua giao thức SMB, giờ thì container nào muốn sử dụng ổ mạng này chỉ việc mount nó khi tạo container
Ví dụ chạy một container từ busybox, có mount ổ đĩa vsmb trên vào đường dẫn /appdata của container
docker run -it --name testsamba --mount source=vsmb,target=/appdata busybox
Như vậy, Container đã truy cập được một ổ đĩa mạng, bạn có thể áp dụng kỹ thuật này trên Docker Swarm
Ở đây ta sẽ tạo ổ đĩa Volume của Container mà nó sử dụng đến SMB
Sử dụng ổ đĩa mạng SMB trên Swarm
Hãy quay lại thực hành phần Tạo và sử dụng Docker Swarm, nếu khi chạy dịch vụ, bạn có ánh xạ ổ đĩa theo cách thông thường thì sao, ví dụ:
Ví vụ tạo dịch vụ tên httpdtest
trên swam, chạy httpd, có ánh xạ ổ đĩa tên vtest1
vào đường dẫn /home/data
, khởi tạo ngay 5 container
cho dịch vụ này
docker service create --mount src=vtest1,dst=/home/data --replicas 5 -p 8888:80 --name httpdtest httpd
Từ nút manager (leader - vps1) gõ lệnh kiểm tra
docker service ps httpdtest
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jyobv2sry4jz httpdtest.1 httpd:latest vps2 Running Running 4 minutes ago
v9f48ean8cgu httpdtest.2 httpd:latest vps1 Running Running 4 minutes ago
nqlziusjid7x httpdtest.3 httpd:latest vps3 Running Running 4 minutes ago
bbrp08ymb8ns httpdtest.4 httpd:latest vps1 Running Running 4 minutes ago
0mg7py95g7mz httpdtest.5 httpd:latest vps3 Running Running 4 minutes ago
Thấy Swarm đã tạo ra 5 container cho dịch vụ httpdtest
, có 2 chạy trên vps1, 2 container trên vps3,
và 1 container trên vps2
Tuy nhiên với tham số có gán ổ đĩa --mount src=vtest1,dst=/home/data
ở trên, mỗi container khi chạy,
thì tại nút đó sẽ được tạo một ổ đĩa có tên vtest1
, như vậy với 3 nút ở trên, có tới 3 ổ đĩa
độc lập nhau nằm cục bộ trên vps, vì chỉ container nào chạy trên đó mới truy cập được.
Bạn có thể ssh vào từng vps và kiểm tra chúng đều có một volume tên vtest1 bằng lệnh docker volume ls
Có nghĩa là, ở trường hợp cụ thể trên, nếu container httpdtest.2
lưu vào ổ đĩa một file, thì container
httpdtest.4
có thể truy cập được, vì chúng chạy cùng node, tuy nhiên các container khác như httpdtest.1
, httpdtest.5
... thì không truy cập được (do ổ đĩa vtest1
là khác nhau trên các
node khác nhau.)
Bạn có thể ssh vào từng node - rồi vào container chạy dịch vụ, và tạo các file trên ổ đĩa - rồi tự kiểm tra xem.
Trong tình huống, cần mount ổ đĩa, mà dữ liệu chia sẻ giống nhau - trên tất cả các container của dịch vụ chạy trên Swarm, thì cần đến các loại ổ đĩa mạng, và ở đây ta sẽ sử dụng ngay ổ đĩa SMB ở trên.
Xóa dịch vụ httpdtest
và ổ đĩa vtest1
đã tạo, ở node leader (vps1)
docker service rm httpdtest docker volume rm vtest1
Cũng cần vào các node worker (vps2, vps3) bằng lệnh docker-machine ssh vp2
, rồi xóa ổ đĩa đã tạo
docker volume rm vtest1
Tạo ổ đĩa mạng SMB cho dịch vụ trên swarm
Vào từng Node và tạo ra ổ đĩa mạng SMB đặt tên là vtest
docker volume create \ --driver local \ --opt type=cifs \ --opt device=//192.168.99.107/mydata \ --opt o=username=testuser,password=123456,file_mode=0777,dir_mode=0777 \ --name vtest
Chạy lại dịch vụ và mout ổ đĩa trên cho các container
docker service create --mount src=vtest,dst=/home/data --replicas 5 -p 8888:80 --name httpdtest httpd
Giờ thì các container của dịch vụ chạy trên Swarm đều sử dụng một ổ đĩa duy nhất, đảm bảo dữ liệu file giống nhau trên tất các các container.