通过DOCKER部署MSSQL集群

通过DOCKER部署MSSQL集群

前言:
本教程仅能实现主库读写,辅库只读的功能,也就是读写分离。
一、安装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连接三个数据库
通过DOCKER部署MSSQL集群_第1张图片
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选项是因为它是在没有诸如PacemakerWindows 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集群搭建成功。

你可能感兴趣的:(docker)