Blog post about OCI volume sources / KEP-4639

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
pull/46960/head
Sascha Grunert 2024-06-25 09:27:26 +02:00
parent 947950c9d3
commit 969c669551
No known key found for this signature in database
GPG Key ID: 09D97D153EF94D93
1 changed files with 187 additions and 0 deletions

View File

@ -0,0 +1,187 @@
---
layout: blog
title: "Kubernetes 1.31: Read Only Volumes Based On OCI Artifacts (alpha)"
date: 2024-08-16
slug: kubernetes-1-31-image-volume-source
author: Sascha Grunert
---
The Kubernetes community is moving towards fulfilling more Artificial
Intelligence (AI) and Machine Learning (ML) use cases in the future. While the
project has been designed to fulfill microservice architectures in the past,
its now time to listen to the end users and introduce features which have a
stronger focus on AI/ML.
One of these requirements is to support [Open Container Initiative (OCI)](https://opencontainers.org)
compatible images and artifacts (referred as OCI objects) directly as a native
volume source. This allows users to focus on OCI standards as well as enables
them to store and distribute any content using OCI registries. A feature like
this gives the Kubernetes project a chance to grow into use cases which go
beyond running particular images.
Given that, the Kubernetes community is proud to present a new alpha feature
introduced in v1.31: The Image Volume Source
([KEP-4639](https://kep.k8s.io/4639)). This feature allows users to specify an
image reference as volume in a pod while reusing it as volume mount within
containers:
```yaml
kind: Pod
spec:
containers:
- …
volumeMounts:
- name: my-volume
mountPath: /path/to/directory
volumes:
- name: my-volume
image:
reference: my-image:tag
```
The above example would result in mounting `my-image:tag` to
`/path/to/directory` in the pods container.
## Use cases
The goal of this enhancement is to stick as close as possible to the existing
[container image](/docs/concepts/containers/images/) implementation within the
kubelet, while introducing a new API surface to allow more extended use cases.
For example, users could share a configuration file among multiple containers in
a pod without including the file in the main image, so that they can minimize
security risks and the overall image size. They can also package and distribute
binary artifacts using OCI images and mount them directly into Kubernetes pods,
so that they can streamline their CI/CD pipeline as an example.
Data scientists, MLOps engineers, or AI developers, can mount large language
model weights or machine learning model weights in a pod alongside a
model-server, so that they can efficiently serve them without including them in
the model-server container image. They can package these in an OCI object to
take advantage of OCI distribution and ensure efficient model deployment. This
allows them to separate the model specifications/content from the executables
that process them.
Another use case is that security engineers can use a public image for a malware
scanner and mount in a volume of private (commercial) malware signatures, so
that they can load those signatures without baking their own combined image
(which might not be allowed by the copyright on the public image). Those files
work regardless of the OS or version of the scanner software.
But in the long term it will be up to **you** as an end user of this project to
outline further important use cases for the new feature.
[SIG Node](https://github.com/kubernetes/community/blob/54a67f5/sig-node/README.md)
is happy to retrieve any feedback or suggestions for further enhancements to
allow more advanced usage scenarios. Feel free to provide feedback by either
using the [Kubernetes Slack (#sig-node)](https://kubernetes.slack.com/messages/sig-node)
channel or the [SIG Node mailinglist](https://groups.google.com/g/kubernetes-sig-node).
## Detailed example {#example}
The Kubernetes alpha feature gate [`ImageVolume`](/docs/reference/command-line-tools-reference/feature-gates)
needs to be enabled on the [API Server](/docs/reference/command-line-tools-reference/kube-apiserver)
as well as the [kubelet](/docs/reference/command-line-tools-reference/kubelet)
to make it functional. If thats the case and the [container runtime](/docs/setup/production-environment/container-runtimes)
has support for the feature (like CRI-O ≥ v1.31), then an example `pod.yaml`
like this can be created:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod
spec:
containers:
- name: test
image: registry.k8s.io/e2e-test-images/echoserver:2.3
volumeMounts:
- name: volume
mountPath: /volume
volumes:
- name: volume
image:
reference: quay.io/crio/artifact:v1
pullPolicy: IfNotPresent
```
The pod declares a new volume using the `image.reference` of
`quay.io/crio/artifact:v1`, which refers to an OCI object containing two files.
The `pullPolicy` behaves in the same way as for container images and allows the
following values:
- `Always`: the kubelet always attempts to pull the reference and the container
creation will fail if the pull fails.
- `Never`: the kubelet never pulls the reference and only uses a local image or
artifact. The container creation will fail if the reference isnt present.
- `IfNotPresent`: the kubelet pulls if the reference isnt already present on
disk. The container creation will fail if the reference isnt present and the
pull fails.
The `volumeMounts` field is indicating that the container with the name `test`
should mount the volume under the path `/volume`.
If you now create the pod:
```shell
kubectl apply -f pod.yaml
```
And exec into it:
```shell
kubectl exec -it pod -- sh
```
Then youre able to investigate what has been mounted:
```console
/ # ls /volume
dir file
/ # cat /volume/file
2
/ # ls /volume/dir
file
/ # cat /volume/dir/file
1
```
**You managed to consume an OCI artifact using Kubernetes!**
The container runtime pulls the image (or artifact), mounts it to the
container and makes it finally available for direct usage. There are a bunch of
details in the implementation, which closely align to the existing image pull
behavior of the kubelet. For example:
- If a `:latest` tag as `reference` is provided, then the `pullPolicy` will
default to `Always`, while in any other case it will default to `IfNotPresent`
if unset.
- The volume gets re-resolved if the pod gets deleted and recreated, which means
that new remote content will become available on pod recreation. A failure to
resolve or pull the image during pod startup will block containers from
starting and may add significant latency. Failures will be retried using
normal volume backoff and will be reported on the pod reason and message.
- Pull secrets will be assembled in the same way as for the container image by
looking up node credentials, service account image pull secrets, and pod spec
image pull secrets.
- The OCI object gets mounted in a single directory by merging the manifest
layers in the same way as for container images.
- The volume is mounted as read-only (`ro`) and non-executable files
(`noexec`).
- Sub-path mounts for containers are not supported
(`spec.containers[*].volumeMounts.subpath`).
- The field `spec.securityContext.fsGroupChangePolicy` has no effect on this
volume type.
- The feature will also work with the [`AlwaysPullImages` admission plugin](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)
if enabled.
Thank you for reading through the end of this blog post! SIG Node is proud and
happy to deliver this feature as part of Kubernetes v1.31.
As writer of this blog post, I would like to emphasize my special thanks to
**all** involved individuals out there! You all rock, lets keep on hacking!
## Further reading
- [Use an Image Volume With a Pod](/docs/tasks/configure-pod-container/image-volumes)
- [`image` volume overview](/docs/concepts/storage/volumes/#image)