k8s部署mysql数据持久化时,pv非空问题

我们在日常开发中经常会用到MySQL数据库,最简单的办法是通过k8s去部署,依赖k8s集群保持高可用,依赖pv/pvc持久化数据。

在一切配好后,启动MySQL的过程中,可能会出错:
[ERROR] --initialize specified but the data directory has files in it. Aborting.

原因是MySQL的初始化需要一个非空的文件夹,但是创建PV的时候默认会有lost+found文件夹,所以导致初始化失败。解决的办法有:

  • 通过挂载subPath子路径

  • 添加args: ["--ignore-db-dir=lost+found"]

  • 这里附上一个我在本地测试的demo供参考,由于自己电脑搭nfs有问题,所以PV选择的是本地。

    一、创建pv/pvc
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-hostpath
    spec:
      storageClassName: manual
      capacity:
        storage: 1Gi
      accessModes:
        - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      hostPath:
        path: /Users/guoxingyu/Documents/data
    
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-hostpath
      labels:
        app: mysql
    spec:
      storageClassName: manual
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    

    二、创建StatefulSet

    核心就是通过subPath错开原路径中的文件夹

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mysql
    spec:
      selector:
        matchLabels:
          app: mysql
      replicas: 1
      serviceName: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          containers:
          - name: mysql
            image: mysql:latest
            - name: MYSQL_ROOT_PASSWORD    # 这里设置root的密码
              value: root
            resources:
              requests:
                cpu: "50m"
                memory: 1Gi
              limits:
                cpu: "1"
                memory: 2Gi
            volumeMounts:
            - name: mysql-store
              mountPath: /var/lib/mysql  # MySQL容器的数据默认都是存在这个目录
              subPath: mysqldata  # 这里通过subPath挂载到子目录,就可以避免出错
          volumes:
          - name: mysql-store
            persistentVolumeClaim:
              claimName: pvc-hostpath
    

    三、创建Service

    apiVersion: v1
    kind: Service
    metadata:
      name: mysql-service
    spec:
      type: NodePort
      ports:
      - port: 3306
        targetPort: 3306