我尝试使用 Kubernetes 部署 MySQL,拥有三个访问相同存储(PVC)的副本。这是配置
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
labels:
type: local
spec:
persistentVolumeReclaimPolicy: Retain
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
type: NodePort
ports:
- protocol: TCP
port: 3307
targetPort: 3306
nodePort: 30091
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 2
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:latest
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: pwd
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
当您应用此配置文件时kubectl apply -f file_name.yaml
,您可以创建三个 pod,它们访问数据库的同一存储。当您检查 pod 的状态时kubectl get pods
,您可以看到只有一个 pod 开始运行,其他 pod 处于运行CrashLoop
状态。发生的情况是,当创建多个实例使用公共存储时,只有一个实例可以获得文件的锁ibdata1
。这就是为什么只有一个 pod 变得健康,而其他 pod 则处于 CrashLoop 状态。(您可以使用 来查看这一点kubectl logs pod-name
)。我想要的是,
- 我可以释放文件的锁
ibdata
并使用所有 Pod 的存储吗?(这通常不能,因为一致性问题) - 如果没有,我该如何创建提议的想法?(使用多个 Pod 实例访问单个存储/卷)?
- 您是否会提出其他想法来实现使用多个 Pod 实例访问单个存储?
欢迎您的回答和帮助。
允许多个 MySQL 实例读取相同数据的唯一方法是将除一个之外的所有实例设置为只读模式。
https://dev.mysql.com/doc/refman/8.0/en/innodb-read-only-instance.html
完整阅读该手册页以了解如何配置它及其工作原理。
但从你的问题中并不清楚你这样做的目标是什么。
如果你想允许多个MySQL实例对数据文件具有读写访问权限,则不能这样做。InnoDB 在进程内部分管理存储中的数据,部分管理RAM 缓冲区中的数据
mysqld
。例如,如果您有多个引擎,它们每个都有自己的缓冲池、日志缓冲区和其他内存缓冲区,并且这些将不会协调。因此,您的数据文件几乎肯定会很快损坏。如果您的目标不同,请描述它。也许还有另一种解决方案。
回复您的评论:
您不能运行多个 MySQL 实例并使用相同的数据目录。MySQL实例启动时,需要锁定InnoDB表空间文件。因此,您可以让一个实例在另一个实例关闭后启动。但是使用相同数据文件同时运行多个程序是行不通的(在读写模式下)。
运行数据库服务器等有状态服务一直是 Kubernetes 的一个弱点。我认识的大多数数据库管理员都建议您仅将 Kubernetes 用于无状态应用程序。如果这些应用程序需要数据库,则数据库应该持久运行,而不是在 Kubernetes 环境中运行。
我知道一些供应商尝试支持在 Kubernetes 中运行 MySQL Server,但这始终是一项艰巨的任务。在我看来,困难大于优势。
我的答案来自 stackoverflow 的副本: