Use of Requirements.lock file in Helm charts - kubernetes-helm

I am trying to understand the usage of Requirements.lock file . For using a dependent chart , we can make use of Requirements.yaml . Based on documentation
Requirements.lock : rebuild the charts/ directory based on the requirements.lock file
Requirements.yaml : update charts/ based on the contents of
requirements.yaml
Can someone explain the difference and usage of lock file and do we need to checking requirements.lock file in the repo too ?

This article says it well:
Much like a runtime language dependency file (such as Python’s requirements.txt), the requirements.yaml file allows you to manage your chart’s dependencies and their versions. When updating dependencies, a lockfile is generated so that subsequent fetching of dependencies use a known, working version.
The requirements.yaml file lists only the immediate dependencies that your chart needs. This makes it easier for you to focus on your chart.
The requirements.lock file lists the exact versions of immediate dependencies and their dependencies and their dependencies and so forth. This allows helm to precisely track the entire dependency tree and recreate it exactly as it last worked--even if some of the dependencies (or their dependencies) are updated later.
Here's roughly how it works:
You create the initial requirements.yaml file. You run helm install and helm creates the requirements.lock file as it builds the dependency tree.
On the next helm install, helm will ensure that it uses the same versions identified in the requirements.lock file.
At some later date, you update the requirements.yaml file. You run helm install (or helm upgrade) and helm will notice your changes and update the requirements.lock file to reflect them.

Related

How to Helm upgrade only subchart

I have multiple subcharts under one helm chart. I install those using the command
helm install my-app . --values values.dev.yaml
It is working fine. All subcharts are part of a one release. Now I have requirements that other member will be starting working those individual subcharts and want to upgrade their subchart without deleting/upgrading the entire application's subchats and in the same release
so when for upgrading one one say frontend subchart from it. I tried
helm upgrade my-app ./charts/frontend --values values.dev.yaml.
It will terminate all the other pods and will keep only pod for this subchart frontend running. Is there any way to upgrade only subcharts of the application without touching the other subcharts?
Just run helm upgrade on the top-level chart normally
rm requirements.lock
helm dependency update
helm upgrade my-app . -f values.dev.yaml
This will "redeploy" the entire chart, including all of its subcharts, but Helm knows to not resubmit unchanged objects to Kubernetes, and Kubernetes knows to not take action when an unmodified object is submitted.
Helm subcharts have some limitations; in addition to what you describe here about not being able to separately manage subcharts' versions, they will also flatten recursive dependencies together (if A depends on B depends on Redis, and A depends on C depends on Redis, B and C will share a single Redis installation and could conflict). If you need to separately manage the versions, consider installing the charts as separate top-level releases.
If your sub-charts are 3rd party dependencies (i.e. you are combining some charts together in a single chart), you can update the external charts by updating Helm dependencies:
Once in the Helm chart dir, where Chart.yaml lives, run
$ helm dependency update
To make sure you get the latest dependency, update Helm repos first:
$ helm repo update && helm dependency update
This will download the latest dependent charts (or the latest allowed, depending on your Chart.yaml config.
Please Note that helm dependency update will download txz files. If no action is taken (i.e. ignore them in git), they could end up version-controlled in your git repo.

List helm dependencies of an installed chart

Helm offers the option of listing dependencies for a chart when browsing through its files.
So if I am above the folder of my-chart, I can perform
▶ helm dependency list my-chart
NAME VERSION REPOSITORY STATUS
common 0.12.6 file://../common/ ok
How can I get the dependencies for the INSTALLED chart, i.e. by retrieving this info from the actualy deployed version? (i.e. the one running on my cluster)
No, you can retrieve this information only using documentation you provided. You should:
Download the chart with $ helm pull repo/name --untar (skip this if you already have it)
Go inside the chart directory
Invoke command: $ helm dependency list my-chart
Alternatively you can inspect requirements.yaml for helm2 or Chart.yaml for helm3, but you will find there only transitive dependencies :
All applications, maybe with the exception of the most trivial,
usually depend on other runtime components, such as web servers,
caches, databases, etc. Helm supports modularization via a dependency
mechanism, which allows to formally specify, manage and deploy
dependencies as part of a Helm release. A Helm chart may declare
dependencies, which are other Helm charts published in external
repositories, conveniently packaged by people who presumably know the
respective components well. The simples possible example is a chart A
-- the dependent - that declared its reliance on a chart B - the dependency - by specifying chart B's “coordinates” (name, version and
repository URL) as part of its own metadata. The exact way in which
the dependencies are declared has evolved across Helm releases. For
Helm 2 charts, the dependencies are declared in a dedicated
requirements.yaml file, while for Helm 3 chart, the dependencies are
declared as part of the chart manifest Chart.yaml. However, the way
the dependencies are processed during installation has remained the
same.
Good article: Helm Dependencies

Automatic upgrade of helm chart files to version 3

I have a ton of helm files, with the structure aligned to comply with Helm2, i.e. a separate requirements.yaml file and no type:application in Chart.yaml
Is there an option in helm-2to3 plugin that automagically places the requirements.yaml under Chart.yaml or do I have to write myself a script to do this?
My charts are checked-in to GH btw (not using a helm repo but operating them via GitOps)
edit: After confirmation in answers below that helm-2to3 does not provide that functionality, I ended up using the draft script below (warning: do not use it in production :) ); you can then proceed by a simple find/xargs oneliner to remove all requirements.yaml (or give them an extension of .bak to keep around for some time).
the chart should of course be run from the root directory of the project where your helm files are kept.
import os
import time
for root, dirs, files in os.walk(os.path.abspath(".")):
for file in files:
if file == "requirements.yaml":
path = os.path.dirname(os.path.join(root, file))
print(path)
os.chdir(path)
files = [f for f in os.listdir('.') if os.path.isfile(f)]
# print(files)
if "requirements.yaml" in files and "Chart.yaml" in files:
requirements_path = os.path.join(root, file)
print("Doing job in..: ", requirements_path)
chart_path = path + "/Chart.yaml"
print(chart_path)
with open(requirements_path) as req:
r = req.read()
with open(chart_path, 'a') as chr:
chr.write(r)
time.sleep(2)
I have a ton of helm template files, with the structure aligned to comply with Helm2, i.e. a separate requirements.yaml file and no type:application in Chart.yaml
The template files, within the helm chart, should work the same way under Helm 3. It's the Chart.yaml file, in each chart that will need to be edited. Unfortunately the helm-2to3 plugin won't do that for you. It's primarily designed to fix the Kubernetes cluster where you might have previously installed helm charts.
Helm3 is capable of installing older helm charts, so I suggest updating each helm chart one at a time.
To conclude, we're using GitOps too. Happily ArgoCD supports both Helm 2 + Helm 3 charts and only uses Helm to generate YAML. This means there is no Helm configuration on the cluster that requires updating. (Miles has a link in his answer, if you're alternatively using FluxCD)
There is a very good plugin that does what you're looking for: https://github.com/helm/helm-2to3
There is also information on migrating a GitOps setup on the Flux CD page (assuming you're using Flux and Helm Operator for your GitOps) https://docs.fluxcd.io/projects/helm-operator/en/stable/helmrelease-guide/release-configuration/#migrating-from-helm-v2-to-v3
Even more information here: https://helm.sh/docs/topics/v2_v3_migration/

When do I put a subchart in the charts/ directory, dependencies in Chart.yaml, or requirements.yaml in Helm?

If I have a chart that depends on another chart, what's the best practices around when it should be included as a package in the charts/ directory vs requirements.yaml vs the dependencies property in Chart.yaml?
For example, if I have a shared dependency that multiple Helm charts will use, should I always put that in a Helm repo and then just refer to it in each chart's requirements.yaml? Or is there a benefit to including it in the charts/ directory?
Example
requirements.yaml
dependencies:
- name: mariadb
version: 7.x.x
repository: https://charts.bitnami.com/bitnami
condition: mariadb.enabled
tags:
- wordpress-database
Chart.yaml
dependencies:
- name: mariadb
version: 7.x.x
repository: https://charts.bitnami.com/bitnami
condition: mariadb.enabled
tags:
- wordpress-database
charts/ directory
my-package.tgz
/charts
mariadb-7.0.0.tgz
...elided...
(and there's technically a 4th where I put the actual exploded chart into the charts directory)
If you need both Helm 2 and Helm 3 compatibility, include it in a separate requirements.yaml file. Most charts will work fine with either version of Helm (if the CLIs are somewhat different) so if your environment still needs Helm 2 compatibility, this is your best choice.
If you don't need Helm 2 compatibility, listing it in the Chart.yaml file is one file fewer.
I'd only manually download the chart (or unpack it) if I had a specific requirement to, probably because my product is uncomfortable downloading software from the public Internet without specifically verifying or approving it. Even then, it's common to have an internal repository of approved artifacts, and it'd be better to point the requirements.yaml/Chart.yaml at that repository than to keep an extra copy. (How do you handle open-source library dependencies in general?)
Even if you have a local dependency chart or support chart library, it's better to properly version it and publish it to a chart repository than to replicate its tarball in charts/ directories. The only benefit to putting a dependency in charts/ is not needing to have it in a repository, but you'll usually want a repository for ease of management.

Using external version.txt for Helm Chart.yaml

When packaging using a Helm Chart.yaml you must specify a version. We would like the chart version to match the apps version.
If there a way to read our existing version.txt file instead of remembering (or not) to update in two places?
There isn't. To confuse things further there's also an appVersion field in the Chart.yaml file saying what version of the application you're packaging, but it's also near-universal to be able to specify an image tag as a value, with the same effect.
This field is only really used by Helm-specific tooling, for example if this chart is listed as a dependency of other charts or if you're publishing the chart to a central repository. If you're not doing either of these things you can largely ignore the version: field.
If your CI system is publishing the Helm chart to a repository, you might be forced to have it modify the Chart.yaml file before publishing it. A simple sed command will work
sed -i.bak "s/^version:/version: $APP_VERSION/" Chart.yaml
but it does become slightly messy to set up.
If you have a more formal "release" process then you would have to remember to update the version number in both places; writing a shell script to update the version numbers (and tag the release in source control, and do whatever other tasks you need) is probably the most straightforward answer.