Ổ đĩ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.

Đăng ký theo dõi ủng hộ kênh