SQL Server on Container起手式

這篇文章主要為了對學習的內容留個大概的記錄,方便日後查詢,因前一陣子對單位內部做分享,故稍微研究了一下SQL Server on Linux的安裝,在排定講授內容時,想說反正都是使用Linux環境,就順便把SQL Server on Container的應用一併納入。

下圖是對組內分享SQL Server on Linux時的實作環境,不過後來上課時,又另外安裝一台CentOS 7.3(伺服器名稱為sqllnx4,IP為192.168.56.134)來練習Container。安裝新的Linux後,記得要執行 #yum update -y  ,以更新所有使用yum下載安裝的套件

--實作開始
--(1) 從 Microsoft Container Registry 提取 SQL Server 2017 Linux 容器映像,查看所有可用的映像,請參閱 https://hub.docker.com/_/microsoft-mssql-server
#docker pull mcr.microsoft.com/mssql/server:2017-latest
----------------------------------------------------------------------------------------------------------
Trying to pull repository mcr.microsoft.com/mssql/server ...
2017-latest: Pulling from mcr.microsoft.com/mssql/server
59ab41dd721a: Pull complete
57da90bec92c: Pull complete
06fe57530625: Pull complete
5a6315cba1ff: Pull complete
739f58768b3f: Pull complete
3a58fde0fc61: Pull complete
89b44069090d: Pull complete
3f6b360deb9e: Pull complete
b8d0242f03c2: Pull complete
Digest: sha256:f551ff159479f402bc3a120d9bb509c78bbcb8d1fe401552e102f28bc654db0e
Status: Downloaded newer image for mcr.microsoft.com/mssql/server:2017-latest
----------------------------------------------------------------------------------------------------------

# docker images    --檢查多了一個image,名稱為"mcr.microsoft.com/mssql/server:2017-latest"  (即"REPOSITORY"欄位 + ":" + "TAG"欄位)

 

--(2-1) 建立容器,名稱為sql1,埠號1433 (根據預設,這會建立 SQL Server 2017 Developer 版本的映像)
--注意: 若VM主機(Linux)已經有安裝SQL Server on Linux(default port 1433),請先將mssql-server服務執行stop(#systemctl stop mssql-server),或者將主機對應IP改為非1433 port(如: -p 1477:1433)
--密碼應遵循 SQL Server 預設密碼原則,否則容器將無法設定 SQL Server 並停止運作。 根據預設,密碼的長度至少必須是 8 個字元,包含下列四種集合的其中三種字元:大寫字母、小寫字母、以 10 為底數的數字,最好包含符號。
# docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=xxxxxxxx" \
>    -p 1433:1433 --name sql1 \
>    -d mcr.microsoft.com/mssql/server:2017-latest
--------------------------------------------------------------------------------------------
5252d8d4220154553277437b218d713bfa84578e3dbda430f4c821fa4f43437c
--------------------------------------------------------------------------------------------

#netstat -tulpn    --檢視容器所使用的port

--[補充]:
參數	            描述
-e "ACCEPT_EULA=Y"	            ->"-e"參數為指定環境變量(environment),可以傳遞到docker裡面。將 ACCEPT_EULA 變數設為任意值可確認您接受終端使用者授權合約。 此為 SQL Server 映像的必要設定。
-e "MSSQL_SA_PASSWORD=<YourStrong@Passw0rd\>"	            ->"-e"參數為指定環境變量,可以傳遞到docker裡面。指定您自己的強式密碼,該密碼長度至少需為 8 個字元且符合 SQL Server 密碼需求。 此為 SQL Server 映像的必要設定。
-p   1433:1433	            ->將主機環境上的 TCP 連接埠 (第一個值) 對應至容器中的 TCP 連接埠 (第二個值)。 在本範例中,SQL Server 正在接聽容器中的 TCP 1433 且對主機上的連接埠 1433 公開。
--name sql1	            ->為容器指定自訂名稱,而不使用隨機產生的名稱。 若您執行數個容器,就無法使用此相同名稱。
-d   mcr.microsoft.com/mssql/server:2017-latest		            ->SQL Server 2017 Linux 容器映像。

# docker ps -a
CONTAINER ID        IMAGE                                        COMMAND                  CREATED             STATUS                      PORTS                    NAMES
5252d8d42201        mcr.microsoft.com/mssql/server:2017-latest   "/opt/mssql/bin/no..."   45 seconds ago      Up 44 seconds               0.0.0.0:1433->1433/tcp   sql1
c9c660141006        docker.io/centos:latest                      "/bin/bash"              About an hour ago   Exited (1) 38 minutes ago                            sqlonlinux

 

--(2-2) 建立容器,名稱為sql2,埠號1477(根據預設,這會建立 SQL Server 2017 Developer 版本的映像)

--[補充]: 我們先來查詢前面sql1容器的SQL Server主機名稱
-h (主機名稱) 參數也相當實用,此參數可將容器的內部名稱變更為自訂值,建議您將 -h 與 --name 設為相同的值,這會讓識別目標容器更輕鬆。
# docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -Q "select @@servername" -Y 20   --查容器(sql1)中,SQL Server Name的名稱為"75cff668489f"
Password:
                                                                                 
--------------------------------------------------------------------------------------------------------------------------------
75cff668489f          
 
# docker stop 75cff668489f    --停用容器
75cff668489f

# docker rm 75cff668489f    --刪除容器
75cff668489f

# docker ps -a    --檢視容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
                           
--開始建立容器,名稱為sql2,多一個"-h"參數
# docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=xxxxxxxx" -p 1477:1433 --name sql2 -h sql2 -d mcr.microsoft.com/mssql/server:2017-latest    --容器(sql2)的主機對應port不能再指定為1433,因為目前容器(sql1)正在使用,故改指定1477

--可在容器內的SQL Server中執行以下語法,以傳回名稱
SELECT @@SERVERNAME, SERVERPROPERTY('ComputerNamePhysicalNetBIOS'), SERVERPROPERTY('MachineName'), SERVERPROPERTY('ServerName')

[root@centos jay]# docker exec -it sql2 bash    --進入容器sql2
root@sql2:/# /opt/mssql-tools/bin/sqlcmd -Y 10 -S localhost -U sa -P xxxxxxxx
1> SELECT @@SERVERNAME, SERVERPROPERTY('ComputerNamePhysicalNetBIOS'),
2>  SERVERPROPERTY('MachineName'), SERVERPROPERTY('ServerName')
3> go

---------- ---------- ---------- ----------
sql2       sql2       sql2       sql2

(1 rows affected)

 

--(3) 變更sa密碼
--建立您的 SQL Server 容器之後,在"容器中"執行 echo $MSSQL_SA_PASSWORD,即可探索您指定的 MSSQL_SA_PASSWORD 環境變數。 
# docker exec -it sql2 echo $MSSQL_SA_PASSWORD    --直接查會找不到,這種直接進入容器執行指令的方式,無法取到容器內的變數值

# docker exec -it sql2 "bash"    --先以互動方式先進入容器"sql2",然後再查詢,改用這種方式才抓得到容器內的變數值
root@28f9e2b5afde:/# echo $MSSQL_SA_PASSWORD
root@28f9e2b5afde:/# exit    --退出容器

--基於安全性考量,請變更您的 SA 密碼。
#docker exec -it sql2 /opt/mssql-tools/bin/sqlcmd \
   -S localhost -U sa -P 舊密碼 \
   -Q 'ALTER LOGIN sa WITH PASSWORD="新密碼"'

 

--(4) [在容器中]使用sqlcmd連線
--以互動模式連接容器,並執行"bash"指令
# docker exec -it sql2 "bash"
root@5252d8d42201:/#

--"在容器中"使用 SQL Server 命令列工具 sqlcmd 以連線至 SQL Server
root@5252d8d42201:/# echo $MSSQL_SA_PASSWORD    --注意: 環境變數還是保持舊密碼
root@5252d8d42201:/# /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "新密碼"    --在這裡,我們使用新密碼登入容器中的SQL Server
1> select @@servername  --回傳5252d8d42201,如果執行docker run時加上"-h"參數,應該會比較好識別
2> go
                                                                                 
--------------------------------------------------------------------------------------------------------------------------------
5252d8d42201                                                                     

(1 rows affected)
1> exit
root@5252d8d42201:/#

 

--(5) 測試從外部連線至容器,即提供給外部的Server使用(需要指定port)
--先找出裝載您容器之電腦的 IP 位址(這裡是192.168.56.121)。 查詢IP時,在 Linux 上,使用ifconfig 或 ip addr。在 Windows 上,使用 ipconfig。
--針對此範例,請在您的用戶端電腦(這裡是192.168.56.133)上安裝 sqlcmd 工具(即mssql-tools)。
--執行 sqlcmd 來指定 IP 位址,以及對應至您容器連接埠 1433 的連接埠。 在此範例中即為主機電腦上的相同連接埠 1433。 如果您在主機電腦上指定了不同的對應連接埠,您可以在這裡使用該連接埠。

--以下,從sqllnx3(192.168.56.133)(有安裝mssql-tools)連線至192.168.56.121時,連線IP使用"中括號"會有問題
[root@sqllnx3 ~]# sqlcmd -S [192.168.56.121],1433 -U sa -P "xxxxxxxx"
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login timeout expired.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : TCP Provider: Error code 0x2AF9.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..

--將連線IP去掉"中括號"就可以連線container成功
[root@sqllnx3 ~]# sqlcmd -S 192.168.56.121,1433 -U sa -P "xxxxxxxx"
1> select @@servername
2> go
                                                                                                 
--------------------------------------------------------------------------------------------------------------------------------
5252d8d42201                                                                                     

(1 rows affected)
1>

--開啟Windows環境的SSMS,連接到"192.168.56.121,1433"及"192.168.56.121,1477"來觀察一下剛剛所建立的容器"sql1"及"sql2"

Jay Huang