首页 > 解决方案 > k8s - ReplicaSet matchLabel 选择器的意义

问题描述

假设部署,replicaSet 和 pod 都是 1:1:1 映射。

deployment ==> replicaSet ==> Pod

当我们进行部署时,replicaSet 将pod-template-hash标签添加到 pod。因此,这看起来足以让副本集检查是否有足够的 pod 正在运行。那么replicaSetmatchLabels选择器有什么意义呢?为什么是强制性的?

解释以便更好地理解

例如:我部署了一个带有这些标签的应用程序。2 个 pod 正在运行

spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-app

现在将其中一个 pod 的 pod-template-hash 的标签值更改为其他值(更改为testing此处)。现在我们立即看到另一个 pod 启动了。所以replicaSet似乎并不关心selector.matchLabels

NAME                            READY   STATUS    RESTARTS   AGE   LABELS
pod/nginx-app-b8b875889-cpnnr   1/1     Running   0          53s   app=nginx-app,pod-template-hash=testing
pod/nginx-app-b8b875889-jlk6m   1/1     Running   0          53s   app=nginx-app,pod-template-hash=b8b875889
pod/nginx-app-b8b875889-xblqr   1/1     Running   0          11s   app=nginx-app,pod-template-hash=b8b875889

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE    LABELS
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   151d   component=apiserver,provider=kubernetes

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE   LABELS
deployment.apps/nginx-app   2/2     2            2           53s   app=nginx-app

NAME                                  DESIRED   CURRENT   READY   AGE   LABELS
replicaset.apps/nginx-app-b8b875889   2         2         2       53s   app=nginx-app,pod-template-hash=b8b875889

标签: kubernetes

解决方案


让我总结一下。整个讨论是关于:为什么部署迫使我设置 matchLabels 选择器,即使没有它也可以轻松生存,因为它添加了 pod-template-hash 并且只使用它就可以了。

在阅读了所有评论和所有讨论后,我决定查看 kubernetes 文档。

我将允许自己引用关于副本集的 k8s 文档:副本集的工作原理

ReplicaSet 的工作原理:

[...]

ReplicaSet 通过 Pod 的 metadata.ownerReferences 字段链接到其 Pod ,该字段指定当前对象所拥有的资源。ReplicaSet 获取的所有 Pod 在其 ownerReferences 字段中都有其拥有的 ReplicaSet 的标识信息。正是通过这个链接,ReplicaSet 才知道它正在维护的 Pod 的状态并做出相应的计划。

那么这是否意味着它根本不使用标签?嗯,不完全是。让我们继续阅读:

ReplicaSet 使用其选择器标识要获取的新 Pod。如果 Pod 没有 OwnerReference 或者 OwnerReference 不是 Controller 并且匹配到 ReplicaSet 的 selector,会立即被该 ReplicaSet 获取

哦,所以看起来它只是使用选择器作为第一种方法的替代方法。

让我们继续阅读。这是Pod Selector部分的引述:

吊舱选择器

.spec.selector 字段是一个标签选择器。如前所述,这些是用于识别 要获取的潜在 Pod 的标签

看起来这些标签并没有用作跟踪 ReplicaSet 拥有的 pod 的主要方法,它们用于“识别潜在的 Pod 获取”。但是这是什么意思?

为什么 ReplicaSet 会获取它不拥有的 pod?文档中有一个部分试图回答这个问题:非模板 Pod 获取

非模板 Pod 收购

虽然您可以毫无问题地创建裸 Pod,但强烈建议确保裸 Pod 没有与您的 ReplicaSet 之一的选择器匹配的标签。这是因为 ReplicaSet 并不局限于拥有其模板指定的 Pod——它可以按照前面章节中指定的方式获取其他 Pod。

[...]

由于这些 Pod 没有 Controller(或任何对象)作为其所有者引用并且与 [...] ReplicaSet 的选择器匹配,因此它们将立即被它获取。

很好,但这仍然不能回答问题:为什么我需要提供选择器?它不能只使用那个哈希吗?

回到过去,当 k8s 出现错误时: https ://github.com/kubernetes/kubernetes/issues/23170 所以有人建议需要验证:https ://github.com/kubernetes/kubernetes/issues/23218 于是验证出现了: https ://github.com/kubernetes/kubernetes/pull/23530

它一直伴随着我们直到今天,即使今天我们可能没有它也可以生活。

虽然我认为它在那里更好,因为它最大限度地减少了在不同 RS 的 pod-template-hash 冲突的情况下重叠标签的机会。


推荐阅读