这是我的总体目标:
正在运行MongoDB
通过pod失败/更新等持久存储数据
我采用的方法:
K8S提供商:Digital Ocean
节点:3
创建PVC
创建无头服务
创建一个StatefulSet
这是配置的简明版本:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: some-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: do-block-storage
---
apiVersion: v1
kind: Service
metadata:
name: some-headless-service
labels:
app: my-app
spec:
ports:
- port: 27017
name: my-app-database
clusterIP: None
selector:
app: my-app
tier: database
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-app-database
labels:
app: my-app
tier: database
spec:
serviceName: some-headless-service
replicas: 1
selector:
matchLabels:
app: my-app
tier: database
template:
metadata:
labels:
app: my-app
tier: database
spec:
containers:
- name: my-app-database
image: mongo:latest
volumeMounts:
- name: some-volume
mountPath: /data
ports:
- containerPort: 27017
name: my-app-database
volumes:
- name: some-volume
persistentVolumeClaim:
claimName: some-pvc
这按预期工作。我可以将副本降低到0:
kubectl scale —replicas=0 statefulset/my-app-database
将其备份:
kubectl scale —replicas=1 statefulset/my-app-database
数据将持续存在。
但是有一次,当我在通过上下缩放有状态集来搞乱时,遇到了这个错误:
Volume is already exclusively attached to one node and can't be attached to another
作为k8的新手,我删除了PVC,并“重新创建”了相同的PVC:
kubectl delete pvc some-pvc
kubectl apply -f persistent-volume-claims/
由于statefulset
默认情况下设置为persistentVolumeReclaimPolicy
,因此Delete
用新的PV旋转备份并删除了旧的PV。
我将新的PV persistentVolumeReclaimPolicy
设置为Retain
,以确保不会自动删除数据。。我意识到:我不确定如何回收该PV。早些时候,为了解决“卷附件”错误,我删除了PVC,该PVC只会使用已有的设置创建另一个新的PV,现在我将数据保留在Released
PV中。
我的主要问题是:
这听起来是否很适合我的目标?
我应该考虑将claimRef
添加到动态创建的PV中,然后使用该ClaimRef重新创建新的PVC,如此处所述:Can a PVC be bound to a specific PV?
我应该尝试获取新鲜的statefulset
PVC来实际使用旧的PV吗?
尝试将旧的PV重新连接到正确的节点是否有意义,我该怎么做?
答案 0 :(得分:0)
如果您想使用StatefulSet
具有可扩展性,则您的存储也应支持此功能,有两种方法可以解决此问题:
如果do-block-storage
存储类支持ReadWriteMany
,则将所有Pod的数据放在单个卷中。
每个吊舱使用不同的音量,将volumeClaimTemplate
添加到您的StatefulSet.spec
,
那么k8s会自动创建类似some-pvc-{statefulset_name}-{idx}
的PVC:
spec:
volumeClaimTemplates:
- metadata:
name: some-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: do-block-storage
更新:
StatefulSet
副本必须与mongodb replication一起部署,然后StatefulSet
中的每个吊舱将具有相同的数据存储。
因此,当容器运行mongod
命令时,必须添加选项--replSet={name}
。当所有Pod就绪时,执行命令rs.initiate()
告诉mongodb如何处理数据复制。放大或缩小StatefulSet
时,执行命令rs.add()
或rs.remove()
告诉mongodb成员已更改。