带副本的 Statefulset:1 个 pod 具有未绑定的即时 PersistentVolumeClaims
Statefulset with replicas : 1 pod has unbound immediate PersistentVolumeClaims
我正在尝试在我的单节点集群(Docker 桌面 Windows)中设置一个弹性集群。
为此,我创建了如下的 PV (working)
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、..)
当使用 StatefulSet
和 volumeClaimTemplates
时,它会为每个副本创建一个 PersistentVolumeClaim
。因此,如果您使用 replicas: 2
,将创建两个不同的 PersistentVolumeClaims,es-data-esnode-0
和 es-data-esnode-1
。
每个 PersistentVolumeClaim
将绑定到一个唯一的 PersistentVolume
,因此在两个 PVC 的情况下,您将需要两个不同的 PersistentVolumes
。但这在桌面设置中使用 volumeClaimTemplate
和 hostPath
卷并不容易。
在这种情况下,您需要 replicas: 2
的原因是什么?它通常用于提供更好的可用性,例如使用多个节点。但是对于桌面环境中的本地设置,通常单个节点上的单个副本应该没问题?我认为最简单的解决方案是使用 replicas: 1
.
让我在评论和 Jonas's 回答中已经说过的内容中添加一些细节。
从评论中推断,您尚未定义名为 elasticdata
的 StorageClass
。如果它不存在,则不能在 PV
和 PVC
.
中引用它
快速浏览一下 hostPath
如何用于定义 PersistentVolume
以及如何在 PersistentVolumeClaim
中引用它。 Here you can see that in the example storageClassName: manual
is used. Kubernetes docs doesn't say it explicitely but if you take a look at Openshift docs,上面写的很清楚:
A Pod that uses a hostPath volume must be referenced by manual
(static) provisioning.
这不仅仅是一些用于将 PVC
请求绑定到此特定 PV
的值。所以如果 elasticdata
StorageClass
没有被定义,你不应该在这里使用它。
第二件事。作为 Jonas already stated in his comment, there is one-to-one binding between PVC
and PV
so no matter that your PV
still has enough capacity, it has been already claimed by a different PVC
and is not available any more. As you can read in the official docs:
A PVC to PV binding is a one-to-one mapping, using a ClaimRef which is
a bi-directional binding between the PersistentVolume and the
PersistentVolumeClaim.
Claims will remain unbound indefinitely if a matching volume does not
exist. Claims will be bound as matching volumes become available. For
example, a cluster provisioned with many 50Gi PVs would not match a
PVC requesting 100Gi. The PVC can be bound when a 100Gi PV is added to
the cluster.
反之亦然。如果只有一个 100Gi PV,它将无法满足两个 PVC
请求每个 50Gi 的请求。请注意,在您发布的 kubectl get pv,pvc
的结果中,PV
和 PVC
都具有 20Gi
的容量,尽管您请求从 [=13= 创建的每个 PVC
] 仅模板 3Gi
.
您在这里不使用任何动态存储供应器,因此您需要根据用例手动提供尽可能多的PersistentVolumes
。
顺便说一句,与其使用 hostPath
,我更愿意推荐你使用 local
volume with properly defined StorageClass
。它比 HostPath
有一些优势。此外,可以单独 运行 外部静态供应器,以改进对本地卷生命周期的管理
我正在尝试在我的单节点集群(Docker 桌面 Windows)中设置一个弹性集群。 为此,我创建了如下的 PV (working)
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、..)
当使用 StatefulSet
和 volumeClaimTemplates
时,它会为每个副本创建一个 PersistentVolumeClaim
。因此,如果您使用 replicas: 2
,将创建两个不同的 PersistentVolumeClaims,es-data-esnode-0
和 es-data-esnode-1
。
每个 PersistentVolumeClaim
将绑定到一个唯一的 PersistentVolume
,因此在两个 PVC 的情况下,您将需要两个不同的 PersistentVolumes
。但这在桌面设置中使用 volumeClaimTemplate
和 hostPath
卷并不容易。
在这种情况下,您需要 replicas: 2
的原因是什么?它通常用于提供更好的可用性,例如使用多个节点。但是对于桌面环境中的本地设置,通常单个节点上的单个副本应该没问题?我认为最简单的解决方案是使用 replicas: 1
.
让我在评论和 Jonas's 回答中已经说过的内容中添加一些细节。
从评论中推断,您尚未定义名为 elasticdata
的 StorageClass
。如果它不存在,则不能在 PV
和 PVC
.
快速浏览一下 hostPath
如何用于定义 PersistentVolume
以及如何在 PersistentVolumeClaim
中引用它。 Here you can see that in the example storageClassName: manual
is used. Kubernetes docs doesn't say it explicitely but if you take a look at Openshift docs,上面写的很清楚:
A Pod that uses a hostPath volume must be referenced by manual (static) provisioning.
这不仅仅是一些用于将 PVC
请求绑定到此特定 PV
的值。所以如果 elasticdata
StorageClass
没有被定义,你不应该在这里使用它。
第二件事。作为 Jonas already stated in his comment, there is one-to-one binding between PVC
and PV
so no matter that your PV
still has enough capacity, it has been already claimed by a different PVC
and is not available any more. As you can read in the official docs:
A PVC to PV binding is a one-to-one mapping, using a ClaimRef which is a bi-directional binding between the PersistentVolume and the PersistentVolumeClaim.
Claims will remain unbound indefinitely if a matching volume does not exist. Claims will be bound as matching volumes become available. For example, a cluster provisioned with many 50Gi PVs would not match a PVC requesting 100Gi. The PVC can be bound when a 100Gi PV is added to the cluster.
反之亦然。如果只有一个 100Gi PV,它将无法满足两个 PVC
请求每个 50Gi 的请求。请注意,在您发布的 kubectl get pv,pvc
的结果中,PV
和 PVC
都具有 20Gi
的容量,尽管您请求从 [=13= 创建的每个 PVC
] 仅模板 3Gi
.
您在这里不使用任何动态存储供应器,因此您需要根据用例手动提供尽可能多的PersistentVolumes
。
顺便说一句,与其使用 hostPath
,我更愿意推荐你使用 local
volume with properly defined StorageClass
。它比 HostPath
有一些优势。此外,可以单独 运行 外部静态供应器,以改进对本地卷生命周期的管理