我是在windows2019上的docker上测试的。容器类型为linux。
原文为 https://blog.csdn.net/qianglei6077/article/details/107055554
注意 :测试的时候最好内存足够大。我是16g内存。 开启三个sqlserver容器,外加一个portainer。 有时候有容器的内存不够,出现报错或连不上的情况。这时候最好重启容器,如果还不行,就停一个,执行完命令,再启动。sqlserver的镜像使用的2019开发版。
架构
主机名 | IP | 端口 | 角色 |
---|---|---|---|
sqlNode1 | 宿主机IP | 1501:1433 | |
sqlNode2 | 宿主机IP | 1502:1433 | 副本 |
sqlNode3 | 宿主机IP | 1503:1433 | 副本 |
docker pull ubuntu:18.04
docker pull mcr.microsoft.com/mssql/server:2019-latest
dockerfile内容如下
FROM ubuntu:18.04
RUN apt-get update
RUN apt install sudo wget curl gnupg gnupg1 gnupg2 -y
RUN apt install software-properties-common systemd vim -y
RUN wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
RUN add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/18.04/mssql-server-2019.list)"
RUN apt-get update
RUN apt-get install -y mssql-server
RUN /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
RUN /opt/mssql/bin/mssql-conf set sqlagent.enabled true
EXPOSE 1433
ENTRYPOINT /opt/mssql/bin/sqlservr
在文件所在目录执行
docker build -t sqlag2019:ha .
创建docker-compose文件
version: '3'
services:
db1:
container_name: sqlNode1
image: sqlag2019:ha
hostname: sqlNode1
domainname: lab.local
environment:
SA_PASSWORD: "MyPassWord123"
ACCEPT_EULA: "Y"
ports:
- "1501:1433"
extra_hosts:
sqlNode2.labl.local: "172.16.238.22"
sqlNode3.labl.local: "172.16.238.23"
networks:
internal:
ipv4_address: 172.16.238.21
db2:
container_name: sqlNode2
image: sqlag2019:ha
hostname: sqlNode2
domainname: lab.local
environment:
SA_PASSWORD: "MyPassWord123"
ACCEPT_EULA: "Y"
ports:
- "1502:1433"
extra_hosts:
sqlNode1.lab.local: "172.16.238.21"
sqlNode3.lab.local: "172.16.238.23"
networks:
internal:
ipv4_address: 172.16.238.22
db3:
container_name: sqlNode3
image: sqlag2019:ha
hostname: sqlNode3
domainname: lab.local
environment:
SA_PASSWORD: "MyPassWord123"
ACCEPT_EULA: "Y"
ports:
- "1503:1433"
extra_hosts:
sqlNode1.lab.local: "172.16.238.21"
sqlNode2.lab.local: "172.16.238.22"
networks:
internal:
ipv4_address: 172.16.238.23
networks:
internal:
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
启动容器
docker-compose up -d
SSMS连接MSSQL
通过宿主机的外网IP+端口连接相应的数据库,如下:
配置-数据库
这部分就是在数据库中进行相关配置,如:创建KEY加密文件,管理用户、可用组等。
步骤1:连接主库-sqlNode1
主库也就是节点1,端口是1501,连接方法如上图。
我们将证书和私钥提取到/tmp/dbm_certificate.cer和/tmp/dbm_certificate.pvk文件中。
我们将这些文件复制到其他节点,并根据以下文件创建主密钥和证书:执行以下脚本
USE master
GO
CREATE LOGIN dbm_login WITH PASSWORD = 'MyStr0ngPa$w0rd';
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'MyStr0ngPa$w0rd';
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 = 'MyStr0ngPa$w0rd'
);
GO
将文件拷贝到其他两个节点:
$ docker cp sqlNode1:/tmp/dbm_certificate.cer .
$ docker cp sqlNode1:/tmp/dbm_certificate.pvk .
$ docker cp dbm_certificate.cer sqlNode2:/tmp/
$ docker cp dbm_certificate.pvk sqlNode2:/tmp/
$ docker cp dbm_certificate.cer sqlNode3:/tmp/
$ docker cp dbm_certificate.pvk sqlNode3:/tmp/
步骤2:连接从库-sqlNode2和sqlNode3
两个从库的端口分别是:1502和1503.然后重复主库执行的操作,如下:
CREATE LOGIN dbm_login WITH PASSWORD = 'MyStr0ngPa$w0rd';
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'MyStr0ngPa$w0rd';
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 = 'MyStr0ngPa$w0rd'
);
GO
步骤3:所有节点
在所有节点上执行以下命令
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];
启用开机自启动ALWAYON,在所有节点执行以下命令
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);
GO
步骤4:创建高可用组
可以用SSMS工具和T-SQL两种方式,下面以T-SQL为例:
运行以下脚本在主节点中创建一个可用性组。 请注意,选择CLUSTER_TYPE = NONE选项是因为它是在没有诸如Pacemaker或Windows Server故障转移群集之类的群集管理平台的情况下安装的。
如果要在Linux上安装AlwaysOn AG,则应为Pacemaker选择CLUSTER_TYPE = EXTERNAL:
CREATE AVAILABILITY GROUP [AG1]
WITH (CLUSTER_TYPE = NONE)
FOR REPLICA ON
N'sqlNode1'
WITH (
ENDPOINT_URL = N'tcp://sqlNode1:5022',
AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
SEEDING_MODE = AUTOMATIC,
FAILOVER_MODE = MANUAL,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
),
N'sqlNode2'
WITH (
ENDPOINT_URL = N'tcp://sqlNode2:5022',
AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
SEEDING_MODE = AUTOMATIC,
FAILOVER_MODE = MANUAL,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
),
N'sqlNode3'
WITH (
ENDPOINT_URL = N'tcp://sqlNode3:5022',
AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
SEEDING_MODE = AUTOMATIC,
FAILOVER_MODE = MANUAL,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
);
GO
在从库中执行以下命令,将从库加入到AG组中
ALTER AVAILABILITY GROUP [ag1] JOIN WITH (CLUSTER_TYPE = NONE);
ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE;
GO
至此在Docker容器中安装SQL Server Alwayson集群已经完成了!
注意:当指定CLUSTER_TYPE = NONE创建可用组时,在执行故障转移时需执行以下命令
ALTER AVAILABILITY GROUP [ag1] FORCE_FAILOVER_ALLOW_DATA_LOSS
测试
在主库上创建一个数据库,并加入到可用组AG中。
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
然后连上数据库,看看效果。
最后附上用到的文件 https://files.cnblogs.com/files/wang2650/sqlserver.7z 主要是修改了dockerfile,加入了ubuntu的数据源,否则,执行系统更新的时候特别慢。