如何在兩個SQL Server on Linux的Container之間共用同一個Docker Volume

本篇來記錄一下如何在兩個SQL Server on Linux的Container之間共用同一個Docker Volume,藉以分享檔案(例如: 資料庫備份檔),另外,同時也都可以擁有各自的Volume,用來保存自己所屬的SQL Server資料庫檔案。

<情境一> 為兩個容器設定共用的Volume,藉以分享檔案

--(1)先加入第一個容器"sql5"
--設定volume名稱為"sqlvolume5",對應到容器"sql5"中的目錄"/var/opt/mssql/data2"
# docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=xxxxxxxx' --name=sql5 -p 1455:1433 -v sqlvolume5:/var/opt/mssql/data2 -d mcr.microsoft.com/mssql/server:2017-latest
# docker ps    --狀態為"Up"
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONTAINER ID        IMAGE                                        COMMAND                  CREATED             STATUS              PORTS                    NAMES
e3603fc7dcd0        mcr.microsoft.com/mssql/server:2017-latest   "/opt/mssql/bin/no..."   20 minutes ago      Up 20 minutes       0.0.0.0:1455->1433/tcp   sql5
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# docker ps -a
# docker volume ls
# docker inspect -f '{{.Mounts}}' sql5    --檢查容器"sql5"的docker volume主機路徑
[{volume sqlvolume5 /var/lib/docker/volumes/sqlvolume5/_data /var/opt/mssql/data2 local z true }]

# docker exec -it sql5 ls /var/opt/mssql/    --有自動新增一個"data2"目錄
# docker exec -it sql5 ls /var/opt/mssql/data    --這裡是容器"sql5"放SQL Server系統資料庫的位置
# docker exec -it sql5 ls /var/opt/mssql/data2    --共用目錄目前是空的

--開啟SSMS,連線至容器"sql5"(192.168.56.121,1455),然後新增一個database: "sql5",可以觀察"資料庫檔案"預設路徑還是在"/var/opt/mssql/data/"

# docker exec -it sql5 ls /var/opt/mssql/data    --有產生資料庫檔案"sql5.mdf","sql5_lod.ldf"
# docker exec -it sql5 ls /var/opt/mssql/data2/data    --共用目錄目前還是空的
--(2)加入第二個容器"sql6"
--利用"--volumes-from"選項來共用 容器"sql5" 的volume
# docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=xxxxxxxx' --name=sql6 -p 1466:1433 --volumes-from sql5 -d mcr.microsoft.com/mssql/server:2017-latest
# docker ps    --可以成功執行,因為容器"sql5"及"sql6"的SQL Server on Linux服務是各自執行的狀態(有各自的專屬目錄),故不會互相衝突
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONTAINER ID        IMAGE                                        COMMAND                  CREATED             STATUS              PORTS                    NAMES
3483a6a933da        mcr.microsoft.com/mssql/server:2017-latest   "/opt/mssql/bin/no..."   13 minutes ago      Up 13 minutes       0.0.0.0:1466->1433/tcp   sql6
e3603fc7dcd0        mcr.microsoft.com/mssql/server:2017-latest   "/opt/mssql/bin/no..."   20 minutes ago      Up 20 minutes       0.0.0.0:1455->1433/tcp   sql5
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# docker ps -a
# docker exec -it sql6 ls /var/opt/mssql/data    --有屬於容器"sql6"的SQL Server系統資料庫
# docker exec -it sql6 ls /var/opt/mssql/data2    --共用目錄目前是空的

--開啟SSMS,連線至容器"sql6"(192.168.56.121,1466),然後新增一個database "sql6"

# docker exec -it sql6 ls /var/opt/mssql/data    --有產生資料庫檔案"sql5.mdf","sql5_lod.ldf"
# docker exec -it sql6 ls /var/opt/mssql/data2/data    --共用目錄目前還是空的

# docker inspect -f '{{.Mounts}}' sql6    --檢查容器"sql6"的docker volume主機路徑(與容器"sql5"相同,所以是共享這個路徑)
[{ sqlvolume5 /var/lib/docker/volumes/sqlvolume5/_data /var/opt/mssql/data2 local  true }]

# docker inspect -f '{{.Mounts}}' sql5    
[{volume sqlvolume5 /var/lib/docker/volumes/sqlvolume5/_data /var/opt/mssql/data2 local z true }]
--(3)新增檔案至共用路徑以測試
--在容器"sql6"的/var/opt/mssql/data2目錄,新增一個空檔"text01.txt"
# docker exec -it sql6 touch /var/opt/mssql/data2/text01.txt    
# docker exec -it sql6 ls /var/opt/mssql/data2    --在容器"sql6"有看到"text01.txt"
# docker exec -it sql5 ls /var/opt/mssql/data2    --在容器"sql5"有看到"text01.txt"

--反向測試
--在容器"sql5"的/var/opt/mssql/data2目錄,新增一個空檔"text02.txt"
# docker exec -it sql5 touch /var/opt/mssql/data2/text02.txt    
# docker exec -it sql5 ls /var/opt/mssql/data2    --在容器"sql5"有看到"text01.txt"及"text02.txt"
# docker exec -it sql6 ls /var/opt/mssql/data2    --在容器"sql6"有看到"text01.txt"及"text02.txt"
--(4)測試完畢,刪除相關檔案
--移除"容器"
# docker ps -a
# docker stop sql5 sql6
# docker rm sql5 sql6

-移除"資料磁碟區"
# docker volume ls
# docker volume rm sqlvolume5
# docker volume ls

 

<情境二> 為兩個容器設定共用的Volume,藉以分享檔案,同時擁有各自的Volume,以另外保存自己的SQL Server資料庫

--實作兩個SQL Server容器,其SQL Server服務有各自的docker volume,並共用另一個docker volume來分享檔案

--(1)建立容器"sql5",注意有使用兩個"-v"參數
# docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=xxxxxxxx" -p 1455:1433 --name sql5 -v sqlvolume50:/var/opt/mssql -v sqlvolume5:/var/opt/mssql/data2 -d mcr.microsoft.com/mssql/server:2017-latest
# docker ps
# docker volume ls
# docker inspect -f '{{.Mounts}}' sql5
-------------------
[{volume sqlvolume50 /var/lib/docker/volumes/sqlvolume50/_data /var/opt/mssql local z true } {volume sqlvolume5 /var/lib/docker/volumes/sqlvolume5/_data /var/opt/mssql/data2 local z true }]
-------------------
--(2)建立容器"sql6",使用了一個"-v"參數(SQL Server服務專用的volume),另外也使用"--volumes-from"參數(為了共用 容器"sql5" 的volume)
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=xxxxxxxx" -p 1466:1433 --name sql6 -v sqlvolume60:/var/opt/mssql/ --volumes-from sql5 -d mcr.microsoft.com/mssql/server:2017-latest
# docker ps
# docker volume ls
# docker inspect -f '{{.Mounts}}' sql6
-------------------
[{volume sqlvolume60 /var/lib/docker/volumes/sqlvolume60/_data /var/opt/mssql local z true } { sqlvolume5 /var/lib/docker/volumes/sqlvolume5/_data /var/opt/mssql/data2 local  true }]
-------------------
--(3)測試
--檢視各容器的SQL Server資料庫檔案
# docker exec -it sql5 ls /var/opt/mssql/data/    --檢視容器"sql5"的SQL Server資料庫檔案
# docker exec -it sql6 ls /var/opt/mssql/data/    --檢視容器"sql6"的SQL Server資料庫檔案

--測試檔案共享
# docker exec -it sql6 ls /var/opt/mssql/data2    --空的
# docker exec -it sql6 touch /var/opt/mssql/data2/abc.txt
# docker exec -it sql6 ls /var/opt/mssql/data2    --可以看到"abc.txt"
# docker exec -it sql5 ls /var/opt/mssql/data2    --可以看到"abc.txt"
--(4)測試完畢,刪除相關檔案
--移除"容器"
# docker ps -a
# docker stop sql5 sql6
# docker rm sql5 sql6

-移除"資料磁碟區"
# docker volume ls
# docker volume rm sqlvolume5 sqlvolume50 sqlvolume60
# docker volume ls

 

Jay Huang