Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CRD chart regression and fix CRDs for upgrades #1131

Merged
merged 5 commits into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/rancher-monitoring/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ url: https://github.com/prometheus-community/helm-charts.git
subdirectory: charts/kube-prometheus-stack
commit: 3ca6ba66032a1efce0500f9ad6f83351ad0604b8
packageVersion: 00
releaseCandidateVersion: 08
releaseCandidateVersion: 09
additionalCharts:
- workingDir: charts-crd
crdOptions:
Expand Down
22 changes: 22 additions & 0 deletions packages/rancher-monitoring/templates/crd-template/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,24 @@
# rancher-monitoring-crd
A Rancher chart that installs the CRDs used by rancher-monitoring.

## How does this chart work?

This chart marshalls all of the CRD files placed in the `crd-manifest` directory into a ConfigMap that is installed onto a cluster alongside relevant RBAC (ServiceAccount, ClusterRoleBinding, ClusterRole, and PodSecurityPolicy).

Once the relevant dependent resourcees are installed / upgraded / rolled back, this chart executes a post-install / post-upgrade / post-rollback Job that:
- Patches any existing versions of the CRDs contained within the `crd-manifest` on the cluster to set `spec.preserveUnknownFields=false`; this step is required since, based on [Kubernetes docs](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#field-pruning) and a [known workaround](https://github.com/kubernetes-sigs/controller-tools/issues/476#issuecomment-691519936), such CRDs cannot be upgraded normally from `apiextensions.k8s.io/v1beta1` to `apiextensions.k8s.io/v1`.
- Runs a `kubectl apply` on the CRDs that are contained within the crd-manifest ConfigMap to upgrade CRDs in the cluster

On an uninstall, this chart executes a separate post-delete Job that:
- Patches any existing versions of the CRDs contained within `crd-manifest` on the cluster to set `metadata.finalizers=[]`
- Runs a `kubectl delete` on the CRDs that are contained within the crd-manifest ConfigMap to clean up the CRDs from the cluster

Note: If the relevant CRDs already existed in the cluster at the time of install, this chart will absorb ownership of the lifecycle of those CRDs; therefore, on a `helm uninstall`, those CRDs will also be removed from the cluster alongside this chart.

## Why can't we just place the CRDs in the templates/ directory of the main chart?

In Helm today, you cannot declare a CRD and declare a resource of that CRD's kind in templates/ without encountering a failure on render.

## [Helm 3] Why can't we just place the CRDs in the crds/ directory of the main chart?

The Helm 3 `crds/` directory only supports the installation of CRDs, but does not support the upgrade and removal of CRDs, unlike what this chart facilitiates.
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@ spec:
runAsNonRoot: true
runAsUser: 1000
initContainers:
- name: delete-crds
- name: set-preserve-unknown-fields-false
image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: IfNotPresent
command:
- /bin/kubectl
- delete
- --ignore-not-found=true
- -f
- /etc/config/crd-manifest.yaml
volumeMounts:
- name: crd-manifest
readOnly: true
mountPath: /etc/config
- /bin/sh
- -c
- >
{{- range $path, $_ := (.Files.Glob "crd-manifest/**.yaml") }}
{{- $crd := get (get ($.Files.Get $path | fromYaml) "metadata") "name" }}
Comment on lines +30 to +31
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helm code that basically says "look at each file in crd-manifest that ends with .yaml and parse it as a YAML doc. Then pull out metadata.name's value and put it in the variable $crd."

e.g. anywhere that says {{ $crd }} below would look like prometheus.monitoring.coreos.com.

if [[ -n "$(kubectl get crd {{ $crd }} -o jsonpath='{.spec.preserveUnknownFields}')" ]]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a best effort operation (hence the || true) that should be done only if the CRD exists and has .spec.preserveUnknownFields set to some value.

If the CRD does not exist or if .spec.preserveUnknownFields is unset, this bash script will skip since the kubectl get command will return nothing to the stdout, but it will still print the error in finding the resource since the kubectl get command prints to stderr.

kubectl patch crd {{ $crd }} -p '{"spec": {"preserveUnknownFields": false, "versions": [{"name": "v1", "served": false, "storage": true}]}}' --type="merge" || true;
fi;
{{- end }}
containers:
- name: create-crds
image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: IfNotPresent
command:
- /bin/kubectl
- apply
- -f
- /etc/config/crd-manifest.yaml
- /bin/sh
- -c
- >
kubectl apply -f /etc/config/crd-manifest.yaml
volumeMounts:
- name: crd-manifest
readOnly: true
Expand Down Expand Up @@ -80,10 +80,13 @@ spec:
image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: IfNotPresent
command:
- /bin/kubectl
- apply
- -f
- /etc/config/crd-manifest.yaml
- /bin/sh
- -c
- >
{{- range $path, $_ := (.Files.Glob "crd-manifest/**.yaml") }}
{{- $crd := get (get ($.Files.Get $path | fromYaml) "metadata") "name" }}
kubectl patch crd {{ $crd }} -p '{"metadata": {"finalizers": []}}' || true;
{{- end }}
volumeMounts:
- name: crd-manifest
readOnly: true
Expand All @@ -93,10 +96,10 @@ spec:
image: {{ template "system_default_registry" . }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: IfNotPresent
command:
- /bin/kubectl
- delete
- -f
- /etc/config/crd-manifest.yaml
- /bin/sh
- -c
- >
kubectl delete -f /etc/config/crd-manifest.yaml
volumeMounts:
- name: crd-manifest
readOnly: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ global:
systemDefaultRegistry: ""

image:
repository: rancher/kubectl
tag: v1.20.2
repository: rancher/rancher-agent
tag: v2.5.7