在容器服務(wù) Serverless 版上部署有狀態(tài)的高可用MySQL集群
高可用是分布式應(yīng)用的重要要求,在ACK Serverless集群中,您可以通過K8s原生調(diào)度語義實現(xiàn)分布式應(yīng)用的跨可用區(qū)打散,以達到高可用部署的要求。本文檔介紹如何在容器服務(wù) Serverless 版上部署有狀態(tài)的高可用MySQL集群。
前提條件
已創(chuàng)建ACK Serverless集群(含多個虛擬節(jié)點)。具體操作,請參見創(chuàng)建ACK Serverless集群。
已開啟虛擬節(jié)點調(diào)度策略。具體操作,請參見開啟ACK Serverless集群虛擬節(jié)點調(diào)度策略。
已安裝csi-provisioner組件且版本 >= v1.22.9。
步驟一:從Github拉取用于創(chuàng)建K8s資源的YAML文件
執(zhí)行以下命令,克隆代碼庫。
git clone https://github.com/AliyunContainerService/serverless-k8s-examples.git
執(zhí)行以下命令,進入工作目錄,并查看目錄下YAML文件列表。
cd serverless-k8s-examples/stateful-mysql ls -al
預(yù)期輸出:
README.md secret.yaml stateful-mysql.yaml storageclass.yaml
其中
secret.yaml
用于創(chuàng)建Secret,storageclass.yaml
用于創(chuàng)建StorageClass,stateful-mysql.yaml
用于創(chuàng)建MySQL StatefulSet。
步驟二:創(chuàng)建NameSpace、Secret、StorageClass
執(zhí)行以下命令,創(chuàng)建命名空間
mysql
。kubectl create namespace mysql
預(yù)期輸出:
namespace/mysql created
執(zhí)行以下命令,創(chuàng)建MySQL Secret,用于存儲MySQL密碼。
kubectl apply -n mysql -f secret.yaml
預(yù)期輸出:
secret/mysql-secret created
以下為該Secret的YAML文件。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-storageclass provisioner: diskplugin.csi.alibabacloud.com parameters: type: cloud_auto,cloud_essd,cloud_ssd # 使用該配置,按優(yōu)先級自適應(yīng)選擇云盤類型,最終創(chuàng)建的云盤類型受節(jié)點實例、所在可用區(qū)云盤支持情況等因素影響。 fstype: ext4 diskTags: "a:b,b:c" encrypted: "false" performanceLevel: PL1 volumeExpandAutoSnapshot: "forced" # 該設(shè)置僅在創(chuàng)建的云盤類型為cloud_essd時生效。 provisionedIops: "40000" burstingEnabled: "false" volumeBindingMode: WaitForFirstConsumer # 表示推遲云盤創(chuàng)建直到Pod創(chuàng)建,可實現(xiàn)云盤在Pod所在可用區(qū)創(chuàng)建。 reclaimPolicy: Retain allowVolumeExpansion: true
執(zhí)行以下命令,創(chuàng)建StorageClass。
kubectl apply -f storageclass.yaml
預(yù)期輸出:
storageclass.storage.k8s.io/fast-storageclass created
以下為該StorageClass的YAML文件。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-storageclass provisioner: diskplugin.csi.alibabacloud.com parameters: type: cloud_auto,cloud_essd,cloud_ssd # 使用該配置,按優(yōu)先級自適應(yīng)選擇云盤類型,最終創(chuàng)建的云盤類型受節(jié)點實例、所在可用區(qū)云盤支持情況等因素影響。 fstype: ext4 diskTags: "a:b,b:c" encrypted: "false" performanceLevel: PL1 volumeExpandAutoSnapshot: "forced" # 該設(shè)置僅在創(chuàng)建的云盤類型為cloud_essd時生效。 provisionedIops: "40000" burstingEnabled: "false" volumeBindingMode: WaitForFirstConsumer # 表示推遲云盤創(chuàng)建直到Pod創(chuàng)建,可實現(xiàn)云盤在Pod所在可用區(qū)創(chuàng)建。 reclaimPolicy: Retain allowVolumeExpansion: true
步驟三:配置Pod可用區(qū)打散,創(chuàng)建MySQL StatefulSet
執(zhí)行以下命令,創(chuàng)建MySQL StatefulSet。本示例將創(chuàng)建一個通過配置虛擬節(jié)點Pod可用區(qū)打散,在多個可用區(qū)上均勻分布的StatefulSet。關(guān)于如何配置虛擬節(jié)點Pod可用區(qū)打散,請參見實現(xiàn)ECI Pod可用區(qū)打散以及親和調(diào)度。
kubectl apply -n mysql -f stateful-mysql.yaml
預(yù)期輸出:
statefulset.apps/dbc1 created
以下為該StatefulSet的YAML文件。
apiVersion: apps/v1 kind: StatefulSet metadata: name: dbc1 labels: app: mysql spec: replicas: 3 selector: matchLabels: app: mysql serviceName: mysql template: metadata: labels: app: mysql spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: mysql affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - mysql topologyKey: "kubernetes.io/hostname" containers: - name: mysql image: registry.cn-hangzhou.aliyuncs.com/kubeway/hub:mysql-server_8.0.28 command: - /bin/bash args: - -c - >- /entrypoint.sh --server-id=$((20 + $(echo $HOSTNAME | grep -o '[^-]*$') + 1)) --report-host=${HOSTNAME}.mysql.mysql.svc.cluster.local --binlog-checksum=NONE --enforce-gtid-consistency=ON --gtid-mode=ON --default-authentication-plugin=mysql_native_password env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password - name: MYSQL_ADMIN_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: admin-password - name: MYSQL_ROOT_HOST value: "%" ports: - name: mysql containerPort: 3306 - name: mysqlx containerPort: 33060 - name: xcom containerPort: 33061 resources: limits: cpu: "500m" ephemeral-storage: "1Gi" memory: "1Gi" requests: cpu: "500m" ephemeral-storage: "1Gi" memory: "1Gi" volumeMounts: - name: mysql mountPath: /var/lib/mysql subPath: mysql readinessProbe: exec: command: - bash - "-c" - | mysql -h127.0.0.1 -uroot -p$MYSQL_ROOT_PASSWORD -e'SELECT 1' initialDelaySeconds: 5 periodSeconds: 2 timeoutSeconds: 1 livenessProbe: exec: command: - bash - "-c" - | mysqladmin -uroot -p$MYSQL_ROOT_PASSWORD ping initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 updateStrategy: rollingUpdate: partition: 0 type: RollingUpdate volumeClaimTemplates: - metadata: name: mysql labels: app: mysql spec: storageClassName: fast-storageclass volumeMode: Filesystem accessModes: - ReadWriteOnce resources: requests: storage: 25Gi
步驟四:驗證MySQL集群中的Pod部署情況
執(zhí)行以下命令,驗證StatefulSet是否已成功創(chuàng)建。
kubectl get statefulset -n mysql
預(yù)期輸出:
NAME READY AGE dbc1 3/3 7m21s
執(zhí)行以下命名,查看Pod詳細信息。
kubectl -n mysql get po -o wide
預(yù)期輸出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES dbc1-0 1/1 Running 0 2m28s 10.1.214.213 virtual-kubelet-cn-hangzhou-j <none> <none> dbc1-1 1/1 Running 0 106s 10.3.146.113 virtual-kubelet-cn-hangzhou-h <none> <none> dbc1-2 1/1 Running 0 64s 10.4.232.78 virtual-kubelet-cn-hangzhou-g <none> <none>
其中NODE列為Pod所在節(jié)點,節(jié)點名稱中包含可用區(qū)的信息。從節(jié)點名稱中可以看到Pod被打散到不同的可用區(qū)中。