SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server on Linux の Docker 版を使って、1 サーバーでクラスターレス可用性グループを組んでみる

leave a comment

可用性グループを構築する場合、複数のサーバーを用意していましたが、クラスターレス可用性グループであれば、Docker のコンテナーを二つ用意すれば構成をとれるのではないだろうかと思って試してみました。

とりあえず、組めるかどうかを試したので、手動での対応の連続です…。

最初に次のコマンドで SQL Server のコンテナーを 2 個起動します。

docker run --name SoL1 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=P@ssw0rd' -e 'MSSQL_LCID=1041' -e 'TZ=Asia/Tokyo'  -p 11433:1433 -p 15022:5022 -d microsoft/mssql-server-linux
docker run --name SoL2 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=P@ssw0rd' -e 'MSSQL_LCID=1041' -e 'TZ=Asia/Tokyo'  -p 21433:1433 -p 25022:5022 -d microsoft/mssql-server-linux

 
各コンテナーでは、SQL Server に起動するためのポートと、ミラーリングエンドポイントのポートにアクセス可能な状態としています。

  • SoL1
    • 11433 → 1433
    • 15022 → 5022
  • SoL2
    • 21433 → 1433
    • 25022 → 5022

次に各コンテナーに対話シェルでアクセスし HA の機能の有効化を行います。

docker exec -it SoL1 bash
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
exit
docker exec -it SoL2 bash
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
exit
docker restart SoL1
docker restart SoL2

次に SQL Server 周りの設定を行います。
最初に 1 台目の SQL Server で次のクエリを実行します。

ALTER EVENT SESSION  AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);
GO
ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START
GO
CREATE LOGIN dbm_login WITH PASSWORD = '**<1Sample_Strong_Password!@#>**';
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '**<master_Key_Password>**';
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
BACKUP CERTIFICATE dbm_certificate
   TO FILE = '/var/opt/mssql/data/dbm_certificate.cer'
   WITH PRIVATE KEY (
           FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
           ENCRYPTION BY PASSWORD = '**<private_Key_Password>**'
       );
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];

 
証明書をマッピングしたログインを作成し、証明書のバックアップをコンテナー内に取得しています。
作成した証明書のバックアップを 2 台目のコンテナーにコピーを行います。

docker cp SoL1:/var/opt/mssql/data/dbm_certificate.cer .
docker cp SoL1:/var/opt/mssql/data/dbm_certificate.pvk .
docker cp ./dbm_certificate.cer SoL2:/var/opt/mssql/data/dbm_certificate.cer
docker cp ./dbm_certificate.pvk SoL2:/var/opt/mssql/data/dbm_certificate.pvk

 
次に、2 台目のコンテナーでコピーした証明書を使用してエンドポイントの設定を行います。

ALTER EVENT SESSION  AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);
GO
ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START
GO
CREATE LOGIN dbm_login WITH PASSWORD = '**<1Sample_Strong_Password!@#>**';
CREATE USER dbm_user FOR LOGIN dbm_login;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '**<master_Key_Password>**';
CREATE CERTIFICATE dbm_certificate
    AUTHORIZATION dbm_user
    FROM FILE = '/var/opt/mssql/data/dbm_certificate.cer'
    WITH PRIVATE KEY (
    FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
    DECRYPTION BY PASSWORD = '**<private_Key_Password>**'
            );
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];

 
最後に可用性グループの設定を行うため、1 台目のコンテナーに SSMS で接続して、次のようなクエリを実行します。

エンドポイントの設定については、ホストからマッピングしている ポート番号を指定しています。

CREATE AVAILABILITY GROUP [ag1]
    WITH (DB_FAILOVER = ON, CLUSTER_TYPE = NONE)
    FOR REPLICA ON
        N'SoL1' WITH (
            ENDPOINT_URL = N'tcp://10.200.0.3:15022',
            AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
            FAILOVER_MODE = MANUAL,
            SEEDING_MODE = AUTOMATIC,
            SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
            ),
        N'SoL2' WITH (
            ENDPOINT_URL = N'tcp://10.200.0.3:25022',
            AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
            FAILOVER_MODE = MANUAL,
            SEEDING_MODE = AUTOMATIC,
            SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
            )
ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE
CREATE DATABASE [db1]
ALTER DATABASE [db1] SET RECOVERY FULL
BACKUP DATABASE [db1] TO DISK = N'NUL'
ALTER AVAILABILITY GROUP [ag1] ADD DATABASE [db1]
ALTER AVAILABILITY GROUP [ag1] SET (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0)

以前の Docker では、–hostname の設定内容が、SQL Server のサーバー名と連携していなかったようなのですが、RC1 では連携しているようですね。
@@servername does not reflect –hostname used when creating container
最後に 2 台目のコンテナーで、可用性グループに参加します。

ALTER AVAILABILITY GROUP [ag1] JOIN WITH (CLUSTER_TYPE = NONE)
ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE

これで Docker コンテナー間でクラスターレス可用性グループが構築できるかと。
image
コンテナーだと再作成が簡単にできるので、軽く検証をしたい場合などは結構便利かなと。

Share

Written by Masayuki.Ozawa

7月 23rd, 2017 at 11:51 am

Posted in SQL Server

Tagged with ,

Leave a Reply