Как определить объемы на уровне конвейера в конвейерах kubeflow для совместного использования между компонентами?
Kubernetes В учебнике по взаимодействию между контейнерами определяется следующий конвейерный yaml:
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes: <--- This is what I need
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
Обратите внимание, что volumes
ключ определяется в spec
, и, таким образом, объем доступен для всех определенных контейнеров. Я хочу добиться того же поведения с помощью kfp, API для конвейеров kubeflow.
Однако я могу добавлять тома только к отдельным контейнерам, но не ко всей спецификации рабочего процесса, используя kfp.dsl.ContainerOp.container.add_volume_mount
это указывает на ранее созданный том (kfp.dsl.PipelineVolume), потому что объем, кажется, определен только внутри контейнера.
Вот что я пробовал, но объем всегда определяется в первом контейнере, а не на "глобальном" уровне. Как мне сделать так, чтобыop2
есть доступ к объему? Я ожидал, что он будет внутри kfp.dsl.PipelineConf, но к нему нельзя добавлять тома. Это просто не реализовано?
import kubernetes as k8s
from kfp import compiler, dsl
from kubernetes.client import V1VolumeMount
import pprint
@dsl.pipeline(name="debug", description="Debug only pipeline")
def pipeline_func():
op = dsl.ContainerOp(
name='echo',
image='library/bash:4.4.23',
command=['sh', '-c'],
arguments=['echo "[1,2,3]"> /tmp/output1.txt'],
file_outputs={'output': '/tmp/output1.txt'})
op2 = dsl.ContainerOp(
name='echo2',
image='library/bash:4.4.23',
command=['sh', '-c'],
arguments=['echo "[4,5,6]">> /tmp/output1.txt'],
file_outputs={'output': '/tmp/output1.txt'})
mount_folder = "/tmp"
volume = dsl.PipelineVolume(volume=k8s.client.V1Volume(
name=f"test-storage",
empty_dir=k8s.client.V1EmptyDirVolumeSource()))
op.add_pvolumes({mount_folder: volume})
op2.container.add_volume_mount(volume_mount=V1VolumeMount(mount_path=mount_folder,
name=volume.name))
op2.after(op)
workflow = compiler.Compiler().create_workflow(pipeline_func=pipeline_func)
pprint.pprint(workflow["spec"])
0 ответов
Возможно, вы захотите проверить разницу между подами и контейнерами Kubernetes. В опубликованном вами примере Kubernetes показан модуль с двумя контейнерами. Вы можете воссоздать тот же пример в KFP, добавив дополнительный контейнер в созданный экземпляр ContainerOp. Во втором примере создаются два модуля из одного контейнера, которые не видят друг друга по дизайну.
Для обмена данными между модулями вам понадобится реальный объем, а не emptyDir, который работает только для контейнера, являющегося одним модулем.
volume = dsl.PipelineVolume(volume=k8s.client.V1Volume( name=f"test-storage", empty_dir=k8s.client.V1EmptyDirVolumeSource())) op.add_pvolumes({mount_folder: volume})
Пожалуйста, не используйте dsl.PipelineVolume или op.add_pvolume, если вы не знаете, что это такое и зачем вам это нужно. Просто используйте нормально
op.add_volume
и
op.container.add_volume_mount
.
Тем не менее, есть ли особая причина, по которой вам нужно использовать тома? Объемы делают трубопроводы и компоненты непереносными. Никакие сторонние компоненты не используют тома.
Команда KFP рекомендует пользователям использовать обычные методы передачи данных: не Python, Python.