Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk:SQL Server di Linux
Artikel ini berisi praktik dan panduan terbaik untuk menjalankan kontainer SQL Server di Kubernetes dengan StatefulSets. Sebaiknya sebarkan satu kontainer SQL Server (instans) per pod di Kubernetes. Dengan demikian, Anda memiliki satu instans SQL Server yang disebarkan per pod di kluster Kubernetes.
Demikian pula, rekomendasi skrip penyebaran adalah untuk menyebarkan satu instans SQL Server dengan mengatur nilai replicas ke 1. Jika Anda memasukkan angka yang lebih besar dari 1 sebagai nilai replicas, Anda mendapatkan banyak instans SQL Server dengan nama yang berkorelasi. Misalnya, dalam skrip di bawah ini, jika Anda menetapkan angka 2 sebagai nilai untuk replicas, Anda akan menyebarkan dua pod SQL Server, dengan nama mssql-0 dan mssql-1 masing-masing.
Alasan lain kami merekomendasikan satu SQL Server per skrip penyebaran adalah untuk memungkinkan perubahan pada nilai konfigurasi, edisi, bendera pelacakan, dan pengaturan lain dapat dilakukan secara independen untuk setiap instans SQL Server yang disebarkan.
Dalam contoh berikut, nama beban kerja StatefulSet harus cocok dengan .spec.template.metadata.labels nilai, yang dalam hal ini adalah mssql. Untuk informasi lebih lanjut, lihat StatefulSets.
Penting
Variabel SA_PASSWORD lingkungan tidak digunakan lagi. Gunakan MSSQL_SA_PASSWORD sebagai gantinya.
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. See <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
Jika Anda masih memilih untuk menyebarkan lebih dari satu replika instans SQL Server menggunakan penyebaran yang sama, skenario tersebut tercakup di bagian berikutnya. Namun, ini adalah instans SQL Server independen terpisah dan bukan replika (tidak seperti replika grup ketersediaan di SQL Server).
Pilih jenis beban kerja
Memilih jenis penyebaran beban kerja yang tepat tidak memengaruhi performa, tetapi StatefulSet memang menyediakan persyaratan kelekatan identitas.
Beban kerja StatefulSet
SQL Server adalah aplikasi database dan dengan demikian sebagian besar harus disebarkan sebagai jenis beban kerja StatefulSet . Menyebarkan beban kerja sebagai StatefulSet membantu menyediakan fitur seperti identifikasi jaringan unik, penyimpanan persisten dan stabil, dan banyak lagi. Untuk informasi selengkapnya tentang jenis beban kerja ini, lihat dokumentasi Kubernetes.
Saat menyebarkan lebih dari satu replika kontainer SQL Server menggunakan skrip YAML penyebaran yang sama dengan beban kerja StatefulSet, parameter penting yang perlu dipertimbangkan adalah kebijakan manajemen Pod, yaitu, .spec.podManagementPolicy.
Ada dua nilai yang mungkin untuk pengaturan ini:
OrderedReady: Ini adalah nilai default, dan perilakunya seperti yang dijelaskan dalam jaminan penyebaran dan penskalaan.
Paralel: Ini adalah kebijakan alternatif yang membuat dan meluncurkan pod (dalam hal ini pod SQL Server) secara paralel, tanpa menunggu pod lain dibuat Demikian pula, semua pod dihapus secara paralel selama penghentian. Anda dapat menggunakan opsi ini saat menyebarkan instans SQL Server yang independen satu sama lain, dan ketika Anda tidak berniat mengikuti urutan untuk memulai atau menghapus instans 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
Karena pod SQL Server yang disebarkan pada Kubernetes independen satu sama lain, Parallel adalah nilai yang biasanya digunakan untuk podManagementPolicy.
Sampel berikut adalah contoh output untuk kubectl get all, tepat setelah membuat pod menggunakan kebijakan paralel:
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
Beban kerja penyebaran
Anda dapat menggunakan jenis penyebaran untuk SQL Server, dalam skenario di mana Anda ingin menyebarkan kontainer SQL Server sebagai aplikasi database stateless, misalnya ketika persistensi data tidak penting. Beberapa contoh tersebut adalah untuk tujuan pengujian/QA atau CI/CD.
Isolasi melalui namespace
Namespace menyediakan mekanisme untuk mengisolasi grup sumber daya dalam satu kluster Kubernetes. Untuk informasi selengkapnya tentang namespace layanan dan kapan menggunakannya, lihat Namespace.
Dari perspektif SQL Server, jika Anda berencana untuk menjalankan pod SQL Server pada kluster Kubernetes yang juga menghosting sumber daya lain, Anda harus menjalankan pod SQL Server di namespace layanan mereka sendiri, untuk kemudahan manajemen dan administrasi. Misalnya, pertimbangkan bahwa Anda memiliki beberapa departemen yang berbagi kluster Kubernetes yang sama, dan Anda ingin menyebarkan instans SQL Server untuk tim Penjualan dan satu lagi untuk tim Pemasaran. Anda akan membuat dua namespace yang disebut sales dan marketing, seperti yang diperlihatkan dalam contoh berikut:
kubectl create namespace sales
kubectl create namespace marketing
Untuk memeriksa apakah namespace dibuat, jalankan kubectl get namespaces, dan Anda akan melihat daftar yang mirip dengan output berikut.
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
Sekarang Anda dapat menyebarkan kontainer SQL Server di setiap namespace layanan ini menggunakan contoh YAML yang ditunjukkan dalam contoh berikut.
namespace Perhatikan metadata yang ditambahkan ke YAML penyebaran, sehingga semua kontainer dan layanan penyebaran ini disebarkan di sales namespace.
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
Untuk melihat sumber daya, Anda dapat menjalankan kubectl get all perintah dengan namespace yang ditentukan untuk melihat sumber daya ini:
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
Namespace juga dapat digunakan untuk membatasi sumber daya dan pod yang dibuat dalam namespace, menggunakan rentang batas dan/atau kebijakan kuota sumber daya, untuk mengelola keseluruhan pembuatan sumber daya dalam namespace.
Mengonfigurasi Kualitas Layanan Pod
Saat menyebarkan beberapa pod pada satu kluster Kubernetes, Anda harus berbagi sumber daya dengan tepat, untuk memastikan berjalannya kluster Kubernetes secara efisien. Anda dapat mengonfigurasi pod sehingga diberi Kualitas Layanan (QoS) tertentu.
Kubernetes menggunakan kelas QoS untuk membuat keputusan tentang penjadwalan dan penghapusan pod. Untuk informasi selengkapnya tentang berbagai kelas QoS, lihat Mengonfigurasi Kualitas Layanan untuk Pod.
Dari perspektif SQL Server, kami sarankan Anda menyebarkan pod SQL Server menggunakan QoS seperti Guaranteed untuk beban kerja berbasis produksi. Mengingat bahwa pod SQL Server hanya memiliki satu instans kontainer SQL Server yang berjalan untuk mencapai QoS yang dijamin untuk pod tersebut, Anda perlu menentukan permintaan CPU dan memori untuk kontainer yang harus sama dengan batas memori dan CPU. Ini memastikan bahwa node menyediakan dan mengalokasikan sumber daya yang diperlukan yang ditentukan selama penyebaran, dan memiliki performa yang dapat diprediksi untuk pod SQL Server.
Berikut adalah YAML penyebaran sampel yang menyebarkan satu kontainer SQL Server di dalam namespace default. Karena permintaan sumber daya tidak ditentukan tetapi batasan ditetapkan sesuai dengan pedoman pada contoh Kualitas Layanan Terjamin, kami melihat bahwa pod yang dibuat dalam contoh berikut memiliki QoS yang ditetapkan sebagai Guaranteed. Ketika Anda tidak menentukan permintaan sumber daya, maka Kubernetes mempertimbangkan batas sumber daya yang sama dengan permintaan sumber daya.
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
Anda dapat menjalankan perintah kubectl describe pod mssql-0 untuk melihat QoS sebagai Guaranteed, dengan output yang mirip dengan cuplikan berikut.
...
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
...
Untuk beban kerja non-produksi, di mana performa dan ketersediaan bukan prioritas tinggi, Anda dapat mempertimbangkan untuk mengatur QoS ke Burstable atau BestEffort.
Sampel QoS yang dapat meledak
Untuk menentukan Burstable contoh YAML, Anda menentukan permintaan sumber daya, bukan batas sumber daya; atau Anda menentukan batas sumber daya, yang lebih tinggi daripada permintaan sumber daya. Kode berikut hanya menampilkan perbedaan dari contoh sebelumnya, untuk menentukan beban kerja yang bersifat lonjakan.
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'
Anda dapat menjalankan perintah kubectl describe pod mssql-0 untuk melihat QoS sebagai Burstable, dengan output yang mirip dengan cuplikan berikut.
...
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
...
Sampel Upaya Terbaik untuk QoS
Untuk menentukan BestEffort contoh YAML, hapus permintaan sumber daya dan batas sumber daya. Anda akan mendapatkan QoS Best Effort, sebagaimana didefinisikan dalam Membuat Pod yang diberi kelas QoS BestEffort. Seperti sebelumnya, kode berikut hanya menampilkan perbedaan dari Guaranteed contoh, untuk menentukan beban kerja upaya terbaik. Ini adalah opsi yang paling tidak direkomendasikan untuk pod SQL Server, karena mungkin akan menjadi yang pertama dihentikan dalam kasus persaingan sumber daya. Bahkan untuk skenario pengujian dan QA, sebaiknya gunakan opsi Burstable untuk 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
Anda dapat menjalankan perintah kubectl describe pod mssql-0 untuk melihat QoS sebagai BestEffort, dengan output yang mirip dengan cuplikan berikut.
...
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
...
Dukungan untuk cgroup (control group) v2
SQL Server mendeteksi dan menghormati batasan grup kontrol (cgroup) v2, dimulai dengan SQL Server 2025 (17.x) dan SQL Server 2022 (16.x) Pembaruan Kumulatif (CU) 20. Batasan ini memberikan kontrol mendetail di kernel Linux melalui sumber daya CPU dan memori, dan meningkatkan isolasi sumber daya di lingkungan Docker, Kubernetes, dan OpenShift.
Dalam versi sebelumnya, penyebaran kontainer pada kluster Kubernetes (misalnya, Azure Kubernetes Service v1.25+) dapat mengalami kesalahan kehabisan memori (OOM) karena SQL Server tidak memberlakukan batas memori yang ditentukan dalam spesifikasi kontainer. Dukungan untuk cgroup v2 mengatasi masalah ini.
Periksa versi cgroup
stat -fc %T /sys/fs/cgroup
Hasilnya adalah sebagai berikut:
| Result | Description |
|---|---|
cgroup2fs |
Anda menggunakan cgroup v2 |
cgroup |
Anda menggunakan cgroup v1 |
Beralih ke cgroup v2
Jalur termudah adalah memilih distribusi yang mendukung cgroup v2 secara default.
Jika Anda perlu beralih secara manual, tambahkan parameter berikut ke konfigurasi GRUB Anda:
systemd.unified_cgroup_hierarchy=1
Kemudian perbarui GRUB. Misalnya, di Ubuntu, jalankan:
sudo update-grub
Di Red Hat Enterprise Linux (RHEL), jalankan:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Pelaporan batas CPU dengan cgroup v2
Saat Anda mengonfigurasi batas CPU menggunakan cgroup v2, SQL Server tidak menampilkan jumlah inti CPU yang dikonfigurasi dalam log kesalahan. Sebaliknya, ia terus melaporkan jumlah total CPU host.
Untuk menyelaraskan penjadwal tugas SQL Server dan rencana kueri (misalnya, pengambilan keputusan paralelisme) dengan jumlah CPU yang diinginkan yang ditentukan dalam cgroup v2, Anda dapat menerapkan konfigurasi berikut.
Mengonfigurasi afinitas prosesor
Atur afinitas prosesor SQL Server secara eksplisit agar sesuai dengan kuota eksekusi cgroup. Dalam contoh berikut, kuota cgroup adalah empat CPU pada host delapan inti:
ALTER SERVER CONFIGURATION
SET PROCESS AFFINITY CPU = 0 TO 3;
Konfigurasi ini memastikan bahwa SQL Server membuat penjadwal hanya untuk jumlah CPU yang dimaksudkan. Untuk informasi selengkapnya, lihat MENGUBAH KONFIGURASI SERVER dan Menggunakan AFINITAS PROSES untuk Node dan/atau CPU.
Aktifkan bendera pelacakan 8002 (disarankan)
Aktifkan bendera pelacakan 8002 untuk menggunakan afinitas lunak di lapisan SQLPAL:
sudo /opt/mssql/bin/mssql-conf traceflag 8002 on
Secara default, penjadwal terikat ke CPU tertentu yang ditentukan dalam masker afinitas. Penanda jejak 8002 memungkinkan penjadwal untuk berpindah antar CPU, yang umumnya meningkatkan performa sambil tetap menghormati batasan afinitas dan cgroup. Untuk informasi selengkapnya, lihat DBCC TRACEON - Trace Flags.
Mulai ulang SQL Server setelah mengaktifkan bendera pelacakan.
Perilaku yang diharapkan
Setelah menghidupkan ulang:
SQL Server hanya membuat jumlah penjadwal yang ditentukan oleh pengaturan afinitas (misalnya, empat penjadwal).
Kernel Linux terus memberlakukan kuota eksekusi CPU cgroup v2.
Keputusan optimasi kueri dan paralelisme didasarkan pada jumlah CPU yang direncanakan, bukan total CPU host.
Catatan
Log kesalahan SQL Server mungkin terus menampilkan jumlah CPU host total. Perilaku pengelogan dan tampilan ini tidak memengaruhi penggunaan CPU aktual, pembuatan penjadwal, atau penegakan CPU oleh cgroup v2 atau afinitas prosesor.
Untuk informasi selengkapnya, lihat sumber daya berikut ini:
- Mulai cepat: Menyebarkan kontainer SQL Server Linux ke Kubernetes menggunakan bagan Helm
- Grup Kontrol v2 (dokumentasi Kernel Linux)