Развертывание контейнеров SQL Server Linux в Kubernetes с помощью StatefulSets
Область применения: SQL Server — Linux
В этой статье содержатся рекомендации и рекомендации по запуску контейнеров SQL Server в Kubernetes с помощью StatefulSets. Мы рекомендуем развернуть один контейнер SQL Server (экземпляр) для каждого модуля pod в Kubernetes. Таким образом, в кластере Kubernetes развернут один экземпляр SQL Server.
Аналогичным образом, рекомендация по скрипту развертывания заключается в развертывании одного экземпляра replicas
SQL Server путем задания значения 1
. Если ввести число больше 1
replicas
значения, вы получите, что многие экземпляры SQL Server со связанными именами. Например, в приведенном ниже сценарии, если вы назначили номер в качестве значения 2
replicas
, необходимо развернуть два модуля pod SQL Server с именами mssql-0
и mssql-1
соответственно.
Другая причина, по которой рекомендуется использовать один sql Server для каждого сценария развертывания, заключается в том, чтобы разрешить изменения значений конфигурации, выпусков, флагов трассировки и других параметров для каждого развернутого экземпляра SQL Server.
В следующем примере имя рабочей нагрузки StatefulSet должно соответствовать .spec.template.metadata.labels
значению, которое в данном случае является mssql
. Дополнительные сведения см. в разделе StatefulSets.
Внимание
Переменная среды SA_PASSWORD
является нерекомендуемой. Вместо этого используйте MSSQL_SA_PASSWORD
.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql # name of the StatefulSet workload, the SQL Server instance name is derived from this. We suggest to keep this name same as the .spec.template.metadata.labels, .spec.selector.matchLabels and .spec.serviceName to avoid confusion.
spec:
serviceName: "mssql" # serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set.
replicas: 1 # only one pod, with one SQL Server instance deployed.
selector:
matchLabels:
app: mssql # this has to be the same as .spec.template.metadata.labels
template:
metadata:
labels:
app: mssql # this has to be the same as .spec.selector.matchLabels, as documented [here](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/):
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql # container name within the pod.
image: mcr.microsoft.com/mssql/server:2022-latest
ports:
- containerPort: 1433
name: tcpsql
env:
- name: ACCEPT_EULA
value: "Y"
- name: MSSQL_ENABLE_HADR
value: "1"
- name: MSSQL_AGENT_ENABLED
value: "1"
- name: MSSQL_SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql
key: MSSQL_SA_PASSWORD
volumeMounts:
- name: mssql
mountPath: "/var/opt/mssql"
volumeClaimTemplates:
- metadata:
name: mssql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
Если вы по-прежнему решили развернуть несколько реплик экземпляра SQL Server с помощью одного развертывания, этот сценарий рассматривается в следующем разделе. Однако это отдельные независимые экземпляры SQL Server, а не реплики (в отличие от реплик групп доступности в SQL Server).
Выбор типа рабочей нагрузки
Выбор подходящего типа развертывания рабочей нагрузки не влияет на производительность, но StatefulSet предоставляет требования к готовности к идентификации.
Рабочие нагрузки StatefulSet
SQL Server — это приложение базы данных, поэтому в основном следует развертывать как тип рабочей нагрузки StatefulSet . Развертывание рабочих нагрузок в качестве StatefulSet помогает предоставлять такие функции, как уникальные сетевые идентификации, постоянное и стабильное хранилище и многое другое. Дополнительные сведения об этом типе рабочей нагрузки см. в документации Kubernetes.
При развертывании нескольких реплик контейнеров SQL Server с использованием того же скрипта развертывания YAML, что и рабочая нагрузка StatefulSet, важно учитывать политики управления pod, то есть .spec.podManagementPolicy
.
Для этого параметра возможны два значения:
OrderedReady: это значение по умолчанию, и поведение, как описано в гарантиях развертывания и масштабирования.
Параллельно. Это альтернативная политика, которая создает и запускает модули pod (в данном случае sql Server pod) параллельно, не ожидая создания других модулей pod аналогично, все модули pod удаляются параллельно во время завершения. Этот параметр можно использовать при развертывании экземпляров SQL Server, которые не зависят друг от друга, и если вы не планируете выполнять порядок запуска или удаления экземпляров SQL Server.
apiVersion: apps/v1 kind: StatefulSet metadata: name: mssql spec: serviceName: "mssql" replicas: 2 # two independent SQL Server instances to be deployed podManagementPolicy: Parallel selector: matchLabels: app: mssql template: metadata: labels: app: mssql spec: securityContext: fsGroup: 10001 containers: - name: mssql image: mcr.microsoft.com/mssql/server:2022-latest ports: - containerPort: 1433 name: tcpsql env: - name: ACCEPT_EULA value: "Y" - name: MSSQL_ENABLE_HADR value: "1" - name: MSSQL_AGENT_ENABLED value: "1" - name: MSSQL_SA_PASSWORD valueFrom: secretKeyRef: name: mssql key: MSSQL_SA_PASSWORD volumeMounts: - name: mssql mountPath: "/var/opt/mssql" volumeClaimTemplates: - metadata: name: mssql spec: accessModes: - ReadWriteOnce resources: requests: storage: 8Gi
Так как модули pod SQL Server, развернутые в Kubernetes, не зависят друг от друга, Parallel
обычно используется для podManagementPolicy
.
В следующем примере приведен пример выходных данных для kubectl get all
сразу после создания модулей pod с помощью параллельной политики:
NAME READY STATUS RESTARTS AGE
pod/mssql-0 0/1 ContainerCreating 0 4s
pod/mssql-1 0/1 ContainerCreating 0 4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 201.0.0.1 <none> 443/TCP 61d
NAME READY AGE
statefulset.apps/mssql 1/1 4s
Рабочие нагрузки развертывания
Тип развертывания для SQL Server можно использовать в сценариях, в которых требуется развернуть контейнеры SQL Server в качестве приложений базы данных без отслеживания состояния, например если сохраняемость данных не является критической. Некоторые из таких примеров предназначены для целей тестирования/QA или CI/CD.
Изоляция через пространства имен
Пространства имен предоставляют механизм изоляции групп ресурсов в одном кластере Kubernetes. Дополнительные сведения о пространствах имен и их использовании см. в разделе "Пространства имен".
С точки зрения SQL Server, если вы планируете запускать модули pod SQL Server в кластере Kubernetes, который также размещает другие ресурсы, следует запускать модули pod SQL Server в собственном пространстве имен, чтобы упростить управление и администрирование. Например, рассмотрите возможность совместного использования нескольких отделов в одном кластере Kubernetes, и вы хотите развернуть экземпляр SQL Server для группы продаж и другую для группы маркетинга. Вы создадите два пространства sales
имен и marketing
, как показано в следующем примере:
kubectl create namespace sales
kubectl create namespace marketing
Чтобы убедиться, что пространства имен созданы, запустите kubectl get namespaces
и вы увидите список, аналогичный приведенным ниже выходным данным.
NAME STATUS AGE
default Active 39d
kube-node-lease Active 39d
kube-public Active 39d
kube-system Active 39d
marketing Active 7s
sales Active 26m
Теперь можно развернуть контейнеры SQL Server в каждом из этих пространств имен с помощью примера YAML, показанного в следующем примере. Обратите внимание, что метаданные namespace
, добавленные в YAML развертывания, поэтому все контейнеры и службы этого развертывания развертываются в sales
пространстве имен.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: azure-disk
provisioner: kubernetes.io/azure-disk
parameters:
storageAccountType: Standard_LRS
kind: Managed
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql-sales
namespace: sales
labels:
app: mssql-sales
spec:
serviceName: "mssql-sales"
replicas: 1
selector:
matchLabels:
app: mssql-sales
template:
metadata:
labels:
app: mssql-sales
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql-sales
image: mcr.microsoft.com/mssql/server:2022-latest
ports:
- containerPort: 1433
name: tcpsql
env:
- name: ACCEPT_EULA
value: "Y"
- name: MSSQL_ENABLE_HADR
value: "1"
- name: MSSQL_AGENT_ENABLED
value: "1"
- name: MSSQL_SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql
key: MSSQL_SA_PASSWORD
volumeMounts:
- name: mssql
mountPath: "/var/opt/mssql"
volumeClaimTemplates:
- metadata:
name: mssql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
---
apiVersion: v1
kind: Service
metadata:
name: mssql-sales-0
namespace: sales
spec:
type: LoadBalancer
selector:
statefulset.kubernetes.io/pod-name: mssql-sales-0
ports:
- protocol: TCP
port: 1433
targetPort: 1433
name: tcpsql
Чтобы просмотреть ресурсы, можно выполнить kubectl get all
команду с указанным пространством имен, чтобы просмотреть следующие ресурсы:
kubectl get all -n sales
NAME READY STATUS RESTARTS AGE
pod/mssql-sales-0 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mssql-sales-0 LoadBalancer 10.0.251.120 20.23.79.52 1433:32052/TCP 17m
NAME READY AGE
statefulset.apps/mssql-sales 1/1 17m
Пространства имен также можно использовать для ограничения ресурсов и модулей pod, созданных в пространстве имен, с помощью диапазонов ограничений и (или) политик квот ресурсов для управления общими ресурсами в пространстве имен.
Настройка качества обслуживания pod
При развертывании нескольких модулей pod в одном кластере Kubernetes необходимо совместно использовать ресурсы, чтобы обеспечить эффективное выполнение кластера Kubernetes. Вы можете настроить модули pod таким образом, чтобы они назначили определенное качество обслуживания (QoS).
Kubernetes использует классы качества обслуживания для принятия решений о планировании и вытеснения модулей pod. Дополнительные сведения о различных классах качества обслуживания см. в разделе "Настройка качества обслуживания для модулей Pod".
С точки зрения SQL Server рекомендуется развертывать модули pod SQL Server с помощью QoS Guaranteed
для рабочих нагрузок на основе рабочих нагрузок. Учитывая, что модуль pod SQL Server имеет только один экземпляр контейнера SQL Server, работающий для обеспечения гарантированного качества обслуживания для этого модуля, необходимо указать запросы ЦП и памяти для контейнера, который должен быть равен ограничениям памяти и ЦП. Это гарантирует, что узлы предоставляют и фиксируют необходимые ресурсы, указанные во время развертывания, и имеют прогнозируемую производительность для модулей pod SQL Server.
Ниже приведен пример развертывания YAML, который развертывает один контейнер SQL Server в пространстве имен по умолчанию, и так как запросы ресурсов не указаны, но ограничения были указаны в соответствии с рекомендациями в примере гарантированного качества обслуживания , мы видим, что модуль pod, созданный в следующем примере, имеет значение Guaranteed
QoS. Если запросы ресурсов не указаны, Kubernetes учитывает ограничения ресурсов, равные запросам ресурсов.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: azure-disk
provisioner: kubernetes.io/azure-disk
parameters:
storageaccounttype: Standard_LRS
kind: Managed
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql
labels:
app: mssql
spec:
serviceName: "mssql"
replicas: 1
selector:
matchLabels:
app: mssql
template:
metadata:
labels:
app: mssql
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql
command:
- /bin/bash
- -c
- cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
image: mcr.microsoft.com/mssql/server:2022-latest
resources:
limits:
memory: 2Gi
cpu: '2'
ports:
- containerPort: 1433
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: userdata
mountPath: "/var/opt/mssql/userdata"
- name: userlog
mountPath: "/var/opt/mssql/userlog"
- name: tempdb
mountPath: "/var/opt/mssql/tempdb"
- name: mssql-config-volume
mountPath: "/var/opt/config"
volumes:
- name: mssql-config-volume
configMap:
name: mssql
volumeClaimTemplates:
- metadata:
name: mssql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
- metadata:
name: userdata
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
- metadata:
name: userlog
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
- metadata:
name: tempdb
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
Вы можете запустить команду kubectl describe pod mssql-0
, чтобы просмотреть QoS как Guaranteed
и выходные данные, аналогичные приведенному ниже фрагменту кода.
...
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/memory-pressure:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...
Для нерабочих рабочих нагрузок, где производительность и доступность не являются высоким приоритетом, можно задать для QoS Burstable
или BestEffort
.
Пример с возможностью ускорения качества обслуживания
Чтобы определить Burstable
пример YAML, укажите запросы ресурсов, а не ограничения ресурсов, или укажите ограничения, которые выше, чем запросы. Следующий код отображает только разницу в предыдущем примере, чтобы определить рабочая нагрузка с возможностью ускорения .
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql
labels:
app: mssql
spec:
serviceName: "mssql"
replicas: 1
selector:
matchLabels:
app: mssql
template:
metadata:
labels:
app: mssql
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql
command:
- /bin/bash
- -c
- cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
image: mcr.microsoft.com/mssql/server:2022-latest
resources:
requests:
memory: 2Gi
cpu: '2'
Вы можете запустить команду kubectl describe pod mssql-0
, чтобы просмотреть QoS как Burstable
и выходные данные, аналогичные приведенному ниже фрагменту кода.
...
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/memory-pressure:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...
Лучший пример качества обслуживания
Чтобы определить BestEffort
пример YAML, удалите запросы ресурсов и ограничения ресурсов. В конечном итоге вы получите лучшие усилия QoS, как определено в разделе "Создание pod", который получает назначенный класс QoS bestEffort. Как и раньше, следующий код отображает только разницу от Guaranteed
примера, чтобы определить оптимальную рабочую нагрузку. Это наименее рекомендуемые варианты для модулей pod SQL Server, так как они, вероятно, будут первыми, которые должны быть завершены в случае состязания ресурсов. Даже в сценариях тестирования и качества обслуживания рекомендуется использовать параметр "Ускорение" для SQL Server.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql
labels:
app: mssql
spec:
serviceName: "mssql"
replicas: 1
selector:
matchLabels:
app: mssql
template:
metadata:
labels:
app: mssql
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql
command:
- /bin/bash
- -c
- cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
image: mcr.microsoft.com/mssql/server:2022-latest
ports:
- containerPort: 1433
Вы можете запустить команду kubectl describe pod mssql-0
, чтобы просмотреть QoS как BestEffort
и выходные данные, аналогичные приведенному ниже фрагменту кода.
...
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/memory-pressure:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...