Docker如何部署SQL?Server?2017?Always?On集群
Docker部署SQL Server 2017 Always On集群
1.Docker部署Always on集群
SQL Server在2016年開始支持Linux。隨著2017和2019版本的發(fā)布,它開始支持Linux和容器平臺上的HA/DR、Kubernetes和大數(shù)據(jù)集群解決方案。
在本文中,我們將在3個機(jī)器的Docker容器上安裝SQL Server 2017,并創(chuàng)建AlwaysOn可用性組。
2.前提工作
注意: 所有機(jī)器操作
2.1安裝Docker
安裝Docker就不介紹了,自行安裝即可.
2.2配置時間同步
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ù)庫的Docker鏡像,如下
4.1SQL Server 2017
docker pull mcr.microsoft.com/mssql/server:2017-latest
可通過docker images
來查看已下載的鏡像信息。
鏡像地址:https://hub.docker.com/_/microsoft-mssql-server
5.開始配置-容器
環(huán)境準(zhǔn)備完畢后,開始正式的配置安裝。
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
說明:
- FROM:表示基于什么鏡像進(jìn)行安裝的
- RUN:在鏡像中進(jìn)行的操作
5.2編譯鏡像
注意: 所有機(jī)器操作
通過dockerfile來編譯鏡像,用于后面的安裝,命令:
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ù)錯誤信息進(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)啟動完成,下面通過SSMS連接數(shù)據(jù)庫進(jìn)行相關(guān)檢查和配置ALWAYSON。
5.5SSMS連接MSSQL
通過宿主機(jī)的外網(wǎng)IP+端口連接相應(yīng)的數(shù)據(jù)庫,如下:
注意:IP和端口之間是逗號
可以看到數(shù)據(jù)庫的圖標(biāo)也是Linux的圖標(biāo)。
6.配置-數(shù)據(jù)庫
這部分就是在數(shù)據(jù)庫中進(jìn)行相關(guān)配置,如:創(chuàng)建KEY加密文件,管理用戶、可用組等。
6.1連接主庫-sql01
主庫也就是節(jié)點(diǎn)1,端口是1433,連接方法如上圖。
我們將證書和私鑰提取到/tmp/dbm_certificate.cer
和/tmp/dbm_certificate.pvk
文件中。
我們將這些文件復(fù)制到其他節(jié)點(diǎn),并根據(jù)以下文件創(chuàng)建主密鑰和證書:執(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
將文件拷貝到其他兩個節(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連接從庫-sql02和sql03
兩個從庫的端口分別是:1502和1503.然后重復(fù)主庫執(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
啟用開機(jī)自啟動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)建一個可用性組。 請注意,選擇CLUSTER_TYPE = NONE
選項(xiàng)是因?yàn)樗窃跊]有諸如Pacemaker或Windows Server故障轉(zhuǎn)移群集之類的群集管理平臺的情況下安裝的。
如果要在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
在從庫中執(zhí)行以下命令,將從庫加入到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)建可用組時,在執(zhí)行故障轉(zhuǎn)移時需執(zhí)行以下命令
-- 將主角色轉(zhuǎn)移到可用性組中的某個備份副本 ALTER AVAILABILITY GROUP [ag1] FORCE_FAILOVER_ALLOW_DATA_LOSS; -- 嘗試進(jìn)行優(yōu)雅的故障轉(zhuǎn)移,如果不能完成,則允許丟失數(shù)據(jù) -- ALTER AVAILABILITY GROUP [ag1] FAILOVER;
6.5測試
在主庫上創(chuàng)建一個數(shù)據(jù)庫,并加入到可用組AG中。
--創(chuàng)建數(shù)據(jù)庫 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
通過SSMS查看同步狀態(tài)是否正常.
6.6監(jiān)控 AG 狀態(tài)
通過以下這些視圖可以監(jiān)控 AG 中各個部分的狀態(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上的主要副本
每個可用性組僅有一個主要副本。 主要副本允許讀取和寫入操作。 若要更改哪個副本為主要副本,可進(jìn)行故障轉(zhuǎn)移。 在典型的可用性組中,群集管理器自動執(zhí)行故障轉(zhuǎn)移過程。 在群集類型為 NONE 的可用性組中,需手動執(zhí)行故障轉(zhuǎn)移過程。
在群集類型為 NONE 的可用性組中,有兩種對主要副本進(jìn)行故障轉(zhuǎn)移的方法:
- 手動故障轉(zhuǎn)移(無數(shù)據(jù)丟失)
- 強(qiáng)制手動故障轉(zhuǎn)移(會丟失數(shù)據(jù))
手動故障轉(zhuǎn)移(無數(shù)據(jù)丟失)
主要副本可用時使用此方法,但你需要暫時或永久更改托管主要副本的實(shí)例。 若要避免潛在的數(shù)據(jù)丟失,發(fā)出手動故障轉(zhuǎn)移前,確保目標(biāo)次要副本為最新版本。
手動故障轉(zhuǎn)移(無數(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.若要確定已將活動事務(wù)提交到主要副本和至少一個同步次要副本,請運(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 時,會同步次要副本。
- 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è)置可確保將每個活動事務(wù)提交到主要副本和至少一個同步次要副本。
備注
此設(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)次要副本升級為主要副本。
ALTER AVAILABILITY GROUP AGRScale FORCE_FAILOVER_ALLOW_DATA_LOSS;
- 6.將舊的主要和其他次要副本的角色更新為 SECONDARY,在托管舊的主要副本的 SQL Server 實(shí)例上運(yùn)行以下命令:
ALTER AVAILABILITY GROUP [AGRScale] SET (ROLE = SECONDARY);
備注
若要刪除可用性組,請使用刪除可用性組。 對于使用群集類型為 NONE 或EXTERNAL 創(chuàng)建的可用性組,請對可用性組的所有副本執(zhí)行該命令。
- 7.恢復(fù)數(shù)據(jù)移動,為托管主要副本的 SQL Server(主要和次要副本) 實(shí)例上的可用性組中的每個數(shù)據(jù)庫運(yùn)行以下命令:
ALTER DATABASE [db1] SET HADR RESUME
- 8.重新創(chuàng)建出于讀取縮放目的創(chuàng)建且不受群集管理器管理的所有偵聽器。 如果原始偵聽器指向舊的主要副本,請將其刪除,然后將其重新創(chuàng)建為指向新的主要副本。
強(qiáng)制手動故障轉(zhuǎn)移(會丟失數(shù)據(jù))
如果主要副本不可用且無法立即恢復(fù),則需要強(qiáng)制執(zhí)行向次要副本的故障轉(zhuǎn)移(存在數(shù)據(jù)丟失)。 但是,如果原始主要副本在故障轉(zhuǎn)移后恢復(fù),它將承擔(dān)主要角色。 若要避免每個副本處于不同的狀態(tài),在存在數(shù)據(jù)丟失的情況下進(jìn)行強(qiáng)制故障轉(zhuǎn)移后,從可用性組中刪除原始主要副本。 原始主要副本重新聯(lián)機(jī)后,從該副本完全刪除該可用性組。
若要強(qiáng)制執(zhí)行從主要副本 N1 到次要副本 N2 的手動故障轉(zhuǎn)移(存在數(shù)據(jù)丟失),請執(zhí)行以下步驟:
- 1.在次要副本 (N2) 上,啟動強(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)用程序流量均指向偵聽器和/或新的主要副本。
- 4.如果原始主要副本 (N1) 進(jìn)入聯(lián)機(jī)狀態(tài),則立即在原始主要副本 (N1) 上使可用性組AGRScale 脫機(jī):
ALTER AVAILABILITY GROUP [AGRScale] OFFLINE
- 5.如果存在數(shù)據(jù)或未同步的更改,則通過備份或其他可滿足業(yè)務(wù)需求的數(shù)據(jù)復(fù)制選項(xiàng)來保存這些數(shù)據(jù)。
- 6.接下來,從原始主要副本 (N1) 中刪除可用性組:
DROP AVAILABILITY GROUP [AGRScale];
- 7.刪除原始主要副本 (N1) 上的可用性組數(shù)據(jù)庫:
USE [master] GO DROP DATABASE [AGDBRScale] GO
- 8.(可選)如果需要,現(xiàn)可將 N1 作為新的次要副本添加回可用性組 AGRScale 中。
在主庫中執(zhí)行以下命令,將從庫加入到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
在從庫中執(zhí)行以下命令,將從庫加入到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é)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決執(zhí)行docker daemon命令時出錯的問題
daemon 這是docker 操作中十分常用的命令指定項(xiàng),最近在運(yùn)行docker daemon命令卻發(fā)生了錯誤,后來通過測試各種方法終于解決了,現(xiàn)在將方法分享給大家,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-11-11docker安裝Redis高可用實(shí)現(xiàn)一主二從三哨兵
redis提供了哨兵模式保證redis實(shí)現(xiàn)高可用,本文主要介紹了docker安裝Redis高可用實(shí)現(xiàn)一主二從三哨兵,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02docker 容器自定義 hosts 網(wǎng)絡(luò)訪問操作
這篇文章主要介紹了docker 容器自定義 hosts 網(wǎng)絡(luò)訪問操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03CentOS8上用Docker部署開源項(xiàng)目Tcloud的教程
這篇文章主要介紹了CentOS8上用Docker部署開源項(xiàng)目Tcloud,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01騰訊云服務(wù)器docker開啟端口后無法訪問的解決方法
本文主要介紹了騰訊云服務(wù)器docker開啟端口后無法訪問的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法
這篇文章主要介紹了Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12