Krz*_*tof 19 docker kubernetes persistent-volumes
我尝试设置kubernetes集群.我有持久Volomue,持久卷声明和存储类所有设置和运行,但是当我想从部署创建pod时,pod已创建但挂起处于Pending状态.在描述之后,我只获得了这个warnig"1个节点有卷节点亲和性冲突".有人能告诉我我的音量配置中缺少什么吗?
apiVersion: v1
kind: PersistentVolume
metadata:
creationTimestamp: null
labels:
io.kompose.service: mariadb-pv0
name: mariadb-pv0
spec:
volumeMode: Filesystem
storageClassName: local-storage
local:
path: "/home/gtcontainer/applications/data/db/mariadb"
accessModes:
- ReadWriteOnce
capacity:
storage: 2Gi
claimRef:
namespace: default
name: mariadb-claim0
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/cvl-gtv-42.corp.globaltelemetrics.eu
operator: In
values:
- master
status: {}
Run Code Online (Sandbox Code Playgroud)
jon*_*ckt 52
在我们的例子中,错误发生在使用 Pulumi 新配置的 AWS EKS 集群上(请参阅此处的完整源代码)。这个错误让我抓狂,因为我没有更改任何内容,只是PersistentVolumeClaim
按照 Buildpacks Tekton 文档中的描述创建了一个:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: buildpacks-source-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
Run Code Online (Sandbox Code Playgroud)
我没有更改默认 EKS 配置中的任何其他内容,也没有添加/更改任何PersistentVolume
或StorageClass
(事实上我什至不知道该怎么做)。由于默认 EKS 设置似乎依赖于 2 个节点,因此我收到错误:
0/2 nodes are available: 2 node(s) had volume node affinity conflict.
Run Code Online (Sandbox Code Playgroud)
读完Sonak Roy 的答案后,我第一次知道该怎么做 - 但不知道该怎么做。因此,对于这里感兴趣的人来说,这是我解决该错误的所有步骤:
failure-domain.beta.kubernetes.io
标签Statefull applications
如本文中的部分所述,在其他 AWS 可用区上配置了两个节点作为持久卷 (PV),该持久卷是通过应用PersistendVolumeClaim
上述内容创建的。
要检查这一点,您需要使用以下命令查看/描述您的节点kubectl get nodes
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: buildpacks-source-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
Run Code Online (Sandbox Code Playgroud)
Label
然后使用以下内容查看该部分kubectl describe node <node-name>
:
0/2 nodes are available: 2 node(s) had volume node affinity conflict.
Run Code Online (Sandbox Code Playgroud)
在我的例子中,节点ip-172-77-88-99.eu-central-1.compute.internal
定义failure-domain.beta.kubernetes.io/region
为 as eu-central-1
, az 定义为failure-domain.beta.kubernetes.io/zone
to eu-central-1b
。
另一个节点定义failure-domain.beta.kubernetes.io/zone
az eu-central-1a
:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-31-10-186.eu-central-1.compute.internal Ready <none> 2d16h v1.21.5-eks-bc4871b
ip-172-31-20-83.eu-central-1.compute.internal Ready <none> 2d16h v1.21.5-eks-bc4871b
Run Code Online (Sandbox Code Playgroud)
PersistentVolume
的topology.kubernetes.io
字段现在我们应该PersistentVolume
在手动应用PersistentVolumeClaim
. 使用kubectl get pv
:
$ kubectl describe node ip-172-77-88-99.eu-central-1.compute.internal
Name: ip-172-77-88-99.eu-central-1.compute.internal
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/instance-type=t2.medium
beta.kubernetes.io/os=linux
failure-domain.beta.kubernetes.io/region=eu-central-1
failure-domain.beta.kubernetes.io/zone=eu-central-1b
kubernetes.io/arch=amd64
kubernetes.io/hostname=ip-172-77-88-99.eu-central-1.compute.internal
kubernetes.io/os=linux
node.kubernetes.io/instance-type=t2.medium
topology.kubernetes.io/region=eu-central-1
topology.kubernetes.io/zone=eu-central-1b
Annotations: node.alpha.kubernetes.io/ttl: 0
...
Run Code Online (Sandbox Code Playgroud)
其次是kubectl describe pv <pv-name>
$ kubectl describe pv pvc-93650993-6154-4bd0-bd1c-6260e7df49d3
Name: pvc-93650993-6154-4bd0-bd1c-6260e7df49d3
Labels: topology.kubernetes.io/region=eu-central-1
topology.kubernetes.io/zone=eu-central-1c
Annotations: kubernetes.io/createdby: aws-ebs-dynamic-provisioner
...
Run Code Online (Sandbox Code Playgroud)
配置了az 中的PersistentVolume
标签,这使得我们的 Pod 抱怨找不到它们的卷 - 因为它们位于完全不同的 az 中!topology.kubernetes.io/zone
eu-central-1c
allowedTopologies
到StorageClass
正如Kubernetes 文档中所述,该问题的一种解决方案是将allowedTopologies
配置添加到StorageClass
. 如果您已经像我一样配置了 EKS 集群,则需要检索已经定义StorageClass
的
kubectl get storageclasses gp2 -o yaml
Run Code Online (Sandbox Code Playgroud)
将其保存到名为 的文件中storage-class.yml
,并添加allowedTopologies
与节点failure-domain.beta.kubernetes.io
标签匹配的部分,如下所示:
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/zone
values:
- eu-central-1a
- eu-central-1b
Run Code Online (Sandbox Code Playgroud)
配置allowedTopologies
定义 的failure-domain.beta.kubernetes.io/zone
必须PersistentVolume
为 ineu-central-1a
或eu-central-1b
- not eu-central-1c
!
完整的storage-class.yml
看起来像这样:
$ kubectl describe nodes ip-172-31-10-186.eu-central-1.compute.internal
Name: ip-172-31-10-186.eu-central-1.compute.internal
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/instance-type=t2.medium
beta.kubernetes.io/os=linux
failure-domain.beta.kubernetes.io/region=eu-central-1
failure-domain.beta.kubernetes.io/zone=eu-central-1a
kubernetes.io/arch=amd64
kubernetes.io/hostname=ip-172-31-10-186.eu-central-1.compute.internal
kubernetes.io/os=linux
node.kubernetes.io/instance-type=t2.medium
topology.kubernetes.io/region=eu-central-1
topology.kubernetes.io/zone=eu-central-1a
Annotations: node.alpha.kubernetes.io/ttl: 0
...
Run Code Online (Sandbox Code Playgroud)
将增强StorageClass
配置应用到您的 EKS 集群
kubectl apply -f storage-class.yml
Run Code Online (Sandbox Code Playgroud)
PersistentVolumeClaim
、添加storageClassName: gp2
并重新应用为了让事情恢复正常,我们需要删除第PersistentVolumeClaim
一个。
为了映射PersistentVolumeClaim
到我们之前的定义,StorageClass
我们需要添加storageClassName: gp2
到我们的 PersistendVolumeClaim 定义中pvc.yml
:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-93650993-6154-4bd0-bd1c-6260e7df49d3 1Gi RWO Delete Bound default/buildpacks-source-pvc gp2 21d
Run Code Online (Sandbox Code Playgroud)
最后重新应用PersistentVolumeClaim
with kubectl apply -f pvc.yml
。这应该可以解决该错误。
小智 29
当持久卷声称该Pod使用的持久性卷被调度在不同的区域而不是一个区域上时,将发生错误“卷节点亲缘性冲突”,因此实际的Pod无法调度,因为它无法从以下位置连接到该卷另一个区域。为此,您可以查看所有持久卷的详细信息。要进行检查,请首先获取您的PVC:
$ kubectl get pvc -n <namespace>
Run Code Online (Sandbox Code Playgroud)
然后获取持久卷的详细信息(而不是批量声明)
$ kubectl get pv
Run Code Online (Sandbox Code Playgroud)
找到与您的PVC相对应的PV并描述它们
$ kubectl describe pv <pv1> <pv2>
Run Code Online (Sandbox Code Playgroud)
您可以检查每个PV的Source.VolumeID,很可能它们将位于不同的可用区,因此您的Pod会显示相似性错误。要解决此问题,请为单个区域创建一个存储类,然后在您的PVC中使用该存储类。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: region1storageclass
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
encrypted: "true" # if encryption required
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: failure-domain.beta.kubernetes.io/zone
values:
- eu-west-2b # this is the availability zone, will depend on your cloud provider
# multi-az can be added, but that defeats the purpose in our scenario
Run Code Online (Sandbox Code Playgroud)
小智 9
在 AWS EKS 上,如果您在 Kubernetes 集群从 1.22 升级到 1.23 之前忘记安装 aws-ebs-csi-driver EKS 插件,也可能会遇到此问题。
您还可以在升级后安装该插件(尽管会出现一些服务中断)。
请务必查看 AWS 常见问题解答:https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi-migration-faq.html
经过一些令人头痛的调查后,需要检查以下几件事:
天蓝色:
如果不:
AKS 的存储类示例:
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: zone-redundant-storage
parameters:
skuname: StandardSSD_ZRS
provisioner: disk.csi.azure.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
Run Code Online (Sandbox Code Playgroud)
吉凯:
如果不:
GKE 的存储类示例:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: standard-regional-pd-storage
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-standard
replication-type: regional-pd
volumeBindingMode: WaitForFirstConsumer
Run Code Online (Sandbox Code Playgroud)
之后,PV 将在所选区域之间具有冗余,允许 Pod 从不同区域中的其他节点访问 PV。
在“1个节点(S)具有体积节点亲和力冲突”由调度产生错误,因为它无法安排您的吊舱一个节点,与符合persistenvolume.spec.nodeAffinity
您的PersistentVolume(PV)领域。
换句话说,您在 PV 中说必须将使用此 PV 的 pod 调度到标签为 的节点kubernetes.io/cvl-gtv-42.corp.globaltelemetrics.eu = master
,但由于某些原因,这是不可能的。
您的 pod 无法调度到这样的节点可能有多种原因:
开始寻找原因的地方是节点和 pod 的定义。
对我来说,升级到 k8s v1.25 后,GKE 上发生了这种情况。就我而言,上述方法均不起作用,因此我考虑克隆该卷,因为我不想丢失数据。
这篇文章引导我启用了Compute Engine 永久磁盘 CSI 驱动程序,该驱动程序一旦启用,就解决了我的问题。
有几件事会导致此错误:
节点标记不正确。当我的工作节点没有适当的标签时(我的主人有这样的标签),我在AWS上遇到了这个问题:
failure-domain.beta.kubernetes.io/region=us-east-2
failure-domain.beta.kubernetes.io/zone=us-east-2c
用标签修补节点后,“ 1个节点有卷节点亲缘性冲突”错误消失了,因此成功部署了带有吊舱的PV,PVC。这些标签的值是特定于云提供商的。基本上,云提供商(通过在多维数据集控制器,API服务器,kubelet中定义的–cloud-provider选项)来设置这些标签是工作。如果未设置适当的标签,请检查您的CloudProvider集成是否正确。我使用了kubeadm,因此设置起来很麻烦,但是例如使用kops等其他工具,它就可以立即运行。
根据您的PV定义和nodeAffinity字段的使用,您尝试使用本地卷(请在此处阅读本地卷描述链接,官方文档),然后确保像这样设置“ NodeAffinity字段”(在AWS上的案例):
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- my-node # it must be the name of your node(kubectl get nodes)
Run Code Online (Sandbox Code Playgroud)这样,在创建资源并对其进行运行描述后,它会像这样显示:
Required Terms:
Term 0: kubernetes.io/hostname in [your node name]
Run Code Online (Sandbox Code Playgroud)
就我而言,根本原因是持久卷位于 us-west-2c 中,而新工作节点重新启动到 us-west-2a 和 us-west-2b 中。解决方案是要么拥有更多工作节点,以便它们位于更多区域,要么删除/扩大应用程序的节点关联性,以便更多工作节点有资格绑定到持久卷。
小智 5
索纳克·罗伊 (Sownak Roy) 的精彩回答。与应该使用它的节点相比,我在不同的区域中创建了相同的 PV。我应用的解决方案仅基于 Sonak 的回答,仅在我的情况下,指定没有“allowedTopologies”列表的存储类就足够了,如下所示:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: cloud-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
volumeBindingMode: WaitForFirstConsumer
Run Code Online (Sandbox Code Playgroud)
kubectl get nodes --show-labels
Run Code Online (Sandbox Code Playgroud)
其中一个 kubernetes 节点应向您显示持久卷的名称/标签,并且您的 pod 应安排在同一节点上。
PersistentVolumeClaim
与 的大小匹配PersistentVolume
。如果尺寸不匹配,请更正resources.requests.storage
或PersistentVolumeClaim
删除旧的PersistentVolume
并创建一个具有正确尺寸的新尺寸。验证步骤:
kubectl describe pv postgres-br-proxy-pv-0
Run Code Online (Sandbox Code Playgroud)
输出:
...
Node Affinity:
Required Terms:
Term 0: postgres-br-proxy in [postgres-br-proxy-pv-0]
...
Run Code Online (Sandbox Code Playgroud)
kubectl get nodes --show-labels
Run Code Online (Sandbox Code Playgroud)
输出:
NAME STATUS ROLES AGE VERSION LABELS
node3 Ready <none> 19d v1.17.6 postgres-br-proxy=postgres-br-proxy-pv-0
Run Code Online (Sandbox Code Playgroud)
如果您没有在pod 正在使用的节点上获取持久卷标签,则该 pod 将不会被调度。
这里描述的几乎相同的问题... https://github.com/kubernetes/kubernetes/issues/61620
“如果您使用本地卷,并且节点崩溃,则您的 pod 无法重新调度到其他节点。它必须调度到同一个节点。这是使用本地存储的一个警告,您的 Pod 会永远绑定到一个特定的节点节点。”
归档时间: |
|
查看次数: |
12416 次 |
最近记录: |