kuberneteskubernetes-helm

Why k8s resource doesn't increase apiVersion?


I have a CustomResourceDefinition:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  labels:
    app.kubernetes.io/name: applicationsets.argoproj.io
    app.kubernetes.io/part-of: argocd
  name: applicationsets.argoproj.io
....

In this CRD I have goTemplateOptions attribute defined.

It's here: https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

But when I download the crd from helm repo: https://artifacthub.io/packages/helm/argo/argo-cd/5.31.0?modal=template&template=crds/crd-applicationset.yaml

I can see that both apiVersion equal, but API themselves are different: no goTemplateOptions attribute defined in Helm.

Why do we have apiVersion equal with API different?

I presumed that version must have been different, through semantic versioning


Solution

  • Kubernetes doesn't use semantic versioning for its API objects. Within the core object set, it's fairly common for fields to be added between releases without changing the apiVersion:.

    There's some discussion of this in the documentation about API groups and versioning:

    Versioning is done at the API level rather than at the resource or field level....

    In general, new API resources and new resource fields can be added often and frequently. Elimination of resources or fields requires following the API deprecation policy.

    There is also a discussion of API versioning. The most important thing here is that the compatibility rules for "alpha", "beta", and GA API versions are different: v1alpha2 is allowed to make arbitrary changes (including removing objects and fields) from v1alpha1, "beta" versions may have breaking changes but need to clearly document them, and GA versions only have additive changes.

    In the context of a Helm chart, for core Kubernetes API objects, you can at least use .Capabilities to check if the cluster is new enough to have some field

    {{ if or (gt .Capabilities.KubeVersion 1) (ge .Capabilities.KubeVersion 32) }}
    ...
    {{ end }}
    

    For an extension type, this is harder to check, and you probably need a control in your chart to specify whether to use the newly-added field. Many charts simply pass through more complex options from Helm values, and another possibility is to document in a comment in the chart's values.yaml that there's a version dependency and omit the field if it's not specified, leaving it up to the system administrator to not supply the value when it won't work.