Implantar grupos de disponibilidade com o DH2i DxEnterprise no Kubernetes

Aplica-se a: SQL Server no Linux

Este tutorial explica como configurar SQL Server grupos de disponibilidade Always On (AGs) com DH2i DxEnterprise para contêineres baseados em Linux SQL Server implantados em um cluster AKS (Serviço de Kubernetes do Azure) Kubernetes. Você pode escolher entre uma configuração de sidecar (preferencial) ou criar sua própria imagem de contêiner personalizada.

Note

A Microsoft oferece suporte a movimentação de dados, AGs e componentes do SQL Server. O DH2i suporta o produto DxEnterprise, que inclui gerenciamento de cluster e quórum.

Aprenda a implantar um StatefulSet e use o DH2i DxEnterprise para criar e configurar um AG. O tutorial consiste nas seguintes etapas:

  • Criar uma configuração de serviço sem periféricos
  • Criar uma configuração StatefulSet com SQL Server e DxEnterprise no mesmo pod como um contêiner sidecar
  • Criar e configurar um AG do SQL Server, adicionando as réplicas secundárias
  • Criar um banco de dados no AG e testar o failover

Pré-requisitos

Este tutorial mostra um exemplo de um AG com três réplicas. Você precisa:

  • Um cluster do AKS (Serviço de Kubernetes do Azure) ou do Kubernetes.
  • Uma licença válida do DxEnterprise com funcionalidades de AG e túneis habilitados. Para obter mais informações, confira a edição do desenvolvedor para uso que não seja de produção ou software DxEnterprise para cargas de trabalho de produção.

Criar o serviço sem periféricos

  1. Em um cluster do Kubernetes, os serviços sem periféricos permitem que os pods se conectem entre si usando nomes de host.

    Para criar o serviço headless, crie um arquivo YAML chamado headless_services.yaml com o seguinte conteúdo de exemplo.

    #Headless services for local connections/resolution
    apiVersion: v1
    kind: Service
    metadata:
      name: dxemssql-0
    spec:
      clusterIP: None
      selector:
        statefulset.kubernetes.io/pod-name: dxemssql-0
      ports:
        - name: dxl
          protocol: TCP
          port: 7979
        - name: dxc-tcp
          protocol: TCP
          port: 7980
        - name: dxc-udp
          protocol: UDP
          port: 7981
        - name: sql
          protocol: TCP
          port: 1433
        - name: listener
          protocol: TCP
          port: 14033
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: dxemssql-1
    spec:
      clusterIP: None
      selector:
        statefulset.kubernetes.io/pod-name: dxemssql-1
      ports:
        - name: dxl
          protocol: TCP
          port: 7979
        - name: dxc-tcp
          protocol: TCP
          port: 7980
        - name: dxc-udp
          protocol: UDP
          port: 7981
        - name: sql
          protocol: TCP
          port: 1433
        - name: listener
          protocol: TCP
          port: 14033
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: dxemssql-2
    spec:
      clusterIP: None
      selector:
        statefulset.kubernetes.io/pod-name: dxemssql-2
      ports:
        - name: dxl
          protocol: TCP
          port: 7979
        - name: dxc-tcp
          protocol: TCP
          port: 7980
        - name: dxc-udp
          protocol: UDP
          port: 7981
        - name: sql
          protocol: TCP
          port: 1433
        - name: listener
          protocol: TCP
          port: 14033
    
  2. Execute o comando a seguir para aplicar a configuração.

    kubectl apply -f headless_services.yaml
    

Criar o StatefulSet

  1. Crie um arquivo YAML StatefulSet com o seguinte conteúdo de exemplo e nomeie-o como dxemssql.yaml.

    Essa configuração StatefulSet cria três réplicas DxEMSSQL que usam reivindicações persistentes de volume para armazenar seus dados. Cada pod nesse StatefulSet é composto por dois contêineres: um contêiner do SQL Server e um contêiner do DxEnterprise. Esses contêineres começam separadamente em configuração sidecar, mas a DxEnterprise gerencia a réplica AG no contêiner SQL Server.

    #DxEnterprise + MSSQL StatefulSet
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: dxemssql
    spec:
      serviceName: "dxemssql"
      replicas: 3
      selector:
        matchLabels:
          app: dxemssql
      template:
        metadata:
          labels:
            app: dxemssql
        spec:
          securityContext:
            fsGroup: 10001
          containers:
            - name: sql
              image: mcr.microsoft.com/mssql/server:2022-latest
              env:
                - name: ACCEPT_EULA
                  value: "Y"
                - name: MSSQL_ENABLE_HADR
                  value: "1"
                - name: MSSQL_SA_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mssql
                      key: MSSQL_SA_PASSWORD
              volumeMounts:
                - name: mssql
                  mountPath: "/var/opt/mssql"
            - name: dxe
              image: docker.io/dh2i/dxe
              env:
                - name: MSSQL_SA_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mssql
                      key: MSSQL_SA_PASSWORD
              volumeMounts:
                - name: dxe
                  mountPath: "/etc/dh2i"
      volumeClaimTemplates:
        - metadata:
            name: dxe
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi
        - metadata:
            name: mssql
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi
    
  2. Crie uma credencial para a instância do SQL Server.

    kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"
    

    Sua senha deve seguir a política de senha padrão do SQL Server. Por padrão, a senha precisa ter pelo menos oito caracteres e conter caracteres de três dos seguintes quatro conjuntos: letras maiúsculas, letras minúsculas, dígitos de base 10 e símbolos. As senhas podem ter até 128 caracteres. Use senhas que sejam tão longas e complexas quanto possível.

  3. Aplique a configuração StatefulSet.

    kubectl apply -f dxemssql.yaml
    
  4. Verifique o status dos pods e prossiga para a próxima etapa quando o status do pod se tornar running.

    kubectl get pods
    kubectl describe pods
    

Criar grupo de disponibilidade e failover de teste

Para detalhes sobre criação e configuração de AG, adição de réplicas e teste de failover, veja Grupos de Disponibilidade do SQL Server no Kubernetes.

Etapas para configurar o ouvinte do grupo de disponibilidade (opcional)

Você também pode configurar um ouvinte de AG por meio das etapas a seguir.

  1. Certifique-se de ter criado o ouvinte AG com o DxEnterprise seguindo a etapa opcional perto do final da documentação do DH2i.

  2. No Kubernetes, você tem a opção de criar endereços IP estáticos. Um endereço IP estático garante que, se você excluir e recriar o serviço de ouvinte, o endereço IP externo atribuído ao seu serviço de ouvinte não mude. Siga as etapas para criar um endereço IP estático no Serviço de Kubernetes do Azure (AKS).

  3. Depois de criar um endereço IP, atribua-o e crie o serviço de balanceamento de carga com o seguinte exemplo de YAML.

    apiVersion: v1
    kind: Service
    metadata:
      name: agslistener
    spec:
      type: LoadBalancer
      loadBalancerIP: <static-IP-address>
      selector:
        app: mssql
      ports:
      - protocol: TCP
        port: 44444
        targetPort: 44444
    

Etapas para configurar o redirecionamento de conexão de leitura/gravação (opcional)

Depois de criar o AG, ative a redireção de conexão de leitura/escrita do secundário para o primário. Confira mais informações em Redirecionamento de conexão leitura/gravação de réplica secundária para primária (Grupos de Disponibilidade Always On).

USE master;
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the primary replica>'
WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL));
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the secondary-0 replica>'
WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL));
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the secondary-1 replica>'
WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL));
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the primary replica>'
WITH (PRIMARY_ROLE(
    READ_WRITE_ROUTING_URL = 'TCP://<External IP address of primary -0>:1433'
));
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the secondary-0 replica>'
WITH (PRIMARY_ROLE(
    READ_WRITE_ROUTING_URL = 'TCP://<External IP address of secondary -0>:1433'
));
GO

ALTER AVAILABILITY GROUP [AGS1]
MODIFY REPLICA ON N'<name of the secondary-1 replica>'
WITH (PRIMARY_ROLE(
    READ_WRITE_ROUTING_URL = 'TCP://<External IP address of secondary -1>:1433'
));
GO