Как определить объемы на уровне конвейера в конвейерах 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.

Другие вопросы по тегам