runtime: image-pull: Make it work with nerdctl

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 <fabiano.fidencio@intel.com>
This commit is contained in:
Fabiano Fidêncio 2024-08-06 12:43:19 +02:00
parent 43dca8deb4
commit f33f2d09f7
2 changed files with 22 additions and 3 deletions

View File

@ -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=<image>` 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

View File

@ -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 == "" {