首页 > 解决方案 > helm 或 K8S 是否使用 spec.selector.matchLabels 覆盖 spec.template.metadata.labels?

问题描述

我有一个使用 helm v3 应用的图表,当我在本地渲染它时,它看起来像这样;

apiVersion: apps/v1
kind: Deployment
metadata:
  name: RELEASE-NAME-generic
  labels:
    app: generic
    chart: generic-1.1.2
    release: RELEASE-NAME
    heritage: Helm
    app.kubernetes.io/name: generic
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/version:
spec:
  replicas: 1
  selector:
    matchLabels:
      app: generic
      release: RELEASE-NAME
  template:
    metadata:
      labels:
        app.kubernetes.io/name: generic
        app.kubernetes.io/instance: RELEASE-NAME
    spec:
      imagePullSecrets:
      - name: ""
      containers:
        - name: generic
          image: ":"
          imagePullPolicy: IfNotPresent
          ports:
          resources:
            {}

注意这里的spec.selector.matchLabelsandspec.template.metadata.labels不匹配。这可能是一个问题,但这只是为了测试。

当我将它应用到集群(GKE,最新版本)并在那里检查 yaml 时,它看起来像这样(大致);

apiVersion: apps/v1
kind: Deployment
metadata:
  name: RELEASE-NAME-generic
  labels:
    app: generic
    chart: generic-1.1.2
    release: RELEASE-NAME
    heritage: Helm
    app.kubernetes.io/name: generic
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/version:
spec:
  replicas: 1
  selector:
    matchLabels:
      app: generic
      release: RELEASE-NAME
  template:
    metadata:
      labels:
        app: generic
        release: RELEASE-NAME
    spec:
      imagePullSecrets:
      - name: ""
      containers:
        - name: generic
          image: ":"
          imagePullPolicy: IfNotPresent
          ports:
          resources:
            {}

已被 中的spec.template.metadata.labels标签覆盖spec.selector.matchLabels

现在,从工作部署的角度来看,这是有道理的,但是我在任何地方都找不到这种行为,无论是在 K8S 还是在 Helm 中,我想知道这是否真的应该发生,或者我是否在这里发疯...

标签: kuberneteskubernetes-helm

解决方案


添加这些标签是为了查找由 Helm 管理的资源。您可以在下面找到文档中的一些信息:

Helm 的 github 站点可能有助于理解标签和选择器的工作原理:

在 Deployments/StatefulSets/DaemonSets >=v1/beta2 中定义的 spec.selector.matchLabels 不得包含 helm.sh/chart 标签或任何包含图表版本的标签,因为选择器是不可变的。图表标签字符串包含版本,因此如果指定了,那么每当 Chart.yaml 版本发生变化时,Helm 尝试更改这个不可变字段都会导致升级失败。

在helm 的网站上找到的其他信息:

在以下条件下,元数据项应该是标签:

Kubernetes 使用它来识别此资源。为了查询系统,向操作员公开它很有用。例如,我们建议使用 helm.sh/chart: NAME-VERSION 作为标签,以便操作员可以方便地找到要使用的特定图表的所有实例。

如果一项元数据不用于查询,则应将其设置为注释。


推荐阅读