在 Kubernetes 上使用 DH2i DxEnterprise 部署可用性组

适用于:SQL Server - Linux

本教程介绍如何使用 DH2i DxEnterprise 为部署到 Azure Kubernetes 服务 (AKS) Kubernetes 群集的基于 Linux 的 SQL Server 容器配置 SQL Server Always On 可用性组 (AG)。 可以在挎斗配置(首选)之间进行选择,也可以生成自己的自定义容器映像。

注意

Microsoft 支持数据移动、AG 和 SQL Server 组件。 DH2i 负责支持 DxEnterprise 产品,包括群集和仲裁管理。

使用本文中提到的步骤,了解如何部署 StatefulSet,并使用 DH2i DxEnterprise 解决方案创建和配置 AG。 本教程包含以下几个步骤:

  • 创建无外设服务配置
  • 在与挎斗容器相同的 Pod 中使用 SQL Server 和 DxEnterprise 创建 StatefulSet 配置
  • 创建并配置 SQL Server 高可用性组,进而添加次要副本
  • 在 AG 中创建一个数据库并测试故障转移

先决条件

本教程以具有三个副本的 AG 为例进行演示。 需要:

  • Azure Kubernetes 服务 (AKS) 或 Kubernetes 群集。
  • 启用了 AG 功能和隧道的有效 DxEnterprise 许可证。 有关详细信息,请参阅适用于非生产用途的开发人员版或适用于生产工作负载的 DxEnterprise 软件

创建无外设服务

  1. 在 Kubernetes 群集中,无外设服务允许 Pod 使用主机名相互连接。

    若要创建无外设服务,请使用以下示例内容创建名为 headless_services.yaml 的 YAML 文件:

    #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. 运行以下命令以应用配置:

    kubectl apply -f headless_services.yaml
    

创建 StatefulSet

  1. 使用以下示例内容创建 StatefulSet YAML 文件,并将其命名为 dxemssql.yaml

    此 StatefulSet 配置创建三个 DxEMSSQL 副本,这些副本利用永久性卷声明来存储其数据。 此 StatefulSet 中的每个 Pod 都包含两个容器:SQL Server 容器和 DxEnterprise 容器。 这些容器在“挎斗”配置中彼此独立启动,但 DxEnterprise 管理 SQL Server 容器中的 AG 副本。

    #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. 为 SQL Server 实例创建凭据。

    kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"
    
  3. 应用 StatefulSet 配置。

    kubectl apply -f dxemssql.yaml
    
  4. 验证 Pod 的状态,并在 Pod 的状态变为 running 时继续执行下一步。

    kubectl get pods
    kubectl describe pods
    

创建可用性组并测试故障转移

有关创建和配置高可用性组、添加副本和测试故障转移的详细信息,请参阅 Kubernetes 中的 SQL Server 可用性组

可用性组侦听程序的配置步骤(可选)

还可以通过以下步骤配置 AG 侦听器:

  1. 确保已使用 DxEnterprise 创建 AG 侦听程序,如 DH2i 文档接近末尾处的额外步骤中所述。

  2. 在 Kubernetes 中,可选择性地创建静态 IP 地址。 创建静态 IP 地址时,应确保如果侦听程序服务被删除再重新创建,分配给你的侦听程序的外部 IP 地址不会更改。 按照这些步骤,在 Azure Kubernetes 服务 (AKS) 中创建静态 IP 地址

  3. 创建 IP 地址后,需要分配该 IP 地址并创建负载均衡器服务,如下面 YAML 示例所示:

    apiVersion: v1
    kind: Service
    metadata:
      name: agslistener
    spec:
      type: LoadBalancer
      loadBalancerIP: 52.140.117.62
      selector:
        app: mssql
      ports:
      - protocol: TCP
        port: 44444
        targetPort: 44444
    

配置读/写连接重定向的步骤(可选)

创建 AG 后,可以按照以下步骤启用从次要副本到主要副本的读/写连接重定向。 有关详细信息,请参阅次要副本到主要副本读/写连接重定向(AlwaysOn 可用性组)

USE [master];
GO

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

USE [master];
GO

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

USE [master];
GO

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

USE [master];
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

USE [master];
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

USE [master];
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