如何使MacDocker支援SQLonLinux容器Volume特性
問題引入
這天老鳥火急火燎的找到菜鳥:“鳥兒啊,按照你之前的文章SQL on Linux Run on Docker,當我銷燬SQL on Linux Docker容器以後,我容器中的所有資料庫資料丟失啦,怎麼辦,怎麼辦啊?”。
菜鳥一臉懵逼:“我是參照微軟官方文件來的啊?難道這幫XX連這個問題都沒有想到?”。於是,菜鳥開始了問題的重現和解決方法。
問題重現
按照上一篇檔案啟動的Docker容器,SQL on Linux例項中的資料庫檔案真的會隨著Docker容器的銷燬而消失,造成資料丟失的災難嗎?這一節進行問題重現和覆盤。
啟動Docker容器
使用Docker Run命令啟動SQL on Linux服務,對映到母體機41433埠上。
$ docker run -e `ACCEPT_EULA=Y` -e `SA_PASSWORD=SQLOnLinux@123` -p 41433:1433 -d microsoft/mssql-server-linux
建立測試物件
使用SSMS連線到Docker母體機41433埠上,執行下面的測試程式碼:建立測試資料庫、建立測試表、初始化兩條資料和查詢測試表。
IF DB_ID(`TestDb`) IS NULL
CREATE DATABASE TestDb;
GO
USE TestDb
GO
IF OBJECT_ID(`dbo.Test`, `U`) IS NOT NULL
DROP TABLE dbo.Test
GO
CREATE TABLE dbo.Test(
RowID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
,Name VARCHAR(20) NOT NULL
);
INSERT INTO dbo.Test
SELECT `A` UNION ALL SELECT `B`;
SELECT * FROM dbo.Test;
結果如下圖展示:
銷燬Docker容器
接下來模擬Docker容器銷燬過程:我們需要使用Docker Stop停止SQL on Linux容器,然後使用Docker rm刪除這個容器,接下來再次啟動Docker容器,最後檢查測試資料庫、測試表和資料是否存在。如果不存在,說明Docker容器中的資料已經丟失。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c1202ff7a33 microsoft/mssql-server-linux "/bin/sh -c /opt/m..." 2 minutes ago Up 2 minutes 0.0.0.0:41433->1433/tcp suspicious_liskov
...
$ docker stop 8c1202ff7a33
8c1202ff7a33
$ docker rm 8c1202ff7a33
8c1202ff7a33
$ docker run -e `ACCEPT_EULA=Y` -e `SA_PASSWORD=SQLOnLinux@123` -p 41433:1433 -d microsoft/mssql-server-linux
83cd4ca5cdf3d370118c10d8b783b204f86aa7b50fd7e334a27542d2cf7a1230
檢查測試物件
再次使用SSMS連線到Docker母體機41433埠,檢視測試資料庫,展示如下圖:
從這個結果來看,測試資料庫已經丟失。說明Docker容器與容器中的資料庫是命運共同體、同生死共命運。如果Docker容器銷燬,容器中的資料庫資料也隨之丟失。這個是使用者資料的災難,我們需要迫切解決這個問題。看來老鳥說的大實話啊。
解決問題
SQL on Linux對Mac Docker Volume的限制
要解決這個問題,我們需要引入Docker的Volume技術。簡單的說,這個技術的核心思想就是在啟動Docker容器的時候,將Docker容器中的目錄對映到母體機的目錄,Docker容器對這個目錄的所有操作會反映到母體機的這個對映目錄裡面。當Docker容器銷燬的時候,母體機的這個對映目錄會被保留下來。這樣,我們的資料庫資料檔案不會隨著容器的銷燬而消失了,繼而就解決了這個問題。但是,偏偏目前SQL on Linux不支援Mac作業系統的Docker Volume特性。詳情參見微軟官方文件:Run the SQL Server Docker image on Linux, Mac, or Windows
關鍵的地方,截圖如下展示:
Mac系統Docker就真的不支援SQL on Linux Docker容器的Volume嗎?讓我們來試試看:
$ docker run -e `ACCEPT_EULA=Y` -e `SA_PASSWORD=SQLOnLinux@123` -p 41433:1433 -v /Users/cherish/Downloads/linuxsqldata:/var/opt/mssql -it microsoft/mssql-server-linux
Configuring Microsoft(R) SQL Server(R)...
Microsoft(R) SQL Server(R) setup failed with error code 1. Please check the setup log in /var/opt/mssql/log for more information.
的確啟動Docker容器的過程中就會報告錯誤,詳細的錯誤日誌資訊如下:
$ cat ~/Downloads/linuxsqldata/log/errorlog
2017-02-09 13:20:06.62 Server Microsoft SQL Server vNext (CTP1.2) - 14.0.200.24 (X64)
Jan 10 2017 19:15:28
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
on Linux (Ubuntu 16.04.1 LTS)
2017-02-09 13:20:06.76 Server UTC adjustment: 0:00
2017-02-09 13:20:06.80 Server (c) Microsoft Corporation.
2017-02-09 13:20:06.84 Server All rights reserved.
2017-02-09 13:20:06.88 Server Server process ID is 4116.
2017-02-09 13:20:06.92 Server Logging SQL Server messages in file `C:varoptmssqllogerrorlog`.
2017-02-09 13:20:06.98 Server Registry startup parameters:
-d C:varoptmssqldatamaster.mdf
-l C:varoptmssqldatamastlog.ldf
-e C:varoptmssqllogerrorlog
2017-02-09 13:20:07.09 Server Command Line Startup Parameters:
--setup
--sa-password
2017-02-09 13:20:07.58 Server Error: 17113, Severity: 16, State: 1.
2017-02-09 13:20:07.58 Server Error 87(The parameter is incorrect.) occurred while opening file `C:varoptmssqldatamaster.mdf` to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.
解決方案
巴嘎,這裡就又引入了另外一個問題,如何解決Mac系統上SQL on Linux的Docker容器不支援Volume的問題?不要驚慌,淡定,當然是有辦法的,這個解決方法便是這篇文章存在的意義。解決方法如下:
$ docker create -v /var/opt/mssql --name sql41433data microsoft/mssql-server-linux
2e1deac3c2bffa5f6cd97dfdc3683c59628538550ea9010d16214906c299cf54
$ docker run -e `ACCEPT_EULA=Y` -e `SA_PASSWORD=SQLOnLinux@123` -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux
大概30秒後,Docker容器中的SQL例項服務起來以後,首先,參照問題重現中建立測試物件,然後銷燬Docker容器,接下來再次啟動Docker容器。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
596f3bfebb8a microsoft/mssql-server-linux "/bin/sh -c /opt/m..." 57 seconds ago Up 56 seconds 0.0.0.0:41433->1433/tcp linuxsql41433
...
$ docker stop 596f3bfebb8a
596f3bfebb8a
$ docker rm 596f3bfebb8a
596f3bfebb8a
$ docker run -e `ACCEPT_EULA=Y` -e `SA_PASSWORD=SQLOnLinux@123` -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux
最後檢查測試物件,截圖如下:
其實,從啟動過程的日誌,我們也可以看到TestDb已經啟動。
說明這個解決方法切實有效。
最後總結
這篇文章解決了Docker容器中SQL on Linux例項資料庫與容器本身同生死同命運的問題,使得使用者資料在容器被銷燬時得以保留。更加詳細的過程和步驟,可以參看youku視訊:
11_SQLOnLinux_MacDockerVolumes
相關文章
- 如何使jbuilder8.0支援struts1.1UI
- Docker容器學習梳理 - Volume資料卷使用Docker
- FreeBSD系統下如何使GraphicsMagick支援中文字型?
- 使Domino支援連線池技術
- Vue特性支援表Vue
- 建立sshd服務容器,並使宿主機與容器免密通訊
- docker 修改執行容器環境變數,如何修改容器中的環境變數env使長期有效Docker變數
- C++ 11 新特性之容器相關特性C++
- 使Ultraedit支援ASM語法高亮的方法ASM
- C++:使自定義類支援迭代器C++
- openGauss 支援UWAL特性
- Flocker 做為後端儲存代理 docker volume-driver 支援後端Docker
- 容器編排系統K8s之Volume的基礎使用K8S
- Docker VolumeDocker
- 配置PHP使之能同時支援GIF和JPEG (轉)PHP
- OpenSSL支援TLS1.3特性前瞻TLS
- javascript如何使網頁如何回到底部JavaScript網頁
- Laravel核心——服務容器的細節特性Laravel
- 容器網路Cilium:DualStack雙棧特性分析
- HarmonyOS線性容器特性及使用場景
- Laravel 核心——服務容器的細節特性Laravel
- 【開源】Qone 正式釋出,使 javascript 支援 .NET LINQJavaScript
- docker建立volume 指定volume 匯出image 匯入imageDocker
- Longhorn 企業級雲原生分散式容器儲存-券(Volume)和節點(Node)分散式
- Seata 新特性,APM 支援 SkyWalking
- 如何在 Docker 容器中執行支援 OData 的 JBoss 資料虛擬化 GADocker
- Spring框架中的容器以及兩大特性Spring框架
- Docker Volume介紹Docker
- Oracle ASM Volume DirectoryOracleASM
- 容器如何工作:OverlayFS
- 如何批量使外來鍵(FK)失效
- kubernetes概念之六:Volume&Persistent Volume&Namespace&Annotationnamespace
- MySQL8.0新特性-CTE語法支援MySql
- LightDB 23.1相容Oracle新特性支援Oracle
- Android N新特性--多視窗支援Android
- Nodejs原生支援的ES6特性NodeJS
- sys使用者不支援flashback table特性!
- Android使WebView支援HTML5Video(全屏)播放的方法AndroidWebViewHTMLIDE