Kubernetes Pod警告:1个节点有卷节点亲缘关系冲突

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

0.如果您在其他答案中没有找到解决方案...

在我们的例子中,错误发生在使用 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 配置中的任何其他内容,也没有添加/更改任何PersistentVolumeStorageClass(事实上我什至不知道该怎么做)。由于默认 EKS 设置似乎依赖于 2 个节点,因此我收到错误:

0/2 nodes are available: 2 node(s) had volume node affinity conflict.
Run Code Online (Sandbox Code Playgroud)

读完Sonak Roy 的答案后,我第一次知道该怎么做 - 但不知道该怎么做。因此,对于这里感兴趣的人来说,这是我解决该错误的所有步骤

1.检查EKS节点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/zoneto eu-central-1b

另一个节点定义failure-domain.beta.kubernetes.io/zoneaz 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)

2. 检查PersistentVolumetopology.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/zoneeu-central-1c

3. 添加allowedTopologiesStorageClass

正如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-1aeu-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)

4. 删除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)

最后重新应用PersistentVolumeClaimwith 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)

  • 我通过以下方法解决了这个问题: - 删除 PVC 和 PV - 在存储类中设置“volumeBindingMode: WaitForFirstConsumer”而不是 Immediate - 重新部署 pod (6认同)

小智 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


Nik*_*Nik 8

经过一些令人头痛的调查后,需要检查以下几件事:

天蓝色:

  • 您的集群是否选择了多个区域?(1、2、3 区)
  • 您的默认存储类别是否具有正确的存储提供程序?(ZRS 区域-冗余-存储)

如果不:

  • 更改存储类别以使用正确的提供程序
  • 创建PV数据备份
  • 停止使用 PVC 的部署(将副本设置为 0)
  • 删除PVC并确认关联的PV已删除。
  • 重新应用 PVC 配置 yaml(不引用旧的存储类名称)
  • 启动使用 PVC 的部署(将副本设置为 1)
  • 手动导入备份数据

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)

吉凯:

  • 您的集群是否选择了多个区域?(A区、B区、C区)
  • 您的默认存储类别是否有复制类型参数?(复制类型:区域-pd)

如果不:

  • 更改存储类别以使用正确的参数
  • 创建PV数据备份
  • 停止使用 PVC 的部署(将副本设置为 0)
  • 删除PVC并确认关联的PV已删除。
  • 重新应用 PVC 配置 yaml(不引用旧的存储类名称)
  • 启动使用 PVC 的部署(将副本设置为 1)
  • 手动导入备份数据

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。


wei*_*eld 7

“1个节点(S)具有体积节点亲和力冲突”由调度产生错误,因为它无法安排您的吊舱一个节点,与符合persistenvolume.spec.nodeAffinity您的PersistentVolume(PV)领域。

换句话说,您在 PV 中说必须将使用此 PV 的 pod 调度到标签为 的节点kubernetes.io/cvl-gtv-42.corp.globaltelemetrics.eu = master,但由于某些原因,这是不可能的。

您的 pod 无法调度到这样的节点可能有多种原因:

  • pod 有节点亲和性、pod 亲和性等与目标节点冲突
  • 目标节点被污染
  • 目标节点已达到其“每个节点的最大 Pods”限制
  • 不存在具有给定标签的节点

开始寻找原因的地方是节点和 pod 的定义。


Pas*_*Kit 7

对我来说,升级到 k8s v1.25 后,GKE 上发生了这种情况。就我而言,上述方法均不起作用,因此我考虑克隆该卷,因为我不想丢失数据。

这篇文章引导我启用了Compute Engine 永久磁盘 CSI 驱动程序,该驱动程序一旦启用,就解决了我的问题。

  • 有同样的问题。运行“gcloud 容器集群更新 CLUSTER-NAME --update-addons=GcePersistentDiskCsiDriver=ENABLED”后,问题得到解决并且 Pod 正确启动 (2认同)
  • 我的天啊。那现在真的救了我。我升级了集群,但使用 PVC 的 DB 和 Redis 服务器没有出现。事实上,解决方案就是启用驱动程序。我不知道为什么它没有记录在任何地方。 (2认同)

Ale*_*lex 5

有几件事会导致此错误:

  1. 节点标记不正确。当我的工作节点没有适当的标签时(我的主人有这样的标签),我在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等其他工具,它就可以立即运行。

  2. 根据您的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)
  1. 必须使用volumeBindingMode设置为WaitForFirstConsumer来创建StorageClass定义(名为local-storage,在此处未发布),以使本地存储正常工作。请参考此处的示例存储类本地描述,官方文档以了解其背后的原因。


blu*_*t_2 5

就我而言,根本原因是持久卷位于 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)

  • 这在过去对我有用。一个月后我再次启动了集群,但遇到了同样的问题。Storageclass 已应用。:( (2认同)

Vis*_*ant 5

  1. 确保 kubernetes 节点具有所需的标签。您可以使用以下方法验证节点标签:
kubectl get nodes --show-labels
Run Code Online (Sandbox Code Playgroud)

其中一个 kubernetes 节点应向您显示持久卷的名称/标签,并且您的 pod 应安排在同一节点上

  1. 确保请求的大小PersistentVolumeClaim与 的大小匹配PersistentVolume。如果尺寸不匹配,请更正resources.requests.storagePersistentVolumeClaim删除PersistentVolume并创建一个具有正确尺寸的新尺寸。

验证步骤:

  1. 描述您的持久卷:
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)
  1. 显示节点标签:
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 将不会被调度。


jit*_*dra 2

这里描述的几乎相同的问题... https://github.com/kubernetes/kubernetes/issues/61620

“如果您使用本地卷,并且节点崩溃,则您的 pod 无法重新调度到其他节点。它必须调度到同一个节点。这是使用本地存储的一个警告,您的 Pod 会永远绑定到一个特定的节点节点。”