如何解决带有副本的 Statefulset:1 个 pod 具有未绑定的即时 PersistentVolumeClaims
我正在尝试在我的单节点集群(Docker 桌面 Windows)中设置一个弹性集群。 为此,我创建了 PV 如下(工作)
apiVersion: v1
kind: PersistentVolume
metadata:
name: elastic-pv-data
labels:
type: local
spec:
storageClassName: elasticdata
accessModes:
- ReadWriteOnce
capacity:
storage: 20Gi
hostPath:
path: "/mnt/data/elastic"
然后是配置:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: esnode
spec:
selector:
matchLabels:
app: es-cluster # has to match .spec.template.metadata.labels
serviceName: elasticsearch
replicas: 2
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: es-cluster
spec:
securityContext:
fsGroup: 1000
initContainers:
- name: init-sysctl
image: busybox
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
command: ["sysctl","-w","vm.max_map_count=262144"]
containers:
- name: elasticsearch
resources:
requests:
memory: 1Gi
securityContext:
privileged: true
runAsUser: 1000
capabilities:
add:
- IPC_LOCK
- SYS_RESOURCE
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.7.1
env:
- name: ES_JAVA_OPTS
valueFrom:
configMapKeyRef:
name: es-config
key: ES_JAVA_OPTS
readinessProbe:
httpGet:
scheme: HTTP
path: /_cluster/health?local=true
port: 9200
initialDelaySeconds: 5
ports:
- containerPort: 9200
name: es-http
- containerPort: 9300
name: es-transport
volumeMounts:
- name: es-data
mountPath: /usr/share/elasticsearch/data
volumeClaimTemplates:
- metadata:
name: es-data
spec:
storageClassName: elasticdata
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
结果是只有一个“pod”将其 pvc 绑定到 pv,另一个得到错误循环“0/1 个节点可用:1 个 pod 具有未绑定的即时 PersistentVolumeClaims”。 这是 kubectl get pv,pvc 结果:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/elastic-pv-data 20Gi RWO Retain Bound default/es-data-esnode-0 elasticdata 14m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/es-data-esnode-0 Bound elastic-pv-data 20Gi RWO elasticdata 13m
如果我理解正确,我应该有一个带有以下标识符的第二个persistantolumeclaim:es-data-esnode-1 有什么我想念或不正确理解的吗? 感谢您的帮助
我在这里跳过不相关的部分(configmap,loadbalancer,..)
解决方法
将 // @ts-ignore
与 StatefulSet
一起使用时,它将为每个副本创建一个 volumeClaimTemplates
。因此,如果您使用 PersistentVolumeClaim
,将创建两个不同的 PersistentVolumeClaims,replicas: 2
和 es-data-esnode-0
。
每个 es-data-esnode-1
将绑定到唯一的 PersistentVolumeClaim
,因此在两个 PVC 的情况下,您将需要两个不同的 PersistentVolume
。但是在桌面设置中使用 PersistentVolumes
和 volumeClaimTemplate
卷并不容易做到这一点。
在这种情况下,您出于什么原因需要 hostPath
?它通常用于提供更好的可用性,例如使用多个节点。但是对于桌面环境中的本地设置,通常单个节点上的单个副本应该没问题?我认为对您来说最简单的解决方案是使用 replicas: 2
。
让我为评论和Jonas's 回答中已经说过的内容添加一些细节。
根据评论推断,您尚未定义名为 StorageClass
的 elasticdata
。如果它不存在,则不能在 PV
和 PVC
中引用它。
快速了解如何使用 hostPath
定义 PersistentVolume
以及如何在 PersistentVolumeClaim
中引用它。 Here 您可以看到在示例中使用了 storageClassName: manual
。 Kubernetes 文档没有明确说明,但如果您看一下 Openshift docs,它会非常清楚地说明:
使用hostPath卷的Pod必须手动引用 (静态)配置。
这不仅仅是用于将 PVC
请求绑定到此特定 PV
的某个值。因此,如果 elasticdata
StorageClass
尚未定义,则不应在此处使用它。
第二件事。正如 Jonas 在他的评论中已经说过的,PVC
和 PV
之间存在一对一的绑定,所以不管你的 PV
仍然有足够的容量,它已经已被其他 PVC
声明且不再可用。正如您在官方docs中所读到的那样:
PVC 到 PV 的绑定是一对一的映射,使用的 ClaimRef 是 PersistentVolume 和 持久卷声明。
如果没有匹配的数量,索赔将无限期地保持未绑定状态 存在。当匹配数量可用时,索赔将受到约束。为了 例如,配置了许多 50Gi PV 的集群将不匹配 PVC 要求 100Gi。添加 100Gi PV 时可以绑定 PVC 集群。
反之亦然。如果只有一个 100Gi PV,它将无法满足来自两个 PVC
的请求,每个请求 50Gi。请注意,在您发布的 kubectl get pv,pvc
的结果中,PV
和 PVC
的容量均为 20Gi
,尽管您在从 {{1} 创建的每个 PVC
中请求} 仅模板PVC
。
您在此处不使用任何动态存储配置器,因此您需要根据用例的需要手动提供尽可能多的 3Gi
。
顺便说一下,我宁愿建议您使用 local
卷并正确定义 StorageClass
,而不是使用 PersistentVolumes
。与 hostPath
相比,它有一些优势。此外,可以单独运行外部静态配置器,以改进对本地卷生命周期的管理
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。