-
Notifications
You must be signed in to change notification settings - Fork 608
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2597 from fluxcd/rfc-helm-oci
[RFC-0002] Flux OCI support for Helm
- Loading branch information
Showing
1 changed file
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# RFC-0002 Flux OCI support for Helm | ||
|
||
**Status:** implementable | ||
|
||
**Creation date:** 2022-03-30 | ||
|
||
**Last update:** 2022-04-13 | ||
|
||
## Summary | ||
|
||
Given that Helm v3.8 supports [OCI](https://helm.sh/docs/topics/registries/) for package distribution, | ||
we should extend the Flux Source API to allow fetching Helm charts from container registries. | ||
|
||
## Motivation | ||
|
||
Helm OCI support is one of the most requested feature in Flux | ||
as seen on this [issue](https://github.com/fluxcd/source-controller/issues/124). | ||
|
||
With OCI support, Flux users can automate chart updates to Git in the same way | ||
they do today for container images. | ||
|
||
### Goals | ||
|
||
- Add support for fetching Helm charts stored as OCI artifacts with minimal API changes to Flux. | ||
- Make it easy for users to switch from [HTTP/S Helm repositories](https://github.com/helm/helm-www/blob/416fabea6ffab8dc156b6a0c5eb5e8df5f5ef7dc/content/en/docs/topics/chart_repository.md) | ||
to OCI repositories. | ||
|
||
### Non-Goals | ||
|
||
- Introduce a new API kind for referencing charts stored as OCI artifacts. | ||
|
||
## Proposal | ||
|
||
Introduce an optional field called `type` to the `HelmRepository` spec. | ||
|
||
When not specified, the `spec.type` field defaults to `Default` which preserve the current `HelmRepository` API behaviour. | ||
|
||
When the `spec.type` field is set to `OCI`, the `spec.url` field must be prefixed with `oci://` (to follow the Helm conventions). | ||
For `oci://` URLs, source-controller will use the Helm SDK and the `oras` library to connect to the OCI remote storage. | ||
For authentication, the controller will use Kubernetes secrets of `kubernetes.io/dockerconfigjson` type. | ||
|
||
### User Stories | ||
|
||
#### Story 1 | ||
|
||
> As a developer I want to use Flux `HelmReleases` that refer to Helm charts stored | ||
> as OCI artifacts in GitHub Container Registry. | ||
First create a secret using a GitHub token that allows access to GHCR: | ||
|
||
```sh | ||
kubectl create secret docker-registry ghcr-charts \ | ||
--docker-server=ghcr.io \ | ||
--docker-username=$GITHUB_USER \ | ||
--docker-password=$GITHUB_TOKEN | ||
``` | ||
|
||
Then define a `HelmRepository` of type `OCI` and reference the `dockerconfig` secret: | ||
|
||
```yaml | ||
apiVersion: source.toolkit.fluxcd.io/v1beta2 | ||
kind: HelmRepository | ||
metadata: | ||
name: ghcr-charts | ||
namespace: default | ||
spec: | ||
type: OCI | ||
url: oci://ghcr.io/my-org/charts/ | ||
secretRef: | ||
name: ghcr-charts | ||
``` | ||
And finally in Flux `HelmReleases`, refer to the ghcr-charts `HelmRepository`: | ||
|
||
```yaml | ||
apiVersion: helm.toolkit.fluxcd.io/v2beta1 | ||
kind: HelmRelease | ||
metadata: | ||
name: my-app | ||
namespace: default | ||
spec: | ||
interval: 60m | ||
chart: | ||
spec: | ||
chart: my-app | ||
version: '1.0.x' | ||
sourceRef: | ||
kind: HelmRepository | ||
name: ghcr-charts | ||
interval: 1m # check for new OCI artifacts every minute | ||
``` | ||
|
||
#### Story 2 | ||
|
||
> As a platform admin I want to automate Helm chart updates based on a semver ranges. | ||
> When a new patch version is available in the container registry, I want Flux to open a PR | ||
> with the version set in the `HelmRelease` manifests. | ||
|
||
Given that charts are stored in container registries, you can use Flux image automation | ||
and patch the chart version in Git, in the same way Flux works for updating container image tags. | ||
|
||
Define an image registry and a policy for the chart artifact: | ||
|
||
```yaml | ||
apiVersion: image.toolkit.fluxcd.io/v1beta1 | ||
kind: ImageRepository | ||
metadata: | ||
name: my-app | ||
namespace: default | ||
spec: | ||
image: ghcr.io/my-org/charts/my-app | ||
interval: 1m0s | ||
--- | ||
apiVersion: image.toolkit.fluxcd.io/v1beta1 | ||
kind: ImagePolicy | ||
metadata: | ||
name: my-app | ||
namespace: default | ||
spec: | ||
imageRepositoryRef: | ||
name: my-app | ||
policy: | ||
semver: | ||
range: 1.0.x | ||
``` | ||
|
||
Then add the policy marker to the `HelmRelease` manifests in Git: | ||
|
||
```yaml | ||
apiVersion: helm.toolkit.fluxcd.io/v2beta1 | ||
kind: HelmRelease | ||
metadata: | ||
name: my-app | ||
namespace: default | ||
spec: | ||
interval: 60m | ||
chart: | ||
spec: | ||
chart: my-app | ||
version: 1.0.0 # {"$imagepolicy": "default:my-app:tag"} | ||
sourceRef: | ||
kind: HelmRepository | ||
name: ghcr-charts | ||
interval: 1m | ||
``` | ||
|
||
### Alternatives | ||
|
||
We could introduce a new API type e.g. `HelmRegistry` to hold the reference to auth secret, | ||
as proposed in [#2573](https://github.com/fluxcd/flux2/pull/2573). | ||
That is considered unpractical, as there is no benefit for users in having a dedicated kind instead of | ||
a `type` field in the current `HelmRepository` API. Adding a `type` field to the spec follows the Flux | ||
Bucket API design, where the same Kind servers different implementations: AWS S3 vs Azure Blob vs Google Storage. | ||
|
||
## Design Details | ||
|
||
In source-controller we'll add a new predicate for filtering `HelmRepositories` based on the `spec.type` field. | ||
|
||
The current `HelmRepositoryReconciler` will be renamed to `HelmRepositoryDefaultReconciler`, | ||
it's scope remains unchanged, and it will handle only objects with `type: Default`. | ||
|
||
We'll introduce a new reconciler named `HelmRepositoryOCIReconciler`, that will handle | ||
objects with `type: OCI`. This reconciler will set the `HelmRepository` Ready status to | ||
`False` if the URL is not prefixed with `oci://`, otherwise the Ready status will be set to `True`. | ||
|
||
The current `HelmChartReconciler` will be renamed to `HelmChartDefaultReconciler`, | ||
it's scope remains unchanged, and it will handle only objects that refer to `HelmRepositories` with `type: Default`. | ||
|
||
For `type: OCI` we'll introduce a new reconciler `HelmChartOCIReconciler` that uses `oras` to download charts | ||
and their dependencies. | ||
|
||
### Enabling the feature | ||
|
||
The feature is enabled by default. |