github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/adr/0007-use-rust-binary-for-both-injection-stages.md (about) 1 # 7. Use Rust Binary for Both Injection Stages 2 3 Date: 2022-10-29 4 5 ## Status 6 7 Accepted 8 9 Amends [3. Image injection into remote clusters without native support](0003-image-injection-into-remote-clusters-without-native-support.md) 10 11 ## Context 12 13 In ADR 3, the decision was made to create a rust binary (`stage1`) that would re-assemble a `registry:2` image and a go registry binary (`stage2`) from a series of configmaps. While this solution works, it is overkill for the operations that `stage2` performs. The `stage2` binary is only responsible for 1. starting a docker registry in `rw` mode, 2. pushing the `registry:2` crane tarball into said registry, 3. starting the docker registry in `r` mode. This `registry:2` image is then immedietely consumed by the `jackal-registry` package, creating a true in-cluster docker registry. The injector pod is then destroyed. The overhead this operation creates: 14 15 - having to keep track of another binary (making the total number 3 for the jackal ecosystem) 16 - nearly doubling the amount of configmaps loaded into the cluster (makes init slower) 17 - having to compile the binary for each platform (adds to the build time + ci) 18 - using a full-featured docker registry to host a single image (wasteful) 19 20 ## Decision 21 22 The rust binary is already being injected via configmap and unpacking the tarball. There is little need to bring everything but the kitchen sink to just serve a single image. Therefore the decision is to use the rust binary to perform the entire injection process. This required a few changes to the rust binary: 23 24 - not only re-assemble + unpack the tarball, but also unpack the `registry:2` image (stored as a [crane tarball format](https://github.com/google/go-containerregistry/tree/main/pkg/v1/tarball)) 25 - transform the `registry:2` crane manifest to a docker v2 manifest 26 - spin up an HTTP server compliant with the v2 docker registry API to serve the `registry:2` image 27 28 ## Consequences 29 30 The removal of the `stage2` binary makes the build process much simpler, and cuts down on make targets, as well as considerations needed during the build process. Additionally, the init process is faster, as the `stage2` binary is not injected anymore and the `registry:2` image is directly served instead of being pushed to an ephemeral registry, then served. There is a current risk to the new size of the `stage1` binary. Using stable compiler optimizations, the smallest it is able to come to is 868kb. While successfully tested on `k3s`, `kind`, and `k3d`, it is possible that the binary is too large for some Kubernetes distros (due to the potential interpretation of the configmap size limit). Additionally, the docker API implementation only serves a v2 manifest (most likely OCI in a future iteration) / image pull flow. This also greatly increases the lines of rust code and logic used within this repo, and future changes to this code will require more rust knowledge and experience, especially understanding the docker registry API and docker manifest formats.