kubernetes部署pod选择器的用途是什么?

Ger*_*ens 27 kubernetes

我不明白为什么kubernetes需要在只能包含一个pod模板的部署语句中使用pod选择器?随意教育我为什么kubernetes工程师在部署防御中引入选择器语句而不是从模板中自动选择pod?

---
apiVersion: v1
kind: Service
metadata:
  name: grpc-service

spec:
  type: LoadBalancer
  ports:
  - name: grpc
    port: 8080
    targetPort: 8080
    protocol: TCP
  selector:
    app: grpc-test

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: grpc-deployment

spec:
  replicas: 1
  revisionHistoryLimit: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0

  selector:
    matchLabels:
      app: grpc-test

  template:
    metadata:
      labels:
        app: grpc-test

    spec:
      containers:
      ...
Run Code Online (Sandbox Code Playgroud)

为什么不简单地定义这样的东西?

---
apiVersion: v1
kind: Service
metadata:
  name: grpc-service

spec:
  type: LoadBalancer
  ports:
  - name: grpc
    port: 8080
    targetPort: 8080
    protocol: TCP
  selector:
    app: grpc-test

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: grpc-deployment

spec:
  replicas: 1
  revisionHistoryLimit: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0

  template:
    metadata:
      labels:
        app: grpc-test

    spec:
      containers:
      ...
Run Code Online (Sandbox Code Playgroud)

Too*_*gts 22

啊! 有趣的是,我曾经尝试过围绕标签选择器的概念.所以,这里......

首先,这些标签到底用于什么?kubernetes中的标签是识别物体的核心手段.控制器根据标签而不是名称控制pod.在这种特定情况下,它们例如用于识别属于部署的副本集的pod.

实际上,您不必.spec.selector在使用v1beta1扩展时隐式定义.在那种情况下,默认来自.spec.template.labels.但是,如果不这样做,您可能会遇到kubectl apply一个或多个用于选择更改的标签的问题,因为kubeclt applykubectl.kubernetes.io/last-applied-configuration比较更改时会查看,并且注释在创建资源时只包含用户输入而没有违约的字段.您将收到错误,因为它无法计算差异:

spec.template.metadata.labels: Invalid value: {"app":"nginx"}: `selector` does not match template `labels`

正如您所看到的,这是一个相当大的缺点,因为它意味着您无法更改任何用作选择器标签的标签,否则它将完全破坏您的部署流程.它apps/v1beta2通过要求明确定义选择器来"固定" ,不允许在这些字段上进行突变.

所以在你的例子中,你实际上不必定义它们!创建将起作用,.spec.template.labels默认情况下将使用您的.但是,在不久的将来,当你必须使用时v1beta2,这个领域将是强制性的.我希望这样的答案可以回答你的问题而且我没有让它更加混乱;)

  • 我同意@misberner,我认为这并没有真正回答问题的核心。这就像问 DMV“为什么我需要填写十份不同的表格才能获得驾驶执照?” DMV 回答“如果您不填写表格 X,Y 部门将不会知道您......”。这样的答案从根本上来说更多的是对当前事态的“描述”,但问题实际上是“为什么不能组织事物以便像......这样的简单界面可以工作?”。 (10认同)
  • 通过谷歌来到这里,我没有发现这个答案非常令人满意。我完全可以看到将标签与服务、节点选择器等一起使用的动机。但是,Kubernetes 规定 pod 模板本身必须与选择器匹配,因此它只能比分配的标签更宽松。然而,这种自由是没有价值的,因为它还规定了命名空间中的部署选择器不能重叠。所以实际的问题是:为什么甚至可以自由指定选择器,而不强制使用自动生成的 pod 标签和选择器,例如 `owning-deployment=<deployment-uid>`? (4认同)
  • @user2896438,部署实际上并不直接管理其 Pod,这可能会让我的解释感到困惑。部署创建一个 ReplicaSet,其目的是维护所述部署的“副本”的“集合”。ReplicaSet 拥有的每个 pod 都将获得唯一的“metadata.ownerReferences”字段,其中包含该 ReplicaSet 的 ID。这里有趣的是,当存在实际与 RS 的选择器标签匹配但没有有效的ownerReferences 字段的 pod 时,RS 会假设该 pod 是其集合的一部分。所以理论上你可以使用它;) (2认同)

Chr*_*ski 6

\n

但是,如果您不这样做\xe2\x80\x99t,一旦用于选择更改的一个或多个标签被 kubectl apply 时,您可能会遇到问题,因为 kubectl apply 将查看 kubectl.kubernetes.io/last-applied-configuration比较更改时,该注释将仅包含用户创建资源时的输入,而不包含任何默认字段。

\n
\n\n

引用Toon的回答。

\n\n

我的解释是这在逻辑上根本没有必要。只是由于 Kubernetes 当前实现的限制,它有一些奇怪的“行为”,因为它用于“比较”两个部署/对象的功能没有考虑“默认值”。

\n