快速入门:在 Azure 上部署 SQL Server 容器群集

适用于:SQL Server - Linux

本快速入门演示如何使用永久性存储在 Azure Kubernetes 服务 (AKS) 或 Red Hat OpenShift 上的容器中配置高可用性 SQL Server 实例。 如果 SQL Server 实例发生故障,业务流程协调程序会自动在新 Pod 中重新创建实例。 群集服务还针对节点故障提供复原能力。

本快速入门使用以下命令行工具来管理群集。

群集服务 命令行工具
Azure Kubernetes 服务 (AKS) kubectl (Kubernetes CLI)
Azure Red Hat OpenShift oc (OpenShift CLI)

先决条件

创建 SA 密码

  1. 在 Kubernetes 群集中创建 SA 密码。 Kubernetes 可以管理敏感的配置信息,例如密码(即密钥)。

  2. 若要在 Kubernetes 中创建一个名为 mssql 且保存 MSSQL_SA_PASSWORD 的值 MyC0m9l&xP@ssw0rd 的密钥,请运行以下命令。 请记住选择自己的复杂密码:

    重要

    SA_PASSWORD 环境变量已弃用。 请改用 MSSQL_SA_PASSWORD

    kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="MyC0m9l&xP@ssw0rd"
    

创建存储

对于 Kubernetes 群集中的数据库,必须使用持久性存储。 可在 Kubernetes 群集中使用以下步骤配置永久性卷永久性卷声明

  1. 请创建清单以定义存储类和永久性卷声明。 清单可指定存储配置程序、参数和回收策略。 Kubernetes 群集使用此清单来创建永久性存储。

  2. 以下 YAML 示例定义了存储类和永久性卷声明。 存储类配置程序为 azure-disk,因为此 Kubernetes 群集位于 Azure 中。 存储帐户类型为 Standard_LRS。 永久性卷声明的名称为 mssql-data。 永久性卷声明元数据包含将其连接回存储类的注释。

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
         name: azure-disk
    provisioner: kubernetes.io/azure-disk
    parameters:
      storageaccounttype: Standard_LRS
      kind: Managed
    ---
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: mssql-data
      annotations:
        volume.beta.kubernetes.io/storage-class: azure-disk
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 8Gi
    

    保存文件(例如 pvc.yaml)。

  3. 在 Kubernetes 中创建永久性卷声明,其中 <path to pvc.yaml file> 是保存文件的位置:

    kubectl apply -f <path to pvc.yaml file>
    

    永久性卷自动创建为 Azure 存储帐户,并绑定到永久性卷声明。

    storageclass "azure-disk" created
    persistentvolumeclaim "mssql-data" created
    
  4. 验证永久性卷声明,其中 <persistentVolumeClaim> 是永久性卷声明的名称:

    kubectl describe pvc <persistentVolumeClaim>
    

    在上述步骤中,永久性卷声明的名称为 mssql-data。 要查看有关永久性卷声明的元数据,请运行以下命令:

    kubectl describe pvc mssql-data
    

    返回的元数据包含一个名为 Volume 的值。 此值映射到 blob 的名称。

    Name:          mssql-data
    Namespace:     default
    StorageClass:  azure-disk
    Status:        Bound
    Volume:        pvc-d169b88e-f26d-11e7-bc3e-0a58ac1f09a4
    Labels:        ‹none>
    Annotations:   kubectl.kubernetes.io/last-applied-configuration-{"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{"volume.beta.   kubernetes.io/storage-class":"azure-disk"},"name":"mssq1-data...
                   pv.kubernetes.io/bind-completed-yes
                   pv.kubernetes.io/bound-by-controller=yes
                   volume.beta.kubernetes.io/storage-class=azure-disk
                   volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/azure-disk
    Capacity:      8Gi
    Access Modes:  RWO
    Events:        <none>
    

    卷的值与 Azure 门户中以下图像中的 blob 的部分名称匹配:

    Screenshot of the Azure portal blob name.

  5. 请验证永久性卷。

    kubectl describe pv
    

    kubectl 返回有关自动创建并绑定到永久性卷声明的永久性卷的元数据。

创建部署

托管 SQL Server 实例的容器被描述为 Kubernetes 部署对象。 部署会创建副本集。 副本集会创建 Pod

需要创建一个清单,用于基于 SQL Server mssql-server-linux Docker 映像描述容器。

  • 该清单引用 mssql-server 永久性卷声明以及已应用于 Kubernetes 群集的 mssql 密钥。
  • 清单还将描述一项服务。 此服务是负载均衡器。 负载均衡器保证在恢复 SQL Server 实例后 IP 地址仍保持不变。
  • 清单描述资源请求和限制。 这些内容均基于最低系统要求
  1. 创建用于描述部署的清单(YAML 文件)。 下面的示例描述了部署,包括基于 SQL Server 容器映像的容器。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mssql-deployment
    spec:
      replicas: 1
      selector:
         matchLabels:
           app: mssql
      template:
        metadata:
          labels:
            app: mssql
        spec:
          terminationGracePeriodSeconds: 30
          hostname: mssqlinst
          securityContext:
            fsGroup: 10001
          containers:
          - name: mssql
            image: mcr.microsoft.com/mssql/server:2022-latest
            resources:
              requests:
                memory: "2G"
                cpu: "2000m"
              limits:
                memory: "2G"
                cpu: "2000m"
            ports:
            - containerPort: 1433
            env:
            - name: MSSQL_PID
              value: "Developer"
            - name: ACCEPT_EULA
              value: "Y"
            - name: MSSQL_SA_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mssql
                  key: MSSQL_SA_PASSWORD
            volumeMounts:
            - name: mssqldb
              mountPath: /var/opt/mssql
          volumes:
          - name: mssqldb
            persistentVolumeClaim:
              claimName: mssql-data
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: mssql-deployment
    spec:
      selector:
        app: mssql
      ports:
        - protocol: TCP
          port: 1433
          targetPort: 1433
      type: LoadBalancer
    

    请将上述代码复制到名为 sqldeployment.yaml 的新文件中。 请更新以下值:

    • MSSQL_PID value: "Developer":设置容器以运行 SQL Server Developer 版本。 Developer 版本未获得生产数据许可。 如果部署用于生产,请设置适当的版本(EnterpriseStandardExpress)。 有关详细信息,请参阅如何为 SQL Server 授与许可

    • persistentVolumeClaim设置用户帐户 :此值需要 claimName: 的条目,该条目映射到用于永久性卷声明的名称。 本教程使用 mssql-data

    • name: MSSQL_SA_PASSWORD设置用户帐户 :请配置容器映像以设置 SA 密码,如本部分中所定义。

      valueFrom:
        secretKeyRef:
          name: mssql
          key: MSSQL_SA_PASSWORD
      

      Kubernetes 部署容器时,它引用名为 mssql 的密钥以获取密码的值。

    • securityContext:定义 Pod 或容器的特权和访问控制设置。 在这种情况下,它是在 pod 级别指定的,因此所有容器都遵循该安全上下文。 在安全上下文中,使用值 10001 定义 fsGroup,该值是 mssql 组的组 ID (GID)。 该值表示容器的所有进程也是补充 GID 10001 (mssql) 的一部分。 卷 /var/opt/mssql 以及在该卷中创建的任何文件的所有者将是 GID 10001mssql 组)。

    警告

    使用 LoadBalancer 服务类型,可在端口 1433 远程访问(通过 Internet)SQL Server 实例。

    保存文件。 例如,sqldeployment.yaml

  2. 创建部署,其中 <path to sqldeployment.yaml file> 是保存文件的位置:

    kubectl apply -f <path to sqldeployment.yaml file>
    

    部署和服务现已创建。 SQL Server 实例位于连接到永久性存储的容器中。

    deployment "mssql-deployment" created
    service "mssql-deployment" created
    

    部署和服务现已创建。 SQL Server 实例位于连接到永久性存储的容器中。

    若要查看 Pod 的状态,请键入 kubectl get pod

    NAME                                READY    STATUS    RESTARTS   AGE
    mssql-deployment-3813464711-h312s   1/1      Running   0          17m
    

    Pod 的状态为 Running。 此状态表示容器已准备就绪。 创建部署后,可能需要几分钟时间才能看到 Pod。 延迟是因为群集从 Microsoft 工件注册表拉取 mssql-server-linux 映像。 在第一次拉取映像后,如果是向已缓存了映像的节点进行部署,则后续部署的速度可能更快。

  3. 请验证服务是否正在运行。 运行以下命令:

    kubectl get services
    

    此命令会返回正在运行的服务,以及该服务的内部和外部 IP 地址。 请记下 mssql-deployment 服务的外部 IP 地址。 请使用此 IP 地址以连接到 SQL Server。

    NAME               TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)          AGE
    kubernetes         ClusterIP      10.0.0.1      <none>          443/TCP          52m
    mssql-deployment   LoadBalancer   10.0.113.96   52.168.26.254   1433:30619/TCP   2m
    

    有关 Kubernetes 群集中的对象状态的详细信息,请运行以下命令。 请记得将 <MyResourceGroup><MyKubernetesClustername> 替换为你的资源组和 Kubernetes 群集名称:

    az aks browse --resource-group <MyResourceGroup> --name <MyKubernetesClustername>
    
  4. 还可通过运行以下命令来验证容器是否以非根身份运行,其中 <nameOfSqlPod> 是 SQL Server Pod 的名称:

    kubectl.exe exec <nameOfSqlPod> -it -- /bin/bash
    

    如果运行 whoami,你可以看到用户名,如 mssqlmssql 是一个非根用户。

    whoami
    

连接到 SQL Server 实例

可使用 sa 帐户和服务的外部 IP 地址从 Azure 虚拟网络外部连接应用程序。 请使用配置为 OpenShift 机密的密码。

可以使用以下应用程序连接到 SQL Server 实例。

使用 sqlcmd 进行连接

要使用 sqlcmd 进行连接,请运行以下命令:

sqlcmd -S <External IP Address> -U sa -P "MyC0m9l&xP@ssw0rd"

请替换以下值:

  • <External IP Address> 替换为 mssql-deployment 服务的 IP 地址
  • MyC0m9l&xP@ssw0rd(使用复杂的密码)

验证故障和恢复

要验证故障和恢复,可通过以下步骤删除 Pod:

  1. 列出运行 SQL Server 的 Pod。

    kubectl get pods
    

    请记下运行 SQL Server 的 Pod 的名称。

  2. 删除 Pod。

    kubectl delete pod mssql-deployment-0
    

    mssql-deployment-0 是从上一步返回的 Pod 名称的值。

Kubernetes 会自动重新创建 Pod 以恢复 SQL Server 实例,并连接到永久性存储。 使用 kubectl get pods 验证是否部署了新的 Pod。 使用 kubectl get services 验证新容器的 IP 地址是否相同。

清理资源

如果不打算完成后续教程,请清理不需要的资源。 可使用 az group delete 命令删除资源组、容器服务及所有相关资源。 将 <MyResourceGroup> 替换为包含群集的资源组的名称。

az group delete --name <MyResourceGroup> --yes --no-wait