-
Notifications
You must be signed in to change notification settings - Fork 9
Draft about tagging strategy #7
base: master
Are you sure you want to change the base?
Changes from 3 commits
bf0b026
9fc6d38
9add60e
7a5a601
4c690d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
# Containers Tagging Strategy | ||
|
||
| Field | Value | | ||
|:-------|:-----------| | ||
| Status | Draft | | ||
| Date | 2018-08-8 | | ||
|
||
## Introduction | ||
|
||
As SUSE starts delivering software shipped in containers accessible | ||
from the [SUSE container registry](https://registry.suse.de). Images within the | ||
registry are referenced by a name and a tag or digest. The digest | ||
is a sha256sum of the image binary (thus assumed to be a unique identifier | ||
of an image) and tags are a valid ASCII name (uppercase & lowercase, digits, | ||
dashes and underscores). | ||
|
||
Pulling from a registry with the docker client looks like: | ||
|
||
``` | ||
docker pull <registry-domain>/<name>:<tag> | ||
``` | ||
|
||
or | ||
|
||
``` | ||
docker pull <registry-domain>/<name>@<image-digest> | ||
``` | ||
|
||
SUSE already started to deliver some applications wrapped in containers. | ||
Initially the containers have been delivered wrapped into RPM package, but now | ||
containers will be delivered using the SUSE container registry. | ||
|
||
Making an analogy with applications delivered with RPMs, the SUSE container | ||
registry can be seen as the online rpm repositories, the name as the package | ||
name and tags as package versions. | ||
|
||
Tags are just text identifiers of an image, they aren't meant to be comparable | ||
or ordered. Assuming tags can just work as versions do for packages is just | ||
inaccurate. Containers in the registry have no versions neither releases, they | ||
only have tags, text identifiers. Relevant to note that each image in the | ||
repository can be referenced by multiple tags. | ||
|
||
Also a complete refefence (`<registry-domain>/<name>:<tag>`) always | ||
points to a unique image. | ||
|
||
## Problem description | ||
|
||
Kubernetes pulls the images referenced in the Kubernetes manifest. Kubernetes | ||
checks if those images are available locally and if not pulls them from the | ||
registry. It means that if an image reference is overwritten with the same | ||
reference Kubernetes will not pull it again and then images of a running | ||
cluster start to diverge from the images available inside the registry. | ||
|
||
The above situation could be specially tricky when, for instance, new nodes are | ||
added to a cluster that is running silently with outdated images. This is | ||
particularly tricky because it can easily end up in a situation where the | ||
cluster is running multiple versions of the same image. Let's imagine the | ||
cluster was running some outdated mariadb image, then when a new node is added | ||
and this node pulls the images from the registry (including the mariadb one) | ||
it will pull and run different versions of the images without noticing it. | ||
Running a cluster with multiple mariadb versions without control or being | ||
enforced by the administrator is clearly dangerous and painful to debug if it | ||
causes some issue at some point. | ||
|
||
The tagging strategy of the delivered images must be aligned with the build and | ||
update workflow. Otherwise it is pretty simple to end up in similar situations | ||
as exposed above. | ||
|
||
## Current situation | ||
|
||
Before SUSE container registry images have been and are being delivered wrapped | ||
in RPMs. This way the update and delivery worklfow is the same as any other | ||
packages. However within the containers ecosystem this presents some issues: | ||
|
||
* Containers ecosystems based on Kubernetes are not designed to interact with | ||
RPM repositories but container registries. | ||
|
||
* Installing, updating and uninstalling RPMs can be costly. In CaaSP it | ||
requires a transactional update. | ||
|
||
* Using RPMS requires additional services to handle images upload into docker | ||
or crio daemons. See container-feeder tool or sle2docker. While systems like | ||
Kubernetes are already prepared to pull and load images from a registry. | ||
|
||
* Big downloads, RPMs do not benefit from layers reuse. RPMs contain all | ||
container layers even only unique layers are finally loaded into the daemon. | ||
|
||
In this context stable tags for references are being used. For CaaSP images are | ||
tagged with a fixed tag (usually the version of the main containerized | ||
application) defined in the kiwi file description and not modified during | ||
updates, however the RPM includes a metadata file used by the container-feeder. | ||
At loading time container-feeder re-tags the image with the '<tag>-<release>' | ||
and 'latest' tags, this way, even using stable tags in manifests the images | ||
are locally tagged with multiple tags, including the specific release tight to | ||
an RPM and image build. | ||
|
||
## Proposed change | ||
|
||
Introduce an app or service to track updates in the registry, something similar | ||
as what zypper does for RPMs and repositories. This is a key point and the | ||
proposed strategy here assumes there is going to be something like that | ||
available. | ||
|
||
The proposed change mimics the tagging strategy exposed above when using images | ||
wrapped in RPMs, but using the SUSE container registry and OBS instead. | ||
|
||
`kiwi` and `skopeo` tools can build images with multiple tags (since versions | ||
9.15.3 and 1.30.0 respectively). Thus the main idea is to keep using stable | ||
tags to facilitate image references in manifests but also tag images in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Currently, we don't reference "stable" tags - we reference the most specific tag available (i.e. the one that includes the build service's build number). Otherwise, we would have hit the problem you described above :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I was not aware that there was a manifest rebuild for each image rebuild, I did not see this part of the chain... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not baked into the build service, it's currently happening on boot: https://github.com/kubic-project/caasp-container-manifests/blob/master/admin-node-setup.sh#L12-L45 (and, on boot works only because they are currently RPMs and tx-update means a reboot) |
||
registry with additional dynamic tags, based on included packages versions or | ||
image release numbers. This way we could have in the registry multiple images | ||
with a meaningful tags pointing to a specific version, but also a stable tag | ||
pointing to the latest version of an image. | ||
|
||
Imagine there is a mariadb image tagged as below in the registry (emulating | ||
`docker images` output): | ||
|
||
``` | ||
REPOSITORY TAG IMAGE ID | ||
caasp/mariadb 10.2 1ade07d13d13 | ||
caasp/mariadb latest 1ade07d13d13 | ||
caasp/mariadb 10.2.15-3.2 1ade07d13d13 | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks perfect to me, where CaaSP manifests would reference the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I was suggesting to use |
||
|
||
Note that the build ID is being used as the release number. Build ID are | ||
the build numbers currently included in the resulting files of KIWI build | ||
within the build service. | ||
|
||
All three tags pointing to the same image. Then if a new update due to a new | ||
mariadb release happens adding the new image could look like that: | ||
|
||
``` | ||
REPOSITORY TAG IMAGE ID | ||
caasp/mariadb 10.2 70b5d81549ec | ||
caasp/mariadb latest 70b5d81549ec | ||
caasp/mariadb 10.2.15-3.2 1ade07d13d13 | ||
caasp/mariadb 10.2.15-3.3 70b5d81549ec | ||
``` | ||
|
||
Note that old image would be still accessible with the concrete version tight | ||
to the specific version and release. Again, if a new update happens but this | ||
time due to a new mariadb version adding a third image into the registry could | ||
result in: | ||
|
||
``` | ||
REPOSITORY TAG IMAGE ID | ||
caasp/mariadb 10.2 70b5d81549ec | ||
caasp/mariadb latest 284549eacf84 | ||
caasp/mariadb 10.2.15-3.2 1ade07d13d13 | ||
caasp/mariadb 10.2.15-3.3 70b5d81549ec | ||
caasp/mariadb 10.3 284549eacf84 | ||
caasp/mariadb 10.3.1-3.4 284549eacf84 | ||
``` | ||
|
||
Aging all three image versions are accessible and there is a stable reference | ||
to get the latest. However this time, since the mariadb version changed, there | ||
is also version tag to get the latest release of an specific version. | ||
|
||
To get to this sort of tagging strategy some modifications are required in our | ||
workflow and toolchain. | ||
|
||
* Need correct versions of KIWI and skopeo in relevant streams (mostly SLE 15) | ||
With it the stable tags could be already defined ('latest' and '10.3' of the | ||
above example) | ||
|
||
* Need OBS to add/modify tags at build time using the KIWI command call to | ||
append the build ID and/or release numbers. Currently the tag can be modified | ||
at call time in KIWI with the `--set-container-tag`. Probably this can be | ||
used to append release numbers to a tag. | ||
|
||
* Need OBS to push to the registry the image with all the tags included within | ||
the built binary. | ||
|
||
* SUSE requires some tool to track changes in the registry and be capable to | ||
detect when updates are available. | ||
|
||
Tagging an image with the main package version it can be achieved by using the | ||
`obs-service-replace_using_package_version` service. This is currently being | ||
used in Head project in IBS & OBS. | ||
|
||
One of the advantages of using this strategy is that it does not necessarily | ||
require a Kubernetes manifest update for each image update. The manifest could | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without a manifest update, Kubernetes won't restart running containers with the new build of the image - I don't believe we can get away from doing this without hitting the problem you described above. |
||
be set to some stable mariadb version (e.g. 10.2) and still be updated if the | ||
image requires a rebuild due some security fixes in the SLE base image or even | ||
in mariadb itself. In addition, Kubernetes manifests can be configured with | ||
the [imagePullPolicy="Always"](https://kubernetes.io/docs/concepts/containers/) | ||
to make sure Kubelet always pulls de image from the registry regardless if it | ||
was already pulled or not. This way Kubelet is always asking for the latest | ||
image for a given tag. | ||
|
||
Finally, using this approach, will be simple to clearly identify a local image | ||
running in a cluster as all supported images will always be in the registry | ||
tagged at least with a complete version and release numbers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the internal registry, the final one is going to be
registry.suse.com
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I know, just added it here because this link is browsable from SUSE network. We can remove the link if this is confusing. The registry.suse.com to me leads to a
Connection refused
errorThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kubic-project - so maybe use registry.opensuse.org?