前言:
本教程仅能实现主库读写,辅库只读的功能,也就是读写分离。
一、安装docker
yum install -y docker
安装docker-compose
yum install -y docker-compose
二、制作自己的MSSQL镜像
1.通过docker查找mssql镜像
docker search mssql
2.拉取mssql镜像
docker pull mcr.microsoft.com/mssql/server
3.准备dockerfile文件
FROM mcr.microsoft.com/mssql/server
EXPOSE 1433
ENTRYPOINT /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
ENTRYPOINT /opt/mssql/bin/mssql-conf set sqlagent.enabled true
ENTRYPOINT /opt/mssql/bin/sqlservr
FROM—引入mssql镜像
EXPOSE—虚拟机中开放的对外端口
ENTRYPOINT—虚拟机中要运行的命令
命令详解
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
#开启性能组
ENTRYPOINT /opt/mssql/bin/mssql-conf set sqlagent.enabled true
#开启SQL代理
ENTRYPOINT /opt/mssql/bin/sqlservr
#启动SQL服务
4.制作镜像
在dockerfile文件所在的目录执行
docker build -t mssql2017:latest .
注意最后的那个“点”,代表在当前目录下制作
5.创建容器
通过docker-compose以msql镜像创建三个容器
docker-compose.yml文件内容如下:
version: '3'
services:
db1:
container_name: sqlNode1
image: mssql2017:latest
hostname: sqlNode1
domainname: lab.local
volumes:#注意下面的路径映射,冒号左侧为本机地址,右侧为容器地址,左侧路径必须有777权限,否则会启动失败
- /home/mssql/loupandata1:/var/opt/mssql #MSSQL的MDB文件存放地址
- /etc/localtime:/etc/localtime:ro #主机和容器时间同步
privileged: true
environment:
SA_PASSWORD: "sa_password" #数据库SA用户的密码
TZ: "Asia/Shanghai" #设置时区
ACCEPT_EULA: "Y"
ports:
- "1501:1433" #主机和容器的端口映射
extra_hosts:#写入/etc/hosts
sqlNode2.labl.local: "172.16.0.3" #节点2的IP
sqlNode3.labl.local: "172.16.0.4" #节点3的IP
networks:
internal:
ipv4_address: 172.16.0.2 #本机IP
db2:
container_name: sqlNode2
image: mssql2017:latest
hostname: sqlNode2
domainname: lab.local
volumes:
- /home/mssql/loupandata2:/var/opt/mssql
- /etc/localtime:/etc/localtime:ro
privileged: true
environment:
SA_PASSWORD: "sa_password"
TZ: "Asia/Shanghai"
ACCEPT_EULA: "Y"
ports:
- "1502:1433"
extra_hosts:
sqlNode1.lab.local: "172.16.0.2"
sqlNode3.lab.local: "172.16.0.4"
networks:
internal:
ipv4_address: 172.16.0.3
db3:
container_name: sqlNode3
image: mssql2017:latest
hostname: sqlNode3
domainname: lab.local
volumes:
- /home/mssql/loupandata3:/var/opt/mssql
- /etc/localtime:/etc/localtime:ro
privileged: true
environment:
SA_PASSWORD: "sa_password"
TZ: "Asia/Shanghai"
ACCEPT_EULA: "Y"
ports:
- "1503:1433"
extra_hosts:
sqlNode1.lab.local: "172.16.0.2"
sqlNode2.lab.local: "172.16.0.3"
networks:
internal:
ipv4_address: 172.16.0.4
networks:
internal:
ipam:
driver: default
config:
- subnet: 172.16.0.0/24
6.启动容器
保存文件后,在docker-compose.yml所在目录启动容器
docker-compose up -d #-d参数:后台运行
查看启动结果:
docker-compose ps
状态列为UP代表启动成功:
[root@xiangeloupan mssqlDockerFile]# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------
sqlNode1 /bin/sh -c /opt/mssql/bin/ ... Up 0.0.0.0:1501->1433/tcp
sqlNode2 /bin/sh -c /opt/mssql/bin/ ... Up 0.0.0.0:1502->1433/tcp
sqlNode3 /bin/sh -c /opt/mssql/bin/ ... Up 0.0.0.0:1503->1433/tcp
小贴式: 批量停止容器:
[root@xiangeloupan mssqlDockerFile]# docker-compose stop Stopping sqlNode1 ... done Stopping sqlNode2 ... done Stopping sqlNode3 ... done
批量启动容器:
[root@xiangeloupan mssqlDockerFile]# docker-compose start Starting db1 ... done Starting db2 ... done Starting db3 ... done
如果容器启动失败,请检查docker-compose的日志文件
docker-compose logs -f >>logs.log
如果发现错误:
[0m /opt/mssql/bin/sqlservr: Error: The system directory [/.system] could not be created. Errno [13]
请修改宿主机指定映射目录的权限
chown -R 10001:0 /data/docker/mssql
三、数据库操作
1.通过SSMS连接三个数据库
2.建立管理用户及密钥文件
在主节点(端口1501为数据库)上执行过程:
USE master
GO
CREATE LOGIN dbm_login WITH PASSWORD = 'loginPwd'; #密码和SA密码保持一致
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'loginPwd';
go
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
BACKUP CERTIFICATE dbm_certificate
TO FILE = '/var/opt/mssql/dbm_certificate.cer' #此目录已经映射到宿主服务器,这样方便管理
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/dbm_certificate.pvk',
ENCRYPTION BY PASSWORD = 'loginPwd'
);
GO
3.在服务器上通过docker cp 命令将主节点生成的私钥文件拷贝到其他两个节点:
$ docker cp sqlNode1:/var/opt/mssql/dbm_certificate.cer .
$ docker cp sqlNode1:/var/opt/mssql/dbm_certificate.pvk .
$ docker cp dbm_certificate.cer sqlNode2:/var/opt/mssql/
$ docker cp dbm_certificate.pvk sqlNode2:/var/opt/mssql/
$ docker cp dbm_certificate.cer sqlNode3:/var/opt/mssql/
$ docker cp dbm_certificate.pvk sqlNode3:/var/opt/mssql/
4.在辅节点导入刚才复制过来的认证文件(每个辅节点分别执行)
CREATE LOGIN dbm_login WITH PASSWORD = 'loginPwd';
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'loginPwd';
GO
CREATE CERTIFICATE dbm_certificate
AUTHORIZATION dbm_user
FROM FILE = '/var/opt/mssql/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/dbm_certificate.pvk',
DECRYPTION BY PASSWORD = 'loginPwd'
);
GO
5.在所有节点下执行:
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];
6.启用开机自启动ALWAYON,在所有节点执行以下命令
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);
GO
7.创建高可用组
运行以下脚本在主节点中创建一个可用性组。 请注意,选择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
8.在辅库中执行下面命令,将辅库加入到可用性组
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
四、测试
在主数据中创建名为agxgtestdb的数据库
CREATE DATABASE agxgtestdb;
GO
ALTER DATABASE agxgtestdbSET RECOVERY FULL;
GO
BACKUP DATABASE agxgtestdbTO DISK = '/var/opt/mssql/data/agxgtestdb.bak';
GO
ALTER AVAILABILITY GROUP [ag1] ADD DATABASE [agxgtestdb];
GO
再新建一张表
use agxgtestdb
select * into agxgtestdb from sys.databases;
insert into agxgtestdb select * from agxgtestdb;
go
sqlNode2和sqlNode3节点中自动同步sqlNode1的数据即为成功。
五、还原数据库
通过WinSCP将数据备份文件上传至主库/var/opt/mssql/目录
在主节库的SQL中执行:
RESTORE DATABASE [BuildingDictionaries] FROM DISK = N'/var/opt/mssql/BuildingDictionaries.bak' WITH MOVE 'BuildingDictionaries' TO '/var/opt/mssql/data/BuildingDictionaries.mdf',MOVE 'BuildingDictionaries_log' TO '/var/opt/mssql/data/BuildingDictionaries_log.ldf',FILE = 1, NOUNLOAD, REPLACE, STATS = 5
将数据库加入到组中:
USE master #必须在master数据库中操作
ALTER AVAILABILITY GROUP [ag1] ADD DATABASE [BuildingDictionaries];
GO
之后,系统会自动将数据库同步到其他辅节点,至此,一个简单的MSSQL集群搭建成功。