全部產品
Search
文件中心

Container Service for Kubernetes:在Container Service Serverless 版上部署有狀態的高可用MySQL叢集

更新時間:Jun 19, 2024

高可用是分布式應用的重要要求,在ACK Serverless叢集中,您可以通過K8s原生調度語義實現分布式應用的跨可用性區域打散,以達到高可用部署的要求。本文檔介紹如何在Container Service Serverless 版上部署有狀態的高可用MySQL叢集。

前提條件

  • 已建立ACK Serverless叢集(含多個虛擬節點)。具體操作,請參見建立叢集

  • 已開啟虛擬節點調度策略。具體操作,請參見開啟叢集虛擬節點調度策略

  • 已安裝csi-provisioner組件且版本 >= v1.22.9。

步驟一:從Github拉取用於建立K8s資源的YAML檔案

  1. 執行以下命令,複製程式碼程式庫。

    git clone https://github.com/AliyunContainerService/serverless-k8s-examples.git
  2. 執行以下命令,進入工作目錄,並查看目錄下YAML檔案清單。

    cd serverless-k8s-examples/stateful-mysql
    ls -al

    預期輸出:

    README.md		secret.yaml		stateful-mysql.yaml	 storageclass.yaml

    其中secret.yaml用於建立Secret,storageclass.yaml用於建立StorageClass,stateful-mysql.yaml用於建立MySQL StatefulSet。

步驟二:建立NameSpace、Secret、StorageClass

  1. 執行以下命令,建立命名空間mysql

    kubectl create namespace mysql

    預期輸出:

    namespace/mysql created
  2. 執行以下命令,建立MySQL Secret,用於儲存MySQL密碼。

    kubectl apply -n mysql -f secret.yaml

    預期輸出:

    secret/mysql-secret created

    以下為該Secret的YAML檔案。

    展開查看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 # 使用該配置,按優先順序自適應選擇雲端硬碟類型,最終建立的雲端硬碟類型受節點執行個體、所在可用性區域雲端硬碟支援情況等因素影響。
      fstype: ext4
      diskTags: "a:b,b:c"
      encrypted: "false"
      performanceLevel: PL1
      volumeExpandAutoSnapshot: "forced" # 該設定僅在建立的雲端硬碟類型為cloud_essd時生效。
      provisionedIops: "40000"
      burstingEnabled: "false"
    volumeBindingMode: WaitForFirstConsumer # 表示延遲雲端硬碟建立直到Pod建立,可實現雲端硬碟在Pod所在可用性區域建立。
    reclaimPolicy: Retain
    allowVolumeExpansion: true
  3. 執行以下命令,建立StorageClass。

    kubectl apply -f storageclass.yaml

    預期輸出:

    storageclass.storage.k8s.io/fast-storageclass created

    以下為該StorageClass的YAML檔案。

    展開查看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 # 使用該配置,按優先順序自適應選擇雲端硬碟類型,最終建立的雲端硬碟類型受節點執行個體、所在可用性區域雲端硬碟支援情況等因素影響。
      fstype: ext4
      diskTags: "a:b,b:c"
      encrypted: "false"
      performanceLevel: PL1
      volumeExpandAutoSnapshot: "forced" # 該設定僅在建立的雲端硬碟類型為cloud_essd時生效。
      provisionedIops: "40000"
      burstingEnabled: "false"
    volumeBindingMode: WaitForFirstConsumer # 表示延遲雲端硬碟建立直到Pod建立,可實現雲端硬碟在Pod所在可用性區域建立。
    reclaimPolicy: Retain
    allowVolumeExpansion: true

步驟三:配置Pod可用性區域打散,建立MySQL StatefulSet

  1. 執行以下命令,建立MySQL StatefulSet。本樣本將建立一個通過配置虛擬節點Pod可用性區域打散,在多個可用性區域上均勻分布的StatefulSet。關於如何配置虛擬節點Pod可用性區域打散,請參見實現虛擬節點Pod可用性區域打散以及親和調度

    kubectl apply -n mysql -f stateful-mysql.yaml

    預期輸出:

    statefulset.apps/dbc1 created

    以下為該StatefulSet的YAML檔案。

    展開查看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部署情況

  1. 執行以下命令,驗證StatefulSet是否已成功建立。

    kubectl get statefulset -n mysql

    預期輸出:

    NAME   READY   AGE
    dbc1   3/3     7m21s
  2. 執行以下命名,查看Pod詳細資料。

    kubectl -n mysql get po -o wide

    預期輸出:

    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所在節點,節點名稱中包含可用性區域的資訊。從節點名稱中可以看到Pod被打散到不同的可用性區域中。

相關文檔