Docker如何部署SQL?Server?2017?Always?On集群
Docker部署SQL Server 2017 Always On集群
1.Docker部署Always on集群
SQL Server在2016年開(kāi)始支持Linux。隨著2017和2019版本的發(fā)布,它開(kāi)始支持Linux和容器平臺(tái)上的HA/DR、Kubernetes和大數(shù)據(jù)集群解決方案。
在本文中,我們將在3個(gè)機(jī)器的Docker容器上安裝SQL Server 2017,并創(chuàng)建AlwaysOn可用性組。
2.前提工作
注意: 所有機(jī)器操作
2.1安裝Docker
安裝Docker就不介紹了,自行安裝即可.
2.2配置時(shí)間同步
crontab -e #增加 * * * * * /usr/sbin/ntpdate time.windows.com && /usr/sbin/hwclock -w >/dev/null 2>&1
3.架構(gòu)
主機(jī)名 | IP | 端口 | 角色 |
---|---|---|---|
sql01 | 192.168.1.30 | 1433:14335022:5022 | 主 |
sql02 | 192.168.1.31 | 1433:14335022:5022 | 副本 |
sql03 | 192.168.1.32 | 1433:14335022:5022 | 副本 |
端口表示:外網(wǎng)端口:內(nèi)網(wǎng)端口
4.準(zhǔn)備相關(guān)容器鏡像
注意: 所有機(jī)器操作
拉取數(shù)據(jù)庫(kù)的Docker鏡像,如下
4.1SQL Server 2017
docker pull mcr.microsoft.com/mssql/server:2017-latest
可通過(guò)docker images
來(lái)查看已下載的鏡像信息。
鏡像地址:https://hub.docker.com/_/microsoft-mssql-server
5.開(kāi)始配置-容器
環(huán)境準(zhǔn)備完畢后,開(kāi)始正式的配置安裝。
5.1創(chuàng)建Dockerfile
注意: 所有機(jī)器操作
創(chuàng)建目錄用于存放dockerfile、docker-compose.yml等文件。
vi dockerfile
- dockerfile內(nèi)容如下
FROM mcr.microsoft.com/mssql/server:2017-latest RUN /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1 RUN /opt/mssql/bin/mssql-conf set sqlagent.enabled true
說(shuō)明:
- FROM:表示基于什么鏡像進(jìn)行安裝的
- RUN:在鏡像中進(jìn)行的操作
5.2編譯鏡像
注意: 所有機(jī)器操作
通過(guò)dockerfile來(lái)編譯鏡像,用于后面的安裝,命令:
docker build -t mcr.microsoft.com/mssql/server:2017-ty .
其中mcr.microsoft.com/mssql/server
為鏡像名稱,2017-ty
是鏡像標(biāo)簽,.
表示在當(dāng)前目錄下編譯,因?yàn)閐ockerfile就在當(dāng)前目錄下。
最后出現(xiàn)Successfully
表示編譯成功,否則根據(jù)錯(cuò)誤信息進(jìn)行解決。
5.3創(chuàng)建master容器
在sql01執(zhí)行:
docker run --name sql01 \ --hostname sql01 \ -p 1433:1433 \ -p 5022:5022 \ -e 'ACCEPT_EULA=Y' \ -e 'SA_PASSWORD=P@ssw0rd02' \ -e "MSSQL_AGENT_ENABLED=True" \ -e "MSSQL_PID=Developer" \ -d mcr.microsoft.com/mssql/server:2017-ty
5.4創(chuàng)建slave容器
在sql02執(zhí)行:
docker run --name sql02 \ --hostname sql02 \ -p 1433:1433 \ -p 5022:5022 \ -e 'ACCEPT_EULA=Y' \ -e 'SA_PASSWORD=P@ssw0rd02' \ -e "MSSQL_AGENT_ENABLED=True" \ -e "MSSQL_PID=Developer" \ -d mcr.microsoft.com/mssql/server:2017-ty
在sql03執(zhí)行:
docker run --name sql03 \ --hostname sql03 \ -p 1433:1433 \ -p 5022:5022 \ -e 'ACCEPT_EULA=Y' \ -e 'SA_PASSWORD=P@ssw0rd02' \ -e "MSSQL_AGENT_ENABLED=True" \ -e "MSSQL_PID=Developer" \ -d mcr.microsoft.com/mssql/server:2017-ty
至此容器已經(jīng)啟動(dòng)完成,下面通過(guò)SSMS連接數(shù)據(jù)庫(kù)進(jìn)行相關(guān)檢查和配置ALWAYSON。
5.5SSMS連接MSSQL
通過(guò)宿主機(jī)的外網(wǎng)IP+端口連接相應(yīng)的數(shù)據(jù)庫(kù),如下:
注意:IP和端口之間是逗號(hào)
可以看到數(shù)據(jù)庫(kù)的圖標(biāo)也是Linux的圖標(biāo)。
6.配置-數(shù)據(jù)庫(kù)
這部分就是在數(shù)據(jù)庫(kù)中進(jìn)行相關(guān)配置,如:創(chuàng)建KEY加密文件,管理用戶、可用組等。
6.1連接主庫(kù)-sql01
主庫(kù)也就是節(jié)點(diǎn)1,端口是1433,連接方法如上圖。
我們將證書(shū)和私鑰提取到/tmp/dbm_certificate.cer
和/tmp/dbm_certificate.pvk
文件中。
我們將這些文件復(fù)制到其他節(jié)點(diǎn),并根據(jù)以下文件創(chuàng)建主密鑰和證書(shū):執(zhí)行以下腳本
USE master GO CREATE LOGIN dbm_login WITH PASSWORD = 'Test@13579'; CREATE USER dbm_user FOR LOGIN dbm_login; GO CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Test@13579'; go CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm'; BACKUP CERTIFICATE dbm_certificate TO FILE = '/tmp/dbm_certificate.cer' WITH PRIVATE KEY ( FILE = '/tmp/dbm_certificate.pvk', ENCRYPTION BY PASSWORD = 'Test@13579' ); GO
將文件拷貝到其他兩個(gè)節(jié)點(diǎn):
#sql01操作 docker cp sql01:/tmp/dbm_certificate.cer ./ docker cp sql01:/tmp/dbm_certificate.pvk ./ scp dbm_certificate.* 192.168.1.31:/data/ty/ scp dbm_certificate.* 192.168.1.32:/data/ty/ #sql02操作 docker cp dbm_certificate.cer sql02:/tmp/ docker cp dbm_certificate.pvk sql02:/tmp/ #sql03操作 docker cp dbm_certificate.cer sql03:/tmp/ docker cp dbm_certificate.pvk sql03:/tmp/
6.2連接從庫(kù)-sql02和sql03
兩個(gè)從庫(kù)的端口分別是:1502和1503.然后重復(fù)主庫(kù)執(zhí)行的操作,如下:
CREATE LOGIN dbm_login WITH PASSWORD = 'Test@13579'; CREATE USER dbm_user FOR LOGIN dbm_login; GO CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Test@13579'; GO CREATE CERTIFICATE dbm_certificate AUTHORIZATION dbm_user FROM FILE = '/tmp/dbm_certificate.cer' WITH PRIVATE KEY ( FILE = '/tmp/dbm_certificate.pvk', DECRYPTION BY PASSWORD = 'Test@13579' ); GO
6.3所有節(jié)點(diǎn)
在所有節(jié)點(diǎn)上執(zhí)行以下命令
CREATE ENDPOINT [Hadr_endpoint] AS TCP (LISTENER_IP = (0.0.0.0), LISTENER_PORT = 5022) FOR DATA_MIRRORING ( ROLE = ALL, AUTHENTICATION = CERTIFICATE dbm_certificate, ENCRYPTION = REQUIRED ALGORITHM AES ); ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED; GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [dbm_login]; GO
啟用開(kāi)機(jī)自啟動(dòng)ALWAYON,在所有節(jié)點(diǎn)執(zhí)行以下命令
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON); GO
6.4創(chuàng)建高可用組
可以用SSMS工具和T-SQL兩種方式,下面以T-SQL為例:
運(yùn)行以下腳本在主節(jié)點(diǎn)
中創(chuàng)建一個(gè)可用性組。 請(qǐng)注意,選擇CLUSTER_TYPE = NONE
選項(xiàng)是因?yàn)樗窃跊](méi)有諸如Pacemaker或Windows Server故障轉(zhuǎn)移群集之類的群集管理平臺(tái)的情況下安裝的。
如果要在Linux上安裝AlwaysOn AG,則應(yīng)為Pacemaker選擇CLUSTER_TYPE = EXTERNAL:
CREATE AVAILABILITY GROUP [AG1] WITH (CLUSTER_TYPE = NONE) FOR REPLICA ON N'sql01' WITH ( ENDPOINT_URL = N'tcp://192.168.1.30:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, SEEDING_MODE = AUTOMATIC, FAILOVER_MODE = MANUAL, SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL) ), N'sql02' WITH ( ENDPOINT_URL = N'tcp://192.168.1.31:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, SEEDING_MODE = AUTOMATIC, FAILOVER_MODE = MANUAL, SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL) ), N'sql03' WITH ( ENDPOINT_URL = N'tcp://192.168.1.32:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, SEEDING_MODE = AUTOMATIC, FAILOVER_MODE = MANUAL, SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL) ); GO
在從庫(kù)中執(zhí)行以下命令,將從庫(kù)加入到AG組中
ALTER AVAILABILITY GROUP [ag1] JOIN WITH (CLUSTER_TYPE = NONE); ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE; GO
至此在Docker容器中安裝SQL Server Alwayson集群已經(jīng)完成了!
注意:當(dāng)指定CLUSTER_TYPE = NONE
創(chuàng)建可用組時(shí),在執(zhí)行故障轉(zhuǎn)移時(shí)需執(zhí)行以下命令
-- 將主角色轉(zhuǎn)移到可用性組中的某個(gè)備份副本 ALTER AVAILABILITY GROUP [ag1] FORCE_FAILOVER_ALLOW_DATA_LOSS; -- 嘗試進(jìn)行優(yōu)雅的故障轉(zhuǎn)移,如果不能完成,則允許丟失數(shù)據(jù) -- ALTER AVAILABILITY GROUP [ag1] FAILOVER;
6.5測(cè)試
在主庫(kù)上創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),并加入到可用組AG中。
--創(chuàng)建數(shù)據(jù)庫(kù) CREATE DATABASE agtestdb; GO ALTER DATABASE agtestdb SET RECOVERY FULL; GO BACKUP DATABASE agtestdb TO DISK = '/var/opt/mssql/data/agtestdb.bak'; GO ALTER AVAILABILITY GROUP [ag1] ADD DATABASE [agtestdb]; GO -- 創(chuàng)建表 use agtestdb CREATE TABLE ExampleTable ( ID INT PRIMARY KEY, Name NVARCHAR(50), Description NVARCHAR(100) ); -- 插入數(shù)據(jù) DECLARE @counter INT = 1; WHILE @counter <= 100 BEGIN INSERT INTO ExampleTable (ID, Name, Description) VALUES (@counter, 'Name ' + CAST(@counter AS NVARCHAR(10)), 'Description for ' + CAST(@counter AS NVARCHAR(10))); SET @counter = @counter + 1; END; GO
通過(guò)SSMS查看同步狀態(tài)是否正常.
6.6監(jiān)控 AG 狀態(tài)
通過(guò)以下這些視圖可以監(jiān)控 AG 中各個(gè)部分的狀態(tài)。
group的監(jiān)控
select * from sys.availability_groups; select * from sys.availability_groups_cluster; select * from sys.dm_hadr_availability_group_states;
replica 的監(jiān)控
select * from sys.availability_replicas; select * from sys.dm_hadr_availability_replica_states; select * from sys.dm_hadr_availability_replica_cluster_nodes; select * from sys.dm_hadr_availability_replica_cluster_states;
在 AG 中的 database 的監(jiān)控
select * from sys.availability_databases_cluster; select * from sys.dm_hadr_database_replica_states; select * from sys.dm_hadr_database_replica_cluster_states; select name,database_id,replica_id,group_database_id from sys.databases;
6.7故障轉(zhuǎn)移讀取縮放AG上的主要副本
每個(gè)可用性組僅有一個(gè)主要副本。 主要副本允許讀取和寫入操作。 若要更改哪個(gè)副本為主要副本,可進(jìn)行故障轉(zhuǎn)移。 在典型的可用性組中,群集管理器自動(dòng)執(zhí)行故障轉(zhuǎn)移過(guò)程。 在群集類型為 NONE 的可用性組中,需手動(dòng)執(zhí)行故障轉(zhuǎn)移過(guò)程。
在群集類型為 NONE 的可用性組中,有兩種對(duì)主要副本進(jìn)行故障轉(zhuǎn)移的方法:
- 手動(dòng)故障轉(zhuǎn)移(無(wú)數(shù)據(jù)丟失)
- 強(qiáng)制手動(dòng)故障轉(zhuǎn)移(會(huì)丟失數(shù)據(jù))
手動(dòng)故障轉(zhuǎn)移(無(wú)數(shù)據(jù)丟失)
主要副本可用時(shí)使用此方法,但你需要暫時(shí)或永久更改托管主要副本的實(shí)例。 若要避免潛在的數(shù)據(jù)丟失,發(fā)出手動(dòng)故障轉(zhuǎn)移前,確保目標(biāo)次要副本為最新版本。
手動(dòng)故障轉(zhuǎn)移(無(wú)數(shù)據(jù)丟失):
- 1.將當(dāng)前的主要副本和目標(biāo)次要副本設(shè)置為 SYNCHRONOUS_COMMIT。
ALTER AVAILABILITY GROUP [AGRScale] MODIFY REPLICA ON N'<node2>' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);
- 2.若要確定已將活動(dòng)事務(wù)提交到主要副本和至少一個(gè)同步次要副本,請(qǐng)運(yùn)行以下查詢:
SELECT ag.name, drs.database_id, drs.group_id, drs.replica_id, drs.synchronization_state_desc, ag.sequence_number FROM sys.dm_hadr_database_replica_states drs, sys.availability_groups ag WHERE drs.group_id = ag.group_id;
當(dāng) synchronization_state_desc 為 SYNCHRONIZED 時(shí),會(huì)同步次要副本。
- 3.將 REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 更新為 1。以下腳本在名為 ag1 的可用性組上將REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT 設(shè)置為 1。 運(yùn)行以下腳本前,將ag1 替換為可用性組的名稱:
ALTER AVAILABILITY GROUP [AGRScale] SET (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 1);
此設(shè)置可確保將每個(gè)活動(dòng)事務(wù)提交到主要副本和至少一個(gè)同步次要副本。
備注
此設(shè)置并非特定于故障轉(zhuǎn)移,應(yīng)根據(jù)環(huán)境要求進(jìn)行設(shè)置。
- 4.將主要副本和不參與故障轉(zhuǎn)移的次要副本設(shè)置為脫機(jī),以便為角色更改做好準(zhǔn)備:
ALTER AVAILABILITY GROUP [AGRScale] OFFLINE
- 5.將目標(biāo)次要副本升級(jí)為主要副本。
ALTER AVAILABILITY GROUP AGRScale FORCE_FAILOVER_ALLOW_DATA_LOSS;
- 6.將舊的主要和其他次要副本的角色更新為 SECONDARY,在托管舊的主要副本的 SQL Server 實(shí)例上運(yùn)行以下命令:
ALTER AVAILABILITY GROUP [AGRScale] SET (ROLE = SECONDARY);
備注
若要?jiǎng)h除可用性組,請(qǐng)使用刪除可用性組。 對(duì)于使用群集類型為 NONE 或EXTERNAL 創(chuàng)建的可用性組,請(qǐng)對(duì)可用性組的所有副本執(zhí)行該命令。
- 7.恢復(fù)數(shù)據(jù)移動(dòng),為托管主要副本的 SQL Server(主要和次要副本) 實(shí)例上的可用性組中的每個(gè)數(shù)據(jù)庫(kù)運(yùn)行以下命令:
ALTER DATABASE [db1] SET HADR RESUME
- 8.重新創(chuàng)建出于讀取縮放目的創(chuàng)建且不受群集管理器管理的所有偵聽(tīng)器。 如果原始偵聽(tīng)器指向舊的主要副本,請(qǐng)將其刪除,然后將其重新創(chuàng)建為指向新的主要副本。
強(qiáng)制手動(dòng)故障轉(zhuǎn)移(會(huì)丟失數(shù)據(jù))
如果主要副本不可用且無(wú)法立即恢復(fù),則需要強(qiáng)制執(zhí)行向次要副本的故障轉(zhuǎn)移(存在數(shù)據(jù)丟失)。 但是,如果原始主要副本在故障轉(zhuǎn)移后恢復(fù),它將承擔(dān)主要角色。 若要避免每個(gè)副本處于不同的狀態(tài),在存在數(shù)據(jù)丟失的情況下進(jìn)行強(qiáng)制故障轉(zhuǎn)移后,從可用性組中刪除原始主要副本。 原始主要副本重新聯(lián)機(jī)后,從該副本完全刪除該可用性組。
若要強(qiáng)制執(zhí)行從主要副本 N1 到次要副本 N2 的手動(dòng)故障轉(zhuǎn)移(存在數(shù)據(jù)丟失),請(qǐng)執(zhí)行以下步驟:
- 1.在次要副本 (N2) 上,啟動(dòng)強(qiáng)制故障轉(zhuǎn)移:
ALTER AVAILABILITY GROUP [AGRScale] FORCE_FAILOVER_ALLOW_DATA_LOSS;
- 2.在新的主要副本 (N2) 上,刪除原始主要副本 (N1):
ALTER AVAILABILITY GROUP [AGRScale] REMOVE REPLICA ON N'N1';
- 3.驗(yàn)證所有的應(yīng)用程序流量均指向偵聽(tīng)器和/或新的主要副本。
- 4.如果原始主要副本 (N1) 進(jìn)入聯(lián)機(jī)狀態(tài),則立即在原始主要副本 (N1) 上使可用性組AGRScale 脫機(jī):
ALTER AVAILABILITY GROUP [AGRScale] OFFLINE
- 5.如果存在數(shù)據(jù)或未同步的更改,則通過(guò)備份或其他可滿足業(yè)務(wù)需求的數(shù)據(jù)復(fù)制選項(xiàng)來(lái)保存這些數(shù)據(jù)。
- 6.接下來(lái),從原始主要副本 (N1) 中刪除可用性組:
DROP AVAILABILITY GROUP [AGRScale];
- 7.刪除原始主要副本 (N1) 上的可用性組數(shù)據(jù)庫(kù):
USE [master] GO DROP DATABASE [AGDBRScale] GO
- 8.(可選)如果需要,現(xiàn)可將 N1 作為新的次要副本添加回可用性組 AGRScale 中。
在主庫(kù)中執(zhí)行以下命令,將從庫(kù)加入到AG組中
use master ALTER AVAILABILITY GROUP AG1 ADD REPLICA ON 'sql01' WITH ( ENDPOINT_URL = 'TCP://192.168.30:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, SEEDING_MODE = AUTOMATIC, FAILOVER_MODE = MANUAL, SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL) ); GO
在從庫(kù)中執(zhí)行以下命令,將從庫(kù)加入到AG組中
ALTER AVAILABILITY GROUP [ag1] JOIN WITH (CLUSTER_TYPE = NONE); ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE; GO
7.參考連接
- https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-ver15
- https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-ubuntu?view=sql-server-ver15
- https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-create-availability-group?view=sql-server-ver15
- https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-configure-mssql-conf?view=sql-server-ver15
- https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-configure-environment-variables?view=sql-server-ver15
- https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-cluster-ubuntu?view=sql-server-linux-ver15
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決執(zhí)行docker daemon命令時(shí)出錯(cuò)的問(wèn)題
daemon 這是docker 操作中十分常用的命令指定項(xiàng),最近在運(yùn)行docker daemon命令卻發(fā)生了錯(cuò)誤,后來(lái)通過(guò)測(cè)試各種方法終于解決了,現(xiàn)在將方法分享給大家,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-11-11docker安裝Redis高可用實(shí)現(xiàn)一主二從三哨兵
redis提供了哨兵模式保證redis實(shí)現(xiàn)高可用,本文主要介紹了docker安裝Redis高可用實(shí)現(xiàn)一主二從三哨兵,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02docker 容器自定義 hosts 網(wǎng)絡(luò)訪問(wèn)操作
這篇文章主要介紹了docker 容器自定義 hosts 網(wǎng)絡(luò)訪問(wèn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03CentOS8上用Docker部署開(kāi)源項(xiàng)目Tcloud的教程
這篇文章主要介紹了CentOS8上用Docker部署開(kāi)源項(xiàng)目Tcloud,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01解決docker pull鏡像報(bào)錯(cuò)的問(wèn)題
這篇文章主要介紹了解決docker pull鏡像報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03騰訊云服務(wù)器docker開(kāi)啟端口后無(wú)法訪問(wèn)的解決方法
本文主要介紹了騰訊云服務(wù)器docker開(kāi)啟端口后無(wú)法訪問(wèn)的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法
這篇文章主要介紹了Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12