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

Proposal to converge helm repositories with docker registries #55

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Proposal 1 - Container Registries provide Helm Repositories

As Helm Charts are designed around the intention of deploying images, it's a natural evolution to store Helm Charts in registries, alongside the images they reference.

As Helm is evolving as the defacto deployment technology, it's believed it's time to evolve registries to support additional artifacts, such as Helm Charts.


For registries to support Helm Charts, a few changes are proposed
1. [Helm Charts align with registry repositories](./002-chart-registry-repo.md)
enabling fully qualified charts
1. [Helm Charts use registry authentication](./003-chart-authentication.md)
1. [Helm Chart Versions merge with docker tags](./006-helm-version-tags.md)
With all the good and evil of "latest" and "stable" tags and versions.
1. [Local Helm Store becomes a cache](./007-helm-store-cache.md)
aligning more with docker run, intermittently does pulls, avoiding the need to continually call `helm repo add`
1. [`helm search` becomes a server side query](./008-helm-search-server-query.md)
Further converging the local Helm store as a remote cache


## Converging with Registries
While docker provides a baseline reference implementation through [docker distribution](https://github.com/docker/distribution), cloud providers of registries have had to fill in specifics for high scale/concurrent delivery.

Delivering images at cloud scale requires a number of enhancements including:
- indexing
- caching
- authentication
- versioning

The evolution and implementation required to deliver Image Manifests and images at cloud scale are a super-set of the needs to deliver charts at cloud scale.

## Upstream Support to Docker Distribution

Proposal to commit upstream changes to [docker distribution](https://github.com/docker/distribution) to enable all implementors of the upstream project to easily adopt Helm Repositories.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Helm Charts Align With Registry Repositories
Container images are referneced with a multi-part URL:

- [**login url**] / [**namespace**] / [**repo**] : [**tag**]
- [**namespace**] / [**repo**] : [**tag** ] are equally referred to as an "image"

Different clouds implement the unique login url in a few different forms, while effectively meaning the same thing:

| Cloud | Format | eg: image |
|-----|-----|-----|
| Docker Hub | [**org**\|**user** ] / [**image**] : [**tag**] **\*1**| [contoso/marketing-fall2018-web:aab1]() |
| Azure Container Registry (acr) | [**uniqueId**].azurecr.io / [**namespace**] / [**image**] : [**tag**] | contoso.azurecr.io/marketing/fall2018/web:aab1 |
| Google Container Registry (gcr) | gcr.io/[**uniqueId**] / [**image**] : [**tag**] | gcr.io/marketing/fall2018-web:aab1 |
| AWS Container Registry (ecr) | [**aws_account_id**].dkr.ecr.region.amazonaws.com/ [**image**] : [**tag**] | 123abc456def.dkr.ecr.region.amazonaws.com/marketing/fall2018-web:aab1 |

1. Docker Hub has a default login url [docker.io]()
1. Docker Hub [**org**\|**user** ] is a [**namespace**] which is currently limted to two nodes.
*The [Microsoft Container Registry (mcr)](mcr.microsoft.com) has implemented a syndicated catalog representing a product hierarchy within the docker store, and looks for Docker to expand this for other partners with deep image catalogs.*

## Helm References

Proposal aligns Helm Charts with the same referencing scheme:
- [**login url**] / [**namespace**] / [**chart**] : [**version/tag**]
Copy link

Choose a reason for hiding this comment

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

cc @jzelinskie
We made some changes around that. For production usually it's not recommended to use mutable tags,
In example, v1.1.0 could refer to different sha overtime. Usually the recommendation is to directly use the sha256, to guaranty which software-version is getting pulled.

To simplify this process, and push best practices,
We tried a slightly different UX than docker:

  1. We introduced the concept of channels, a channel is a pointer to a sha and it can move over time: e.g beta, stable, latest, master, dev .....
    Since a channel is 'nearly' a current docker tag, the command line is the same, using :
[**login url**] / [**namespace**] / [**chart**] : [**channel**]

e.g: https://quay.io/application/charts/ghost?tab=releases, the channel 'stable' is currently pointing to v1.0.1

helm registry pull quay.io/charts/ghost:stable 
Pull package: charts/ghost... 
./charts_ghost_1.0.1
  1. A tag/version is immutable and can be seen as an alias to the sha256. It's more convinent to remember but as 'safe' as using the sha.
    The user refer to an immutable version/tag with @:
helm registry pull quay.io/charts/ghost@1.0.1 

This command is equivalent to:

helm registry pull quay.io/charts/ghost@sha256:35d3ec4fd61914383be8e94d3fe8a74fc24b2e2baedf87042b13d033e674290c

wdyt ?

Copy link
Author

Choose a reason for hiding this comment

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

Channels are a very interesting concept, specifically as chart owners wish to flight updates to a specific version, and they provide a preview for what's coming.
The value I see for mutable tags(versions) is the ability to get security updates to a specific version without direct intervention:

  • I deploy version 1 of a thing
  • Version 2 of the thing is made available. By calling it version 2, it's presumed to be breaking changes, and I (as the developer/ops person) should opt into version 2
  • A security flaw is found in sub-particle-a that both Version 1 and 2 reference in their charts.
  • The security fix is flighted to the preview channel for both version 1 & 2
  • After approval, thing: version 1 and thing:2 are updated.
  • My company is watching changes to version 1, and quickly takes the update, tests it, and deploys the updated "stable" version.

In the above example, the thing owners were able to flight a security fix to version 1 & 2. The users of thing:1 were able to get updates, without having to involve development teams to make specific changes.

The great thing about additional channels is an org can also run automated tests on the preview channel. If any errors occur, they can automate reporting of issues.

If i reference a sha directly, I'm always bound to that very specific version, with no ability to move forward for automated patching. I wrote about this here: https://stevelasker.blog/2018/03/01/docker-tagging-best-practices-for-tagging-and-versioning-docker-images/

I think channels and stable tags are better together, but not mutual exclusive.

Copy link

@ant31 ant31 Nov 14, 2018

Choose a reason for hiding this comment

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

The value I see for mutable tags(versions) is the ability to get security updates to a specific version without direct intervention:

That exactly the purpose of the channel, and was automatic upgrade was the main focus this feature. You can of course use channels like version/tags, or 'allow' mutable tags (explicitly allow force push) but default/recommended usage would be:

channel: mutable
tag: non-mutable

Automatic upgrades should be opt-in, not a side effect.

  • I deploy channel 1-stable of a thing (points to the version/tag 1.2.0)

  • Version 2 of the thing is made available. By calling it version/tag 2.0.0, it's presumed to be breaking changes, and I (as the developer/ops person) should opt into channel 2-stable

  • A security flaw is found in sub-particle-a that both Version 1.2.0 and 2.0.0 reference in their charts.
    The security fix is flighted to both channels 1-beta & 2-beta,

  • After approval, version/tags 1.2.1 and 2.0.1 are pushed, channels 1-stable is updated to points to 1.2.1, and channel 2-beta is updated to 2.0.1

  • My company is watching changes to version 1-stable, and quickly takes the update, tests it, and deploys the updated "stable" version.

In term of use experience
The chart maintainer it is doing:

  1. Release the security fix in the beta channels
# Push 1.2.1 to the beta channel
$ helm registry push quay.io/myorg  --channel 1-beta
>>> Release '1.2.1' added to the '1-beta' channel

# Push 2.0.1 to the beta channel
$ helm registry push quay.io/myorg  --channel 2-beta
>>> Release '2.0.1' added to the '2-beta' channel
  1. Review channels:
$ helm registry channel quay.io/myorg/thing
channel    release
---------  ---------
1-stable     1.2.0
1-beta        1.2.1
2-stable      2.0.0
2-beta        2.0.1
  1. Once confirmed / approved, promote from beta to stable
$ helm registry push quay.io/myorg  --channel 1-stable
>>> Release '1.2.1' added to the '1-stable' channel
$ helm registry push quay.io/myorg  --channel 2-stable
>>> Release '2.0.1' added to the '2-stable' channel

For the application use the experience is either:

  • manually pull versions
helm registry install quay.io/org/thing@v1.2.1
  • Trust the channels and get automatic latest versions
helm registry install quay.io/org/thing:1-stable

At least, we should be able to 'protect' a tag from being 'force' pushed.

Copy link
Author

Choose a reason for hiding this comment

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

I see where your going. It's basically a more explicit way to opt into updates for a stable tag.
The thing that strikes me with this is:

  • customers are already struggling with stable and unique tags
  • they don't seem to be understanding the wave of problems ahead of them for patching containers
  • when I tell them about it, they either think containers aren't as great as they hoped (looking backwards), or they get it and love the ability to patch, test, then deploy a container
  • channels adds yet another concept they are struggling to keep up with
  • how can we get this into distribution across all registries so it's a common thing. Unless it's common, I struggle with it getting great adoption

I do like the expectations. Just struggle with getting it to common usage.

Is this something we can layer in, as customers feel the pain?

Copy link

@ant31 ant31 Nov 14, 2018

Choose a reason for hiding this comment

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

channels adds yet another concept they are struggling to keep up with

We can completely layer that, and not even talk about channels to begin with.
Channels are not a key feature, nor required to use a registry, then it should not be a big deal if vendor don't adopt it at the same time.

I'm bringing that early, because it could change the cli UX.
With app-registry, after several iteration we landed with:

helm pull domain/org/app:channel
helm pull domain/org/app@tag
helm pull domain/org/app@sha256

If we delay channels for let's say12 months, and everyone is using the syntax:

helm pull domain/org/app:tag

it will be impossible to switch to :channel / @tag.

So the only question to answer early is:

  • how users will pull or deploy from a channel via the CLI ?
helm pull domain/org/app --channel beta
helm pull domain/org/app+beta
helm pull domain/org/app:beta  # lookup for the tag beta first , then for the channel 
....

ps:
About customers, we presented it saying: "you can subscribe to stable/beta/alpha channels and get automatic upgrades or... continue to manually manage versions". This looked much more like a step forward than backward in term of maintenance and operations.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Helm Charts Use Registry Authentication

Enabling a registry to assign a user/group/service account access to one or more chart and image repositories

Client authentication is cached, similar to docker credentials, but doesn't depend on docker locally installed

## Helm CLI Integrated
Different cloud providers have different methods of authentication. However, this creates a disjointed experience requiring the user to use the clouds CLI and tool CLI.
The proposed goal here is to enable a common authentication model that doesn't require additional plug-ins.

It's intended to support a common API on Helm Chart repositories to support:

- Basic Auth
- Token Auth
- Cert Based Auth
- 2 Factor Auth

### Proposed Experience
To create a Helm native experience, we're proposing:
```sh
# basic auth
helm login [registryURL] -u $USER -p $PASSWORD
# token
helm login [registryURL] --token $TOKEN
# cert
helm login [registryURL] --cert --certPath $OPTIONAL_CERT_PATH
```
Example:
```sh
helm login demo42.azurecr.io -u -p
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# `helm update` & `helm install` support remote urls

Deploying a helm chart from a remote URL is supported today, however the repo must be specified as a parameter.
```sh
helm upgrade \
--repo=https://demo42.azurecr.io/base-charts/team-charts \
myrelease \
chartmuseum
```
This proposal suggests charts can be fully referenced:

```sh
helm upgrade myrelease demo42.azurecr.io/base-charts/team-charts/chartmuseum
```

Helm Charts do not need to be fully qualified
Just as docker images don't need to be fully qualified to be used, a helm chart wouldn't require this either.

A user can build a chart locally, refer to it as chartmusueum, and deploy it.

To push the chart, it would be "tagged", in docker terms to prepend the registry login url.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Proposal 6 Helm Chart Versions merge with docker tags

2.0 Helm Charts use semantic versioning. Semantic versioning is far more predictable and structured then docker tags.

Proposal:

1. [Maintain semantic versioning](#proposal-8-1)
2. Align with : notation to differentiate domains (.), namespaces (/) and file name extensions.
3. Maintain "latest" concept, which also aligns with the docker manifest concept to have two tags equate tot the same chart.
Copy link

@eldada eldada Nov 12, 2018

Choose a reason for hiding this comment

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

Typo? ...two tags equate tot the same... -> ...two tags equate to the same

Copy link

Choose a reason for hiding this comment

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

See the comment about 'channels'. We enforced the semver for 'tags/version', and let a free-form for channels'

### 1 Maintain Semantic Versioning <a id="proposal-8-1"></a>
To avoid the open form, difficult to parse docker tagging format, semantic versioning will continue to be supported.
However, similar to stable tags, including :latest, helm charts would provide versioned, stable releases.
Helm Charts would leverage manifests that enable two or more "versions" to reference the same chart.

- `helm pull demo42.azrecr.io/base-charts/team-charts/chartmuseum:1.2.1`
- `helm update myDeployment demo42.azrecr.io/base-charts/team-charts/chartmuseum:1.2.1`





Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Proposal 7 - Helm Chart Cache
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that this topic is valid regardless of which direction we go as it relates to Docker convergence.

We should remove this and open it as its own proposal. People would benefit from this.

Please also see related issue #54

Copy link
Author

Choose a reason for hiding this comment

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

there are several items here. Happy to split up and converge with other proposals, like #54 as it makes sense. Perhaps to discuss on the call today to figure out specific next steps.

To support multiple registries, with nested repositories, a folder cache, with matching hierarchy is proposed:
`demo42.azrecr.io/base-charts/team-charts/chartmuseum:1.2.1` would be represented on disk as:

```
└── demo42.azrecr.io
└── base-charts
└── team-charts
└── chartmuseum
└── 1.2.1
```
### Helm Chart Cache

The helm chart store is typically a local store. To pull a public chart, make changes, then push the chart to a private helm repository, the local store can get out of sync.
57 changes: 57 additions & 0 deletions proposals/helm-repo-container-registry-convergence/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Helm Repo and Container Registry Convergence Proposal

As Helm Charts become the way customers deploy and update multi-image deployments to Kubernetes, which references images stored in a registry, theirs an opportunity to align Helm concepts with registry concepts.

This proposal suggests aligning some of the commands and chart references to align more consistently with a container registry.

The proposal doesn't suggest changes in how charts are deployed, rather the storage and referencing of Helm charts.

The proposal covers the following:

1. [Container Registries are collections of Helm Repositories](./001-repo-registry.md)
Evolution of [Docker Distribution](https://github.com/docker/distribution) to support Helm Repositories
2. [Helm Charts Align With Registry Repositories](./002-chart-registry-repo.md)
Consistent with an image repository, a chart repository is a specific chart, with unique tags representing a versioned history
3. [Helm Charts use registry authentication](./003-chart-authentication.md)
4. [`helm fetch` becomes `helm pull`](./004-helm-fetch-pull.md)
aligning the commands more consistently
5. [`helm update` & `helm install` support remote urls](./005-helm-fetch-url.md)
Without having to set a `--repo` parameter
6. [Helm Chart Versions merge with docker tags](./006-helm-version-tags.md)
With all the good and evil of "latest" and "stable" tags and versions.
7. [Local Helm Store becomes a cache](./007-helm-store-cache.md)
aligning more with docker run, intermittently does pulls, avoiding the need to continually call `helm repo add`
8. [`helm search` becomes a server side query](./008-helm-search-server-query.md)
Further converging the local Helm store as a remote cache

## Background
Helm Charts evolved as a means to streamline and empower deployment of Kubernetes templates. Chart Museum evolved Helm Charts to provide a storage means for Charts. To maximize the ease for server side support, Chart Museum supported minimal storage requirements. Chart Museum can be stored directly in an S3 storage account. As cloud providers implement Helm Repositories, each are facing the same challenges providing charts at cloud-scale.

## Why Unify?

To be massively successful, Helm and Helm Repositories should appeal and be easily adopted by the masses. Docker has done a great job providing a progressive disclosure of complexity to the user, with a set of commands that most can grok.

The more things are different, the more difficult it is for users to adopt. Helm, Repositories even Kubernetes are the underlying infrastructure we hope all will use. But, we need to leave room for mental processing of concepts to all the other things developers and operational users need to account for.

By converging some of the underlying implementations, along with the commands, we can simplify the number of things users need to remember.

- `helm fetch` vs.
`docker pull`
- A **Helm Repo** is a collection of charts
- A **Helm Chart** has a collection of versions
- A **container repo** is a **single image**, with a **collection of versions** (tags)
- `docker run` will implicitly issue `docker pull` if the image doesn't exist
- `helm upgrade` requires a `helm fetch` first, or a `--repo` parameter that is different than a image


## Why should Helm change, when "it's better"?

We can certainly make the argument that several of the helm concepts, such as semantic versioning is far better than the open field of tags. And, some of those concepts are preserved, while still aligned with tags. However, Docker has a large installed base, which is only growing. Attempting to either change docker, or insist the changes are justified only increases friction to adoption.

## Involved Participants

As the goal is broad adoption, we are proposing this proposal be supported by all major clouds ([Azure](www.azure.com), [Google Cloud](https://cloud.google.com/) & [AWS](https://aws.amazon.com)) as well as container vendors, such as [Docker](https://www.docker.com), [Codefresh](https://codefresh.io), [JFrog](https://jfrog.com) and others...

## Proposed Timeline

Helm 3.0 is entering final design phases. Given the growth and quick adoption, with the significance of changes, it's proposed these changes are incorporated into Helm 3.0.