Skip to content

Commit 6b9ad4a

Browse files
authored
Merge pull request #46960 from saschagrunert/oci-volumesource-blog
Blog post about OCI volume sources / KEP-4639
2 parents 9266fbb + 969c669 commit 6b9ad4a

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
---
2+
layout: blog
3+
title: "Kubernetes 1.31: Read Only Volumes Based On OCI Artifacts (alpha)"
4+
date: 2024-08-16
5+
slug: kubernetes-1-31-image-volume-source
6+
author: Sascha Grunert
7+
---
8+
9+
The Kubernetes community is moving towards fulfilling more Artificial
10+
Intelligence (AI) and Machine Learning (ML) use cases in the future. While the
11+
project has been designed to fulfill microservice architectures in the past,
12+
it’s now time to listen to the end users and introduce features which have a
13+
stronger focus on AI/ML.
14+
15+
One of these requirements is to support [Open Container Initiative (OCI)](https://opencontainers.org)
16+
compatible images and artifacts (referred as OCI objects) directly as a native
17+
volume source. This allows users to focus on OCI standards as well as enables
18+
them to store and distribute any content using OCI registries. A feature like
19+
this gives the Kubernetes project a chance to grow into use cases which go
20+
beyond running particular images.
21+
22+
Given that, the Kubernetes community is proud to present a new alpha feature
23+
introduced in v1.31: The Image Volume Source
24+
([KEP-4639](https://kep.k8s.io/4639)). This feature allows users to specify an
25+
image reference as volume in a pod while reusing it as volume mount within
26+
containers:
27+
28+
```yaml
29+
30+
kind: Pod
31+
spec:
32+
containers:
33+
-
34+
volumeMounts:
35+
- name: my-volume
36+
mountPath: /path/to/directory
37+
volumes:
38+
- name: my-volume
39+
image:
40+
reference: my-image:tag
41+
```
42+
43+
The above example would result in mounting `my-image:tag` to
44+
`/path/to/directory` in the pod’s container.
45+
46+
## Use cases
47+
48+
The goal of this enhancement is to stick as close as possible to the existing
49+
[container image](/docs/concepts/containers/images/) implementation within the
50+
kubelet, while introducing a new API surface to allow more extended use cases.
51+
52+
For example, users could share a configuration file among multiple containers in
53+
a pod without including the file in the main image, so that they can minimize
54+
security risks and the overall image size. They can also package and distribute
55+
binary artifacts using OCI images and mount them directly into Kubernetes pods,
56+
so that they can streamline their CI/CD pipeline as an example.
57+
58+
Data scientists, MLOps engineers, or AI developers, can mount large language
59+
model weights or machine learning model weights in a pod alongside a
60+
model-server, so that they can efficiently serve them without including them in
61+
the model-server container image. They can package these in an OCI object to
62+
take advantage of OCI distribution and ensure efficient model deployment. This
63+
allows them to separate the model specifications/content from the executables
64+
that process them.
65+
66+
Another use case is that security engineers can use a public image for a malware
67+
scanner and mount in a volume of private (commercial) malware signatures, so
68+
that they can load those signatures without baking their own combined image
69+
(which might not be allowed by the copyright on the public image). Those files
70+
work regardless of the OS or version of the scanner software.
71+
72+
But in the long term it will be up to **you** as an end user of this project to
73+
outline further important use cases for the new feature.
74+
[SIG Node](https://github.com/kubernetes/community/blob/54a67f5/sig-node/README.md)
75+
is happy to retrieve any feedback or suggestions for further enhancements to
76+
allow more advanced usage scenarios. Feel free to provide feedback by either
77+
using the [Kubernetes Slack (#sig-node)](https://kubernetes.slack.com/messages/sig-node)
78+
channel or the [SIG Node mailinglist](https://groups.google.com/g/kubernetes-sig-node).
79+
80+
## Detailed example {#example}
81+
82+
The Kubernetes alpha feature gate [`ImageVolume`](/docs/reference/command-line-tools-reference/feature-gates)
83+
needs to be enabled on the [API Server](/docs/reference/command-line-tools-reference/kube-apiserver)
84+
as well as the [kubelet](/docs/reference/command-line-tools-reference/kubelet)
85+
to make it functional. If that’s the case and the [container runtime](/docs/setup/production-environment/container-runtimes)
86+
has support for the feature (like CRI-O ≥ v1.31), then an example `pod.yaml`
87+
like this can be created:
88+
89+
```yaml
90+
apiVersion: v1
91+
kind: Pod
92+
metadata:
93+
name: pod
94+
spec:
95+
containers:
96+
- name: test
97+
image: registry.k8s.io/e2e-test-images/echoserver:2.3
98+
volumeMounts:
99+
- name: volume
100+
mountPath: /volume
101+
volumes:
102+
- name: volume
103+
image:
104+
reference: quay.io/crio/artifact:v1
105+
pullPolicy: IfNotPresent
106+
```
107+
108+
The pod declares a new volume using the `image.reference` of
109+
`quay.io/crio/artifact:v1`, which refers to an OCI object containing two files.
110+
The `pullPolicy` behaves in the same way as for container images and allows the
111+
following values:
112+
113+
- `Always`: the kubelet always attempts to pull the reference and the container
114+
creation will fail if the pull fails.
115+
- `Never`: the kubelet never pulls the reference and only uses a local image or
116+
artifact. The container creation will fail if the reference isn’t present.
117+
- `IfNotPresent`: the kubelet pulls if the reference isn’t already present on
118+
disk. The container creation will fail if the reference isn’t present and the
119+
pull fails.
120+
121+
The `volumeMounts` field is indicating that the container with the name `test`
122+
should mount the volume under the path `/volume`.
123+
124+
If you now create the pod:
125+
126+
```shell
127+
kubectl apply -f pod.yaml
128+
```
129+
130+
And exec into it:
131+
132+
```shell
133+
kubectl exec -it pod -- sh
134+
```
135+
136+
Then you’re able to investigate what has been mounted:
137+
138+
```console
139+
/ # ls /volume
140+
dir file
141+
/ # cat /volume/file
142+
2
143+
/ # ls /volume/dir
144+
file
145+
/ # cat /volume/dir/file
146+
1
147+
```
148+
149+
**You managed to consume an OCI artifact using Kubernetes!**
150+
151+
The container runtime pulls the image (or artifact), mounts it to the
152+
container and makes it finally available for direct usage. There are a bunch of
153+
details in the implementation, which closely align to the existing image pull
154+
behavior of the kubelet. For example:
155+
156+
- If a `:latest` tag as `reference` is provided, then the `pullPolicy` will
157+
default to `Always`, while in any other case it will default to `IfNotPresent`
158+
if unset.
159+
- The volume gets re-resolved if the pod gets deleted and recreated, which means
160+
that new remote content will become available on pod recreation. A failure to
161+
resolve or pull the image during pod startup will block containers from
162+
starting and may add significant latency. Failures will be retried using
163+
normal volume backoff and will be reported on the pod reason and message.
164+
- Pull secrets will be assembled in the same way as for the container image by
165+
looking up node credentials, service account image pull secrets, and pod spec
166+
image pull secrets.
167+
- The OCI object gets mounted in a single directory by merging the manifest
168+
layers in the same way as for container images.
169+
- The volume is mounted as read-only (`ro`) and non-executable files
170+
(`noexec`).
171+
- Sub-path mounts for containers are not supported
172+
(`spec.containers[*].volumeMounts.subpath`).
173+
- The field `spec.securityContext.fsGroupChangePolicy` has no effect on this
174+
volume type.
175+
- The feature will also work with the [`AlwaysPullImages` admission plugin](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)
176+
if enabled.
177+
178+
Thank you for reading through the end of this blog post! SIG Node is proud and
179+
happy to deliver this feature as part of Kubernetes v1.31.
180+
181+
As writer of this blog post, I would like to emphasize my special thanks to
182+
**all** involved individuals out there! You all rock, let’s keep on hacking!
183+
184+
## Further reading
185+
186+
- [Use an Image Volume With a Pod](/docs/tasks/configure-pod-container/image-volumes)
187+
- [`image` volume overview](/docs/concepts/storage/volumes/#image)

0 commit comments

Comments
 (0)