K8S + HELM. 创建一个持久化卷用于MySQL数据库

98次阅读
没有评论

问题描述

正在使用K8S和Helm 3,并且正在使用MYSQL 5.7数据库。他想知道如何创建一个MYSQL pod,使得数据库在第一次创建后可以持久存在,即使pod关闭再重新启动,数据也不会丢失。用户已经使用了PersistentVolume和PersistentVolumeClaim。
以下是用户提供的YAML文件:
Mysql pod:

apiVersion: v1
kind: Pod
metadata:
  name: myproject-db
  namespace: {{ .Release.Namespace }}
  labels:
    name: myproject-db
    app: myproject-db
spec:
  hostname: myproject-db
  subdomain: {{ include "k8s.db.subdomain" . }}
  containers:
    - name: myproject-db
      image: mysql:5.7
      imagePullPolicy: IfNotPresent
      env:
        MYSQL_DATABASE: test
        MYSQL_ROOT_PASSWORD: 12345
      ports:
        - name: mysql
          protocol: TCP
          containerPort: 3306
      resources:
        requests:
          cpu: 200m
          memory: 500Mi
        limits:
          cpu: 500m
          memory: 600Mi
      volumeMounts:
        - name: mysql-persistence-storage
          mountPath: /var/lib/mysql
  volumes:
    - name: mysql-persistence-storage
      persistentVolumeClaim:
        claimName: mysql-pvc

Persistent Volume:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  labels:
    type: local
    name: mysql-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/data/mysql"

Persistent Volume Claim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  volumeMode: Filesystem
  volumeName: mysql-pv

此外,用户还创建了一个存储类,尽管没有使用,但是提供如下:
Storage Class:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mysql-storage
provisioner: docker.io/hostpath
volumeBindingMode: WaitForFirstConsumer

在运行Helm install myproject myproject/之后,数据库被创建并可以使用。但是,如果用户添加记录并停止并删除数据库pod,希望记录保留,而不会丢失数据库数据。然而,用户发现当MYSQL pod重新启动时,数据库数据丢失了。
用户想知道如何使用helm install ...helm upgrade(重要的是由helm命令创建的pod),只有在第一次创建数据库时才会创建数据库,而在以后的次数中,数据库数据不会丢失。
谢谢。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据你提供的YAML文件,你正在使用host文件系统作为持久化卷。假设你有多个工作节点,并且pod在不同的节点上重新启动,数据将会“丢失”(只存在于之前运行的节点上)。
为了解决这个问题,你可以强制pod在特定的节点上运行并重新启动。你会注意到数据仍然存在,因为它在之前的相同节点上重新启动。
以下是如何在K8S中指定pod运行在特定节点上的步骤:
1. 首先,你需要为节点添加一个标签。例如,你可以为节点添加一个名为mysql-node的标签:

kubectl label nodes <node-name> mysql-node=true
  1. 然后,在你的pod的YAML文件中添加一个nodeSelector字段,指定pod应该运行在具有mysql-node=true标签的节点上。例如:
apiVersion: v1
kind: Pod
metadata:
  name: myproject-db
  namespace: {{ .Release.Namespace }}
  labels:
    name: myproject-db
    app: myproject-db
spec:
  hostname: myproject-db
  subdomain: {{ include "k8s.db.subdomain" . }}
  nodeSelector:
    mysql-node: "true"
  containers:
    - name: myproject-db
      image: mysql:5.7
      imagePullPolicy: IfNotPresent
      env:
        MYSQL_DATABASE: test
        MYSQL_ROOT_PASSWORD: 12345
      ports:
        - name: mysql
          protocol: TCP
          containerPort: 3306
      resources:
        requests:
          cpu: 200m
          memory: 500Mi
        limits:
          cpu: 500m
          memory: 600Mi
      volumeMounts:
        - name: mysql-persistence-storage
          mountPath: /var/lib/mysql
  volumes:
    - name: mysql-persistence-storage
      persistentVolumeClaim:
        claimName: mysql-pvc

通过添加nodeSelector字段,你可以确保pod只会在具有mysql-node=true标签的节点上运行。这样,当pod重新启动时,它将在相同的节点上重新启动,数据将保持不变。
请注意,你需要根据你的实际环境和节点名称进行相应的更改。

方案2

使用持久化卷的类型可能会影响数据的持久性。你可以尝试使用其他类型的持久化卷,如网络存储卷(NFS)或云存储卷(如AWS EBS)。
另一种方法是尝试使用其他类型的持久化卷,如网络存储卷(NFS)或云存储卷(如AWS EBS)。这些类型的持久化卷可以提供更好的数据持久性,即使pod重新启动,数据也不会丢失。
你可以根据你的需求选择适合的持久化卷类型,并相应地更新你的YAML文件。
请注意,使用不同类型的持久化卷可能需要进行额外的配置和设置,具体取决于你选择的持久化卷类型和你的环境。
以上是两种解决方案,你可以根据你的需求选择适合你的解决方案。希望对你有所帮助!

正文完