github.com/GoogleContainerTools/skaffold/v2@v2.13.2/docs-v2/content/en/docs/deployers/helm.md (about) 1 --- 2 title: "Helm [UPDATED]" 3 linkTitle: "Helm [UPDATED]" 4 weight: 40 5 featureId: deploy 6 aliases: [/docs/pipeline-stages/deployers/helm] 7 --- 8 9 [`helm`](https://helm.sh/) is a package manager for Kubernetes that helps you 10 manage Kubernetes applications. Skaffold natively supports iterative development 11 for projects configured to use helm. 12 13 {{< alert title="Note" >}} 14 To use `helm` with Skaffold, the `helm` binary must be installed on your machine. Skaffold will not install it for you. 15 {{< /alert >}} 16 17 18 # Configuring your Helm Project with Skaffold 19 20 Skaffold supports projects set up to render and/or deploy with Helm, but certain aspects of the project need to be configured correctly in order for Skaffold to work properly. This guide should demystify some of the nuance around using Skaffold with Helm to help you get started quickly. 21 22 {{< alert title="No more `artifactOverrides` or `imageStrategy`" >}} 23 Skaffold no longer requires the intricate configuring of `artifactOverrides` or `imageStrategy` fields. See docs [here]({{< relref "#image-reference-strategies" >}}) on how old `artifactOverrides` and `imageStrategy` values translate to `setValueTemplates` entries in the latest Skaffold schemas (`apiVersion: skaffold/v3alpha1` or skaffold binary version `v2.0.0` onwards) 24 {{< /alert >}} 25 26 {{< alert title="Note" >}} 27 In Skaffold `v2` the primary difference between the helm renderer (`manifest.helm.*`) and the helm deployer (`deploy.helm.*`) is the use of `helm template` vs `helm install` 28 {{< /alert >}} 29 30 31 ## How `helm` render support works in Skaffold 32 In the latest version of Skaffold, the primary methods of using `helm` templating with Skaffold involve the `deploy.helm.setValueTemplates` and the `deploy.helm.setValues` fields. `deploy.helm.setValues` supplies the key:value pair to substitute from a users `values.yaml` file (a standard `helm` file for rendering). `deploy.helm.setValueTemplates` does a similar thing only the key:value value comes from an environment variable instead of a given value. Depending on how a user's `values.yaml` and how `charts/templates` specify `image: $IMAGE_TEMPLATE`, the docs [here]({{< relref "#image-reference-strategies" >}}) explain the proper `setValueTemplates` to use. When migrating from schema version `v2beta29` or less, Skaffold will automatically configure these values to continue to work. 33 34 35 `helm` deploy support in Skaffold is accomplished by calling `helm install ...` with the appropriate `--set` flags for the variables Skaffold will inject as well as uses the `skaffold` binary as a `helm` `--post-renderer`. Using `skaffold` as a post-renderer is done to inject Skaffold specific labels primarily the `run-id` label which Skaffold uses to tag K8s objects it will manage via it's status checking. 36 37 38 This works by having Skaffold run `helm install ...` taking into consideration all of the supplied flags, skaffold.yaml configuration, etc. and creating an intermediate yaml manifest with all helm replacements except that the fully qualified image from the current run is NOT added but instead a placeholder with the artifact name - eg: `skaffold-helm-image`. Then the skaffold post-renderer is called to convert `image: skaffold-helm-image` -> `image: gcr.io/example-repo/skaffold-helm-image:latest@sha256:<sha256-hash>` in specified locations (specific allowlisted k8s objects and/or k8s object fields). This above replacement is nearly identical to how it works for values.yaml files using only the `image` key in `values.yaml` - eg: 39 `image: "{{.Values.image}}"` 40 41 When using `image.repository` + `image.tag` or `image.registry` + `image.repository` + `image.tag` - eg: 42 `image: "{{.Values.image.repository}}:{{.Values.image.tag}}"` 43 `image: "{{.Values.image.registry}}/{{.Values.image.repository}}:{{.Values.image.tag}}"` 44 there is some specialized logic that the skaffold `post-renderer` uses to properly handling these cases. See the docs [here]({{< relref "#image-reference-strategies" >}}) on the correct way to specify these for Skaffold using `setValueTemplates` 45 46 {{< alert title="Note" >}} 47 Starting in Skaffold `v2.1.0`, Skaffold will output additional `setValueTemplates` 48 {{< /alert >}} 49 50 ## Image Configuration 51 The normal Helm convention for defining image references is through the `values.yaml` file. Often, image information is configured through an `image` stanza in the values file, which might look something like this: 52 53 ```project_root/values.yaml``` 54 ```yaml 55 image: 56 repository: gcr.io/my-repo # default repo 57 tag: v1.2.0 # default tag 58 pullPolicy: IfNotPresent # default PullPolicy 59 image2: 60 repository: gcr.io/my-repo-2 # default repo 61 tag: latest # default tag 62 pullPolicy: IfNotPresent # default PullPolicy 63 ``` 64 65 This images would then be referenced in a templated resource file, maybe like this: 66 67 ```project_root/templates/deployment.yaml:``` 68 ```yaml 69 spec: 70 template: 71 spec: 72 containers: 73 - name: {{ .Chart.Name }} 74 image: {{ .Values.image.repository }}:{{ .Values.image.tag}} 75 imagePullPolicy: {{ .Values.image.pullPolicy }} 76 - name: {{ .Chart.Name }} 77 image: {{ .Values.image2.repository }}:{{ .Values.image2.tag}} 78 imagePullPolicy: {{ .Values.image2.pullPolicy }} 79 ``` 80 81 **IMPORTANT: To get Skaffold to work with Helm, the `image` key must be configured in the skaffold.yaml.** 82 83 Associating the Helm image key allows Skaffold to track the image being built, and then configure Helm to substitute it in the proper resource definitions to be deployed to your cluster. In practice, this looks something like this: 84 85 ```yaml 86 build: 87 artifacts: 88 - image: myFirstImage # must match in setValueTemplates 89 - image: mySecondImage # must match in setValueTemplates 90 deploy: 91 helm: 92 releases: 93 - name: my-release 94 setValueTemplates: 95 image.repository: "{{.IMAGE_REPO_myFirstImage}}" 96 image.tag: "{{.IMAGE_TAG_myFirstImage}}@{{.IMAGE_DIGEST_myFirstImage}}" 97 image2.repository: "{{.IMAGE_REPO_mySecondImage}}" 98 image2.tag: "{{.IMAGE_TAG_mySecondImage}}@{{.IMAGE_DIGEST_mySecondImage}}" 99 setValues: 100 image.pullPolicy: "IfNotPresent" 101 image2.pullPolicy: "IfNotPresent" 102 ``` 103 104 The `setValues` configuration binds a Helm key to the specified value. The `setValueTemplates` configuration binds a Helm key to an environment variable. Skaffold generates useful environment variables (available via `setValueTemplates`) for each build artifact (value in build.artifacts\[x\].image). Currenty these include: 105 106 | Helm Template Value | Example Value | 107 | --------------- | --------------- | 108 | `{{.IMAGE_FULLY_QUALIFIED_<artifact-name>}}` | `gcr.io/example-repo/myImage:latest@sha256:<sha256-hash>`| 109 | `{{.IMAGE_REPO_<artifact-name>}}` | `gcr.io/example-repo/myImage` | 110 | `{{.IMAGE_TAG_<artifact-name>}}` | `latest` | 111 | `{{.IMAGE_DIGEST_<artifact-name>}}` | `sha256:<sha256-hash>` | 112 | `{{.IMAGE_DOMAIN_<artifact-name>}}` | `gcr.io` | 113 | `{{.IMAGE_REPO_NO_DOMAIN_<artifact-name>}}` | `example-repo` | 114 115 ### Sanitizing the artifact name from invalid go template characters 116 The `<artifact-name>` (eg: `{{.IMAGE_FULLY_QUALIFIED_<artifact-name>}}`) when used with `setValueTemplates` cannot have `/`, `-`, `.`, or `:` characters. If you have an artifact name with these characters (eg: `localhost/nginx` or `gcr.io/foo-image/foo`), change them to use `_` in place of these characters in the `setValueTemplates` field 117 118 | Artifact name | Sanitized Name | 119 | --------------- | --------------- | 120 | `localhost/nginx` | `localhost_nginx`| 121 | `gcr.io/example-repo/myImage` | `gcr_io_example_repo_myImage` | 122 | `gcr.io/example-repo/myImage:1234_container` | `gcr_io_example_repo_myImage_1234_container` | 123 124 Example 125 ```yaml 126 build: 127 artifacts: 128 - image: localhost/nginx # must match in setValueTemplates w/ `/` & `-` changed to `_` 129 deploy: 130 helm: 131 releases: 132 - name: my-chart 133 chartPath: helm 134 setValueTemplates: 135 image: {{.IMAGE_FULLY_QUALIFIED_localhost_nginx}} 136 137 ``` 138 139 140 ### Image reference strategies 141 142 Skaffold supports three _image reference strategies_ for Helm: 143 144 1. `fqn`: provides a fully-qualified image reference (default); 145 2. `helm`: provides separate repository and tag portions (shown above); 146 3. `helm+explicitRegistry`: provides separate registry, repository, and tag portions. 147 148 #### `fqn` strategy: single fully-qualified name (default) 149 150 With the fully-qualified name strategy, Skaffold configures Helm by setting a key to the fully-tagged image reference. 151 152 The `skaffold.yaml` setup: 153 ```yaml 154 build: 155 artifacts: 156 - image: myFirstImage # must match in setValueTemplates 157 - image: mySecondImage # must match in setValueTemplates 158 deploy: 159 helm: 160 releases: 161 - name: my-chart 162 chartPath: helm 163 setValueTemplates: 164 image: {{.IMAGE_FULLY_QUALIFIED_myFirstImage}} 165 image2: {{.IMAGE_FULLY_QUALIFIED_mySecondImage}} 166 ``` 167 The `values.yaml` (note that Skaffold overrides this value): 168 ``` 169 image: gcr.io/other-project/other-image:latest 170 image2: gcr.io/other-project/other-image:latest 171 ``` 172 173 The chart template: 174 ```yaml 175 spec: 176 containers: 177 - name: {{ .Chart.Name }} 178 image: "{{.Values.image}}" 179 - name: {{ .Chart.Name }} 180 image: "{{.Values.image2}}" 181 ``` 182 183 Skaffold will invoke 184 ``` 185 helm install <chart> <chart-path> --set-string image=<artifact-name>,image2=<artifact-name> --post-renderer=<path-to-skaffold-binary-from-original-invocation> 186 ``` 187 188 #### `helm` strategy: split repository and tag 189 190 Skaffold can be configured to provide Helm with a separate repository and tag. The key used in the `artifactOverrides` is used as base portion producing two keys `{key}.repository` and `{key}.tag`. 191 192 The `skaffold.yaml` setup: 193 ```yaml 194 build: 195 artifacts: 196 - image: myFirstImage # must match in setValueTemplates 197 - image: mySecondImage # must match in setValueTemplates 198 deploy: 199 helm: 200 releases: 201 - name: my-chart 202 chartPath: helm 203 setValueTemplates: 204 image.repository: "{{.IMAGE_REPO_myFirstImage}}" 205 image.tag: "{{.IMAGE_TAG_myFirstImage}}@{{.IMAGE_DIGEST_myFirstImage}}" 206 image2.repository: "{{.IMAGE_REPO_mySecondImage}}" 207 image2.tag: "{{.IMAGE_TAG_mySecondImage}}@{{.IMAGE_DIGEST_mySecondImage}}" 208 ``` 209 210 The `values.yaml` (note that Skaffold overrides these values): 211 ``` 212 image: 213 repository: gcr.io/other-project/other-image 214 tag: latest 215 image2: 216 repository: gcr.io/other-project/other-image 217 tag: latest 218 ``` 219 220 The chart template: 221 ```yaml 222 spec: 223 containers: 224 - name: {{ .Chart.Name }} 225 image: "{{.Values.image.repository}}:{{.Values.image.tag}}" 226 - name: {{ .Chart.Name }} 227 image: "{{.Values.image2.repository}}:{{.Values.image2.tag}}" 228 ``` 229 230 Skaffold will invoke 231 ``` 232 helm install <chart> <chart-path> --set-string image.repository=<artifact-name>,image.tag=<artifact-name>,image2.repository=<artifact-name>,image2.tag=<artifact-name> --post-renderer=<path-to-skaffold-binary-from-original-invocation> 233 ``` 234 235 #### `helm`+`explicitRegistry` strategy: split registry, repository, and tag 236 237 Skaffold can also be configured to provide Helm with a separate repository and tag. The key used in the `artifactOverrides` is used as base portion producing three keys: `{key}.registry`, `{key}.repository`, and `{key}.tag`. 238 239 The `skaffold.yaml` setup: 240 ```yaml 241 build: 242 artifacts: 243 - image: myFirstImage # must match in setValueTemplates 244 - image: mySecondImage # must match in setValueTemplates 245 deploy: 246 helm: 247 releases: 248 - name: my-chart 249 chartPath: helm 250 setValueTemplates: 251 image.registry: "{{.IMAGE_DOMAIN_myFirstImage}}" 252 image.repository: "{{.IMAGE_REPO_NO_DOMAIN_myFirstImage}}" 253 image.tag: "{{.IMAGE_TAG_myFirstImage}}@{{.IMAGE_DIGEST_myFirstImage}}" 254 image2.registry: "{{.IMAGE_DOMAIN_mySecondImage}}" 255 image2.repository: "{{.IMAGE_REPO_NO_DOMAIN_mySecondImage}}" 256 image2.tag: "{{.IMAGE_TAG_mySecondImage}}@{{.IMAGE_DIGEST_mySecondImage}}" 257 ``` 258 259 The `values.yaml` (note that Skaffold overrides these values): 260 ``` 261 image: 262 registry: gcr.io 263 repository: other-project/other-image 264 tag: latest 265 image2: 266 registry: gcr.io 267 repository: other-project/other-image 268 tag: latest 269 ``` 270 271 The chart template: 272 ```yaml 273 spec: 274 containers: 275 - name: {{ .Chart.Name }} 276 image: "{{.Values.image.registry}}/{{.Values.image.repository}}:{{.Values.image.tag}}" 277 ``` 278 279 Skaffold will invoke 280 ``` 281 helm install <chart> <chart-path> --set-string image.registry=<artifact-name>,image.repository=<artifact-name>,image.tag=<artifact-name>,image2.registry=<artifact-name>,image2.repository=<artifact-name>,image2.tag=<artifcact-name> --post-renderer=<path-to-skaffold-binary-from-original-invocation> 282 ``` 283 284 ### Helm Build Dependencies 285 286 The `skipBuildDependencies` flag toggles whether dependencies of the Helm chart are built with the `helm dep build` command. This command manipulates files inside the `charts` subfolder of the specified Helm chart. 287 288 If `skipBuildDependencies` is `false` then `skaffold dev` does **not** watch the `charts` subfolder of the Helm chart, in order to prevent a build loop - the actions of `helm dep build` always trigger another build. 289 290 If `skipBuildDependencies` is `true` then `skaffold dev` watches all files inside the Helm chart. 291 292 ### `skaffold.yaml` Configuration 293 294 The `helm` type offers the following options: 295 296 {{< schema root="HelmDeploy" >}} 297 298 Each `release` includes the following fields: 299 300 {{< schema root="HelmRelease" >}}