Este tutorial é a segunda parte de uma série que ajuda você a implantar um ambiente Windows altamente disponível no Google Cloud com o Microsoft Active Directory, o SQL Server 2016 e o Internet Information Services (IIS). Neste tutorial, você configura duas instâncias do SQL Server em diferentes zonas da mesma região como um grupo de disponibilidade "Sempre ativada" do SQL Server de várias sub-redes.
A série consiste nestes tutoriais:
- Como implantar um ambiente do Microsoft Active Directory tolerante a falhas
- Como implantar um SQL Server de várias sub-redes (este documento)
- Como implantar servidores da Web do IIS com balanceamento de carga
Em cada tutorial, nos baseamos na infraestrutura que você criou no anterior.
Objetivos
- Criar duas sub-redes da rede abrangendo duas zonas.
- Implantar uma máquina virtual (VM) do Microsoft SQL Server 2016 em cada zona.
- Configurar cada instância do SQL Server para participar do domínio do Active Directory.
- Criar um cluster de failover do Windows Server.
- Criar e configurar um banco de dados de exemplo
bookshelf
do SQL Server. - Configurar o grupo de disponibilidade "Sempre ativada" do SQL Server.
Custos
Neste tutorial, você continuará usando os recursos do Google Cloud que configurou nos tutoriais anteriores. Você usa os seguintes componentes faturáveis:
A estimativa de custo desse ambiente na calculadora de preços é de cerca de US$ 98 por dia, incluindo as licenças do SQL Server 2016 Enterprise e o ambiente do Active Directory de dois servidores.
Antes de começar
Para a configuração usada neste tutorial, é preciso que você tenha acesso a um controlador de domínio do Windows e a um domínio ativo do Active Directory. Se você ainda não tiver esse ambiente, conclua as etapas nos seguintes tutoriais:
Como inicializar variáveis comuns
Você precisa definir muitas variáveis de ambiente para controlar onde os elementos da infraestrutura são implantados.
Em um editor de texto, crie um script que defina as variáveis de ambiente a seguir para especificar o código do projeto, a região e as zonas que você quer usar.
As variáveis definem a região como
us-east1
. Se você usou uma região diferente no tutorial anterior, altere-a nesse script para corresponder à região que você usou antes.region=us-east1 zone_1=${region}-b zone_2=${region}-c vpc_name=webappnet project_id=your-project-id
Substitua your-project-id pelo ID do projeto do Google Cloud que você está usando.
Abra o Cloud Shell:
Copie o script na janela do Cloud Shell e execute-o.
Defina a região padrão e o ID do projeto para que você não precise especificar esses valores em cada comando subsequente:
gcloud config set compute/region ${region} gcloud config set project ${project_id}
Como criar a infraestrutura de rede
Depois de definir as variáveis de infraestrutura, crie as sub-redes usadas pelo SQL Server.
Adicione novas sub-redes à sua rede de nuvem privada virtual (VPC, na sigla em inglês) atual:
gcloud compute networks subnets create private-sql-1 \ --network ${vpc_name} \ --range 10.3.0.0/24 gcloud compute networks subnets create private-sql-2 \ --network ${vpc_name} \ --range 10.4.0.0/24
Crie uma regra de firewall interna para permitir o tráfego entre as sub-redes
private-ad*
que você criou anteriormente e as novas sub-redesprivate-sql*
:gcloud compute firewall-rules create allow-internal-ports-private-sql \ --network ${vpc_name} \ --allow tcp:0-65535,udp:0-65535,icmp \ --source-ranges 10.4.0.0/24,10.3.0.0/24,10.2.0.0/24,10.1.0.0/24
Como criar instâncias do SQL Server
Em seguida, você cria duas VMs da edição SQL Server 2016 Enterprise usando imagens pré-configuradas do Compute Engine com as seguintes propriedades:
- Nomes:
bookshelf-sql1
ebookshelf-sql2
- Tamanho do disco de inicialização:
200GB
- Tipo de máquina:
n1-highmem-4
Se você pretende usar esse ambiente além deste tutorial e requerer recursos de computação adicionais, poderá personalizar o tipo de máquina para essas instâncias posteriormente. Também é possível adicionar discos e redimensionar os discos permanentes atuais.
Neste tutorial, você usa a imagem pública do SQL Server no Windows Server nas VMs. Isso significa que você será cobrado pelo uso do SQL Server. Também é possível implantar as licenças atuais do SQL Server no Compute Engine usando a mobilidade de licenças por meio do Software Assurance e aplicá-las em qualquer imagem pública do Windows Server depois de instalar o SQL Server.
Crie uma instância do Compute Engine do Windows Server 2016 com o SQL Server 2016 Enterprise:
gcloud compute instances create bookshelf-sql1 \ --machine-type n1-highmem-4 \ --boot-disk-type pd-ssd \ --boot-disk-size 200GB \ --image-project windows-sql-cloud \ --image-family sql-ent-2016-win-2016 \ --zone ${zone_1} \ --network-interface=network=${vpc_name},subnet=private-sql-1,private-network-ip=10.3.0.2,aliases=10.3.0.4/31
Crie a segunda instância:
gcloud compute instances create bookshelf-sql2 \ --machine-type n1-highmem-4 \ --boot-disk-type pd-ssd \ --boot-disk-size 200GB \ --image-project windows-sql-cloud \ --image-family sql-ent-2016-win-2016 \ --zone ${zone_2} \ --network-interface=network=${vpc_name},subnet=private-sql-2,private-network-ip=10.4.0.2,aliases=10.4.0.4/31
Configurar a instância bookshelf-sql2
Em seguida, configure a instância bookshelf-sql2
. Você começa com a segunda instância porque é necessário mais trabalho para configurar o banco de dados em bookshelf-sql1
, e a configuração de bookshelf-sql2
requer menos sessões do protocolo RDP (Remote Desktop Protocol).
Crie uma senha para a instância do Windows
bookshelf-sql2
:gcloud compute reset-windows-password bookshelf-sql2 \ --zone ${zone_2} --quiet
O nome de usuário é o mesmo da sua conta do Google. Anote o nome de usuário e a senha para uso futuro.
Use o RDP para se conectar à instância do SQL Server. Basta usar as credenciais criadas anteriormente.
Na instância, abra um terminal do PowerShell como administrador. Clique em Iniciar, digite
PowerShell
e pressioneControl+Shift+Enter
.Configure as variáveis a seguir:
$DomainName = "example-gcp.com" $DNS1 = "10.1.0.100" $DNS2 = "10.2.0.100" $LocalStaticIp = "10.4.0.2" $DefaultGateway = "10.4.0.1"
Configure o servidor DNS primário:
netsh interface ip set dns Ethernet static $DNS1
Configure o servidor DNS secundário:
netsh interface ip add dns Ethernet $DNS2 index=2
Defina o endereço IP e o gateway padrão:
netsh interface ip set address name=Ethernet static $LocalStaticIp 255.255.255.0 $DefaultGateway 1
Adicione a VM ao domínio do Windows:
Add-Computer -DomainName $DomainName ` -Credential (Get-Credential "example-gcp\Administrator")
Quando for solicitado que você forneça uma senha para a conta
Administrator
, use as credenciais de administrador definidas ao instalar uma floresta do Active Directory no tutorial anterior. Para o nome de usuário, adicione o nome do domínio como um prefixo, como emEXAMPLE-GCP\Administrator
.Abra as portas do firewall do Windows para o grupo de disponibilidade do SQL Server:
netsh advfirewall firewall add rule name="5022 for Avail Groups" dir=in action=allow protocol=TCP localport=5022 netsh advfirewall firewall add rule name="1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433
Instale o recurso de cluster de failover:
Install-WindowsFeature Failover-Clustering -IncludeManagementTools
Reinicie a instância:
Restart-Computer
Use o RDP para se conectar à instância do SQL Server usando as credenciais da conta
EXAMPLE-GCP\Administrator
.Abra uma janela do console do PowerShell como administrador.
Na janela do console do PowerShell, crie as pastas para os dados e arquivos de registro do SQL Server:
New-Item -ItemType directory -Path C:\SQLData New-Item -ItemType directory -Path C:\SQLLog
Crie uma nova pasta para backups de banco de dados e compartilhe-a:
New-Item -ItemType directory -Path C:\SQLBackup New-SMBShare -Name SQLBackup -Path C:\SQLBackup -FullAccess "Authenticated Users"
Configurar a instância bookshelf-sql1
Em seguida, configure a instância bookshelf-sql1
.
No Cloud Shell, crie uma senha para a instância do Windows
bookshelf-sql1
:gcloud compute reset-windows-password bookshelf-sql1 --zone ${zone_1} --quiet
O nome de usuário é o mesmo da sua conta do Google. Anote o nome de usuário e a senha para uso futuro.
Use o RDP para se conectar à instância do SQL Server usando as credenciais criadas para a instância
bookshelf-sql1
.Abra uma janela do console do PowerShell como administrador.
Na janela do console do PowerShell, defina as seguintes variáveis:
$DomainName = "example-gcp.com" $DNS1 = "10.1.0.100" $DNS2 = "10.2.0.100" $LocalStaticIp = "10.3.0.2" $DefaultGateway = "10.3.0.1"
Configure o servidor DNS primário:
netsh interface ip set dns Ethernet static $DNS1
Configure o servidor DNS secundário:
netsh interface ip add dns Ethernet $DNS2 index=2
Defina o endereço IP e o gateway padrão:
netsh interface ip set address name=Ethernet static $LocalStaticIp 255.255.255.0 $DefaultGateway 1
Adicione a VM ao domínio:
Add-Computer -DomainName $DomainName ` -Credential (Get-Credential "example-gcp\Administrator")
Quando for necessário fornecer uma senha para a conta de administrador, use as credenciais de administrador definidas durante a instalação da floresta do Active Directory no tutorial anterior. Para o nome de usuário, adicione o nome do domínio como um prefixo, como em
EXAMPLE-GCP\Administrator
.Adicione regras de firewall do Windows:
netsh advfirewall firewall add rule name="5022 for Avail Groups" dir=in action=allow protocol=TCP localport=5022 netsh advfirewall firewall add rule name="1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433
Instale o recurso de cluster de failover:
Install-WindowsFeature Failover-Clustering -IncludeManagementTools
Reinicie a instância:
Restart-Computer
Configurar o cluster de failover do Windows Server
Use o RDP para se conectar à instância
bookshelf-sql1
. Quando for necessário fornecer uma senha para a conta de Administrador, use as credenciais de administrador definidas durante a instalação da floresta do Active Directory no tutorial anterior. Para o nome de usuário, adicione o nome do domínio como um prefixo, como emEXAMPLE-GCP\Administrator
.Abra uma janela do console do PowerShell como administrador.
Na janela do console do PowerShell, defina as seguintes variáveis:
$node1 = "bookshelf-sql1" $node2 = "bookshelf-sql2"
Defina o nome do cluster:
$nameWSFC = "bookshelf-dbclus"
Defina os endereços IP para os clusters e os listeners de cluster:
$ipWSFC1 = "10.3.0.4" $ipWSFC2 = "10.4.0.4" $ipWSListener1 = "10.3.0.5" $ipWSListener2 = "10.4.0.5"
Verifique se a instância
bookshelf-sql1
do SQL Server está pronta para ingressar no cluster. Execute o script a seguir, que tenta se conectar à instância do SQL Server:$SQLServer1IsReady=$False For ($i=0; $i -le 30; $i++) { $SqlCatalog = "master" $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $node1;" + ` "Database = $SqlCatalog; Integrated Security = True" try { $SqlConnection.Open() Write-Host "Connection to the server $node1 was successful" $SQLServer1IsReady=$True $SqlConnection.Close() break } catch { Write-Host "SQL server $node1 is not ready, waiting for 60s" Start-Sleep -s 60 #Wait for 60 seconds } } if($SQLServer1IsReady -eq $False) { Write-Error "$node1 is not responding. Was it deployed correctly?" }
Certifique-se de que a instância do SQL Server
bookshelf-sql2
esteja pronta para participar do cluster:$SQLServer2IsReady=$False For ($i=0; $i -le 30; $i++) { $SqlCatalog = "master" $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $node2;" + ` "Database = $SqlCatalog; Integrated Security = True" try { $SqlConnection.Open() Write-Host "Connection to the server $node2 was successful" $SQLServer2IsReady=$True $SqlConnection.Close() break } catch { Write-Host "SQL server $node2 is not ready, waiting for 60s" Start-Sleep -s 60 #Wait for 60 seconds } } if($SQLServer2IsReady -eq $False) { Write-Error "$node2 is not responding. Was it deployed correctly?" }
Crie o novo cluster:
New-Cluster -Name $nameWSFC -Node $node1, $node2 -NoStorage ` -StaticAddress $ipWSFC1, $ipWSFC2
Ative o recurso de grupos de disponibilidade "Sempre ativada" em ambos os nós:
Enable-SqlAlwaysOn -ServerInstance $node1 -Force Enable-SqlAlwaysOn -ServerInstance $node2 -Force
Crie pastas para os dados do banco de dados e arquivos de registros:
New-Item -ItemType directory -Path C:\SQLData New-Item -ItemType directory -Path C:\SQLLog
Configurar o banco de dados
Neste tutorial, usamos o banco de dados de exemplo bookshelf
, que você cria para testar se sua configuração está funcionando corretamente.
Na janela do console do PowerShell em que você está trabalhando, execute a seguinte instrução SQL para criar o banco de dados
bookshelf
:$CreateDatabaseSQLScript = @" CREATE DATABASE bookshelf ON PRIMARY (NAME = 'bookshelf_Data', FILENAME='C:\SQLData\bookshelf_data.mdf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB ) LOG ON (NAME = 'bookshelf_log', FILENAME='C:\SQLLog\bookshelf_log.ldf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB ) GO USE [bookshelf] Exec dbo.sp_changedbowner @loginame = 'sa', @map = false; ALTER DATABASE [bookshelf] SET RECOVERY FULL; GO BACKUP DATABASE bookshelf to disk = '\\bookshelf-sql2\SQLBackup\bookshelf.bak' WITH INIT GO "@ Invoke-Sqlcmd -Query $CreateDatabaseSQLScript -ServerInstance $node1
Execute a instrução SQL a seguir para criar a tabela
Books
:$CreateTableSQLScript = @" USE [bookshelf] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Books] ( [Id] [bigint] IDENTITY(1,1) NOT NULL, [Title] [nvarchar](max) NOT NULL, [Author] [nvarchar](max) NULL, [PublishedDate] [datetime] NULL, [ImageUrl] [nvarchar](max) NULL, [Description] [nvarchar](max) NULL, [CreatedById] [nvarchar](max) NULL, CONSTRAINT [PK_dbo.Books] PRIMARY KEY CLUSTERED ([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO "@ Invoke-Sqlcmd -Query $CreateTableSQLScript -ServerInstance $node1
Configure as variáveis a seguir:
$Domain = "example-gcp.com" $ADControllerFQDN = "ad-dc1.$Domain" $ServiceAccountName = "sql.service" $ServiceAccountPrincipalName = "$ServiceAccountName@$Domain"
Ative o cmdlet
RSAT-AD-PowerShell
com o seguinte comando do PowerShell:Add-WindowsFeature RSAT-AD-PowerShell
Você precisa de Ferramentas de Administração de Servidor Remoto para criar uma conta de serviço a partir da VM.
Adicione uma conta de serviço de banco de dados chamada
sql.service
no domínio:New-ADUser -Name $ServiceAccountName ` -Server $ADControllerFQDN ` -SamAccountName $ServiceAccountName ` -UserPrincipalName $ServiceAccountPrincipalName ` -AccountPassword (Read-Host -AsSecureString "AccountPassword") ` -PassThru | Enable-ADAccount
Quando você for solicitado a inserir a senha da conta
sql.service
, use uma senha forte e armazene a senha em um local seguro para uso futuro.Execute a seguinte instrução SQL para adicionar a conta
EXAMPLE-GCP\sql.service
como administrador de banco de dados:$AddSQLServiceAccountScript = @" USE [master] GO CREATE LOGIN [EXAMPLE-GCP\sql.service] FROM WINDOWS WITH DEFAULT_DATABASE=[bookshelf], DEFAULT_LANGUAGE=[us_english] GO USE [bookshelf] GO CREATE USER [EXAMPLE-GCP\sql.service] FOR LOGIN [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_accessadmin] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_backupoperator] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_datareader] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_datawriter] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_ddladmin] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_owner] ADD MEMBER [EXAMPLE-GCP\sql.service] GO USE [bookshelf] GO ALTER ROLE [db_securityadmin] ADD MEMBER [EXAMPLE-GCP\sql.service] GO "@ Invoke-Sqlcmd -Query $AddSQLServiceAccountScript -ServerInstance $node1
Configurar o grupo de disponibilidade do SQL Server
Ainda na instância em que você está trabalhando, defina as variáveis a seguir:
$Database="bookshelf" $BackupFolder="SQLBackup" $SharedLocation="\\$node2\$BackupFolder" $ListenerName="sql-listener" $AGName="MainAG" $PrimaryServer = "$node1.$Domain\MSSQLSERVER" $SecondaryServer = "$node2.$Domain\MSSQLSERVER"
Faça backup do banco de dados no servidor principal:
Backup-SqlDatabase ` -Database $Database -Initialize ` -BackupFile "$SharedLocation\$Database.bak" ` -ServerInstance $node1
Restaure o banco de dados no servidor secundário:
Restore-SqlDatabase ` -Database $Database ` -BackupFile "$SharedLocation\$Database.bak" ` -ServerInstance $node2 ` -NORECOVERY
Faça backup do registro do banco de dados no servidor principal:
Backup-SqlDatabase ` -Database $Database -Initialize ` -BackupFile "$SharedLocation\$Database.log" ` -ServerInstance $node1 ` -BackupAction Log
Restaure o registro do banco de dados no servidor secundário:
Restore-SqlDatabase ` -Database $Database ` -BackupFile "$SharedLocation\$Database.log" ` -ServerInstance $node2 ` -RestoreAction Log ` -NORECOVERY
Crie e inicie os endpoints:
$endpoint1=New-SqlHADREndpoint -Port 5022 -Owner sa ` -Encryption Supported -EncryptionAlgorithm Aes ` -Name AlwaysonEndpoint1 ` -Path "SQLSERVER:\SQL\$node1.$Domain\Default" Set-SqlHADREndpoint -InputObject $endpoint1 -State Started $endpoint2=New-SqlHADREndpoint -Port 5022 -Owner sa ` -Encryption Supported -EncryptionAlgorithm Aes ` -Name AlwaysonEndpoint2 ` -Path "SQLSERVER:\SQL\$node2.$Domain\Default" Set-SqlHADREndpoint -InputObject $endpoint2 -State Started
A saída é esta:
AlwaysonEndpoint1 STARTED 5022 - for node1 AlwaysonEndpoint2 STARTED 5022 - for node2
Verifique a configuração executando os comandos a seguir no PowerShell:
$node1 = "bookshelf-sql1" $node2 = "bookshelf-sql2" Invoke-Sqlcmd -Query "select name, state_desc, port FROM sys.tcp_endpoints" -ServerInstance $node1 Invoke-Sqlcmd -Query "select name, state_desc, port FROM sys.tcp_endpoints" -ServerInstance $node2
Se a configuração estiver correta, você verá um resultado como este:
name state_desc port ---- ---------- ---- Dedicated Admin Connection STARTED 0 TSQL Default TCP STARTED 0 AlwaysonEndpoint1 STARTED 5022 Dedicated Admin Connection STARTED 0 TSQL Default TCP STARTED 0 AlwaysonEndpoint2 STARTED 5022
Defina os URLs do endpoint:
$EndpointUrlSQLServer1="TCP://" + $node1 + "." + $Domain + ":5022" $EndpointUrlSQLServer2="TCP://" + $node2 + "." + $Domain + ":5022"
Crie uma representação das réplicas na memória:
$PrimaryReplica = New-SqlAvailabilityReplica -Name $node1 ` -EndpointUrl $EndpointUrlSQLServer1 ` -FailoverMode "Automatic" ` -AvailabilityMode "SynchronousCommit" ` -AsTemplate -Version 13 $SecondaryReplica = New-SqlAvailabilityReplica -Name $node2 ` -EndpointUrl $EndpointUrlSQLServer2 ` -FailoverMode "Automatic" ` -AvailabilityMode "SynchronousCommit" ` -AsTemplate -Version 13
Crie o grupo de disponibilidade:
New-SqlAvailabilityGroup -Name $AGName ` -AvailabilityReplica @($PrimaryReplica, $SecondaryReplica) ` -Path "SQLSERVER:\SQL\$node1.$Domain\Default" ` -Database $Database
Conecte a instância secundária ao grupo de disponibilidade:
Join-SqlAvailabilityGroup -Path "SQLSERVER:\SQL\$node2\Default" -Name $AGName
Conecte ao banco de dados secundário para o grupo de disponibilidade:
Add-SqlAvailabilityDatabase ` -Path "SQLSERVER:\SQL\$node2\Default\AvailabilityGroups\$AGName" ` -Database $Database
Crie o listener:
New-SqlAvailabilityGroupListener -Name $ListenerName ` -Port 1433 ` -StaticIp @("$ipWSListener1/255.255.255.0","$ipWSListener2/255.255.255.0") ` -Path SQLSERVER:\Sql\$node1\Default\AvailabilityGroups\$AGName
Remova a pasta compartilhada, que não é mais necessária:
For ($i=0; $i -le 30; $i++) { try { Remove-Item \\$node2\c$\$BackupFolder -Force -Recurse -ErrorAction Stop Write-Host "Shared folder $SharedLocation was removed" break } catch { Write-Host "\\$node2\c$\$BackupFolder is in use waiting 1m to retry" Start-Sleep -s 60 } }
Limpeza
Se você quiser continuar para o próximo tutorial desta série (Como implantar servidores da Web do IIS com balanceamento de carga), mantenha os recursos criados neste tutorial. No entanto, se você não pretende usar o ambiente criado neste tutorial, limpe os recursos criados no Google Cloud para não ser cobrado por eles. Nas seções a seguir, você aprenderá a excluir e desativar esses recursos.
Como excluir o projeto
Como excluir instâncias
Se você não quiser excluir seu projeto completamente, poderá excluir os recursos específicos criados.
Para excluir uma instância do Compute Engine:
No console do Google Cloud, acesse a página Instâncias de VMs.
Selecione as instâncias que você quer excluir.
Na parte superior da página, clique em Excluir para excluir as instâncias.
Como excluir redes VPC
Para excluir a rede VPC, sub-redes e regras de firewall:
No console do Google Cloud, acesse a página "Redes VPC".
Selecione a rede VPC que você criou.
Na parte superior da página, clique em Excluir para excluir a rede.
A seguir
- Prossiga para o próximo tutorial desta série:
- Saiba mais sobre o SQL Server no Google Cloud:
- Consulte as práticas recomendadas para projetar cargas de trabalho escalonáveis e altamente disponíveis.
- Confira arquiteturas de referência, diagramas e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.