问题描述
正在使用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
- 然后,在你的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文件。
请注意,使用不同类型的持久化卷可能需要进行额外的配置和设置,具体取决于你选择的持久化卷类型和你的环境。
以上是两种解决方案,你可以根据你的需求选择适合你的解决方案。希望对你有所帮助!