From f33f2d09f73651cac7d633422438d0fe1b782e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Tue, 6 Aug 2024 12:43:19 +0200 Subject: [PATCH] runtime: image-pull: Make it work with nerdctl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our code for handling images being pulled inside the guest relies on a containerType ("sandbox" or "container") being set as part of the container annotations, which is done by the CRI Engine being used, and depending on the used CRI Engine we check for a specfic annotation related to the image-name, which is then passed to the agent. However, when running kata-containers without kubernetes, specifically when using `nerdctl`, none of those annotations are set at all. One thing that we can do to allow folks to use `nerdctl`, however, is to take advantage of the `--label` flag, and document on our side that users must pass `io.kubernetes.cri.image-name=$image_name` as part of the label. By doing this, and changing our "fallback" so we can always look for such annotation, we ensure that nerdctl will work when using the nydus snapshotter, with kata-containers, to perform image pulling inside the pod sandbox / guest. Signed-off-by: Fabiano FidĂȘncio --- .../kata-guest-image-management-design.md | 7 +++++++ src/runtime/virtcontainers/kata_agent.go | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/design/kata-guest-image-management-design.md b/docs/design/kata-guest-image-management-design.md index 164698f2b..160cf5321 100644 --- a/docs/design/kata-guest-image-management-design.md +++ b/docs/design/kata-guest-image-management-design.md @@ -113,6 +113,13 @@ Next, the kata-agent's RPC module will handle the create container request which > **Notes:** > In this flow, `ImageService.pull_image()` parses the image metadata, looking for either the `io.kubernetes.cri.container-type: sandbox` or `io.kubernetes.cri-o.ContainerType: sandbox` (CRI-IO case) annotation, then it never calls the `image-rs.pull_image()` because the pause image is expected to already be inside the guest's filesystem, so instead `ImageService.unpack_pause_image()` is called. +## Using guest image pull with `nerdctl` + +When running a workload, add the `--label io.kubernetes.cri.image-name=` option e.g.: +```sh +nerdctl run --runtime io.containerd.kata.v2 --snapshotter nydus --label io.kubernetes.cri.image-name=docker.io/library/busybox:latest --rm docker.io/library/busybox:latest uname -r +``` + References: [1] [[RFC] Image management proposal for hosting sharing and peer pods](https://github.com/confidential-containers/confidential-containers/issues/137) [2] https://github.com/containerd/containerd/blob/main/docs/content-flow.md diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 9d4c59cf7..b56c3d7e0 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -1613,13 +1613,25 @@ func handleImageGuestPullBlockVolume(c *Container, virtualVolumeInfo *types.Kata if containerType == string(PodSandbox) { image_ref = "pause" } else { + const kubernetesCRIImageName = "io.kubernetes.cri.image-name" + const kubernetesCRIOImageName = "io.kubernetes.cri-o.ImageName" + switch criContainerType { case ctrAnnotations.ContainerType: - image_ref = container_annotations["io.kubernetes.cri.image-name"] + image_ref = container_annotations[kubernetesCRIImageName] case podmanAnnotations.ContainerType: - image_ref = container_annotations["io.kubernetes.cri-o.ImageName"] + image_ref = container_annotations[kubernetesCRIOImageName] default: - image_ref = "" + // There are cases, like when using nerdctl, where the criContainerType + // will never be set, leading to this code path. + // + // nerdctl also doesn't set any mechanism for automatically setting the + // image, but as part of it's v2.0.0 release it allows the user to set + // any kind of OCI annotation, which we can take advantage of and use. + // + // With this in mind, let's "fallback" to the default k8s cri image-name + // annotation, as documented on our image-pull documentation. + image_ref = container_annotations[kubernetesCRIImageName] } if image_ref == "" {