Установка Kubeflow

Инструкция описывает установку Kubeflow в созданном клиентском кластере. Потребуется доступ к клиентскому кластеру, кластеру управления и хосту зеркала.

В результате в кластере будут развернуты:

  • Kubeflow — notebooks, pipelines, experiments, training jobs, serving (KServe внутри кластера), Katib, TensorBoard;
  • Ingress для доступа к Kubeflow по адресу kubeflow.<commonName> или Gateway на хост с IP Gateway.

Дополнительно: Внешний доступ к KServe.

Как работать с этой страницей

Шаг 1 выполняется в кластере управления: создание отдельного OIDC-клиента для Kubeflow. Не используйте OIDC-клиента других сервисов платформы.

Шаг 2 выполняется в клиентском кластере: SSP для Cilium, цепочка установки kubeflow-step-0 … kubeflow-step-4, проверка лейблов Istio. После шага 1 перейдите в клиентский кластер.

В конце каждой вкладки GUI и CLI указано, как проверить результат. Не переходите к следующему шагу, пока не получите ожидаемый результат проверки.

Внешний доступ к KServe на установку Kubeflow не влияет и описан отдельно: Внешний доступ к KServe.

Для шагов в клиентском кластере приведены вкладки GUI и CLI. Загрузка патчей в зеркало выполняется на хосте зеркала и только из консоли.

В GUI манифесты Kubernetes и кастомных ресурсов платформы загружаются через импорт манифестов: иконка импорта слева от имени пользователя → вставьте YAML → Проверить → Сохранить. Несколько объектов в одном файле разделяйте ---. Установка чартов: Как развернуть новый сервис.

Подставляйте свои значения вместо плейсхолдеров:

ПлейсхолдерОткуда взять
<commonName>status.appliedCustomValues.controller.shturval.commonName у SSC shturval-ingress-controller
<CLUSTER_NAME>имя клиентского кластера в кластере управления
<IP-Gateway>свободный IP из заранее созданного CiliumLoadBalancerIPPool. Нужен только для публикации через Gateway
<hostname-Gateway>хост Gateway Kubeflow. Это не commonName у shturval-ingress-controller: в FQDN должен быть IP именно Gateway. При автоматической схеме платформы: kubeflow.<CLUSTER_NAME>.ip-<IP-Gateway>.shturval.link, в IP точки замените на дефисы

Перед началом

Клиентский кластер уже установлен. Проверьте:

  • ShturvalUpdate shturval-update в неймспейсе shturval-update-system имеет .status.ready=true;
  • у SSC shturval-ingress-controller заполнен commonName — из него собирается хост kubeflow.<commonName>;
  • лицензия поддерживает Enterprise ML: Виды лицензии.

Для CLI-пути на рабочей машине администратора нужны kubectl и openssl. openssl потребуется, чтобы сгенерировать cookie_secret для oauth2-proxy Kubeflow и при HTTPS снять CA внешнего S3.

  1. Откройте клиентский кластер.
  2. Администрирование → Кастомные ресурсы → группа update.shturval.tech → ShturvalUpdate → объект shturval-update. В статусе должно быть ready: true.
  3. Сервисы и репозитории → Установленные сервисы → shturval-ingress-controller → Управлять → вкладка Манифест. Найдите controller.shturval.commonName и сохраните значение — это <commonName>.
export KUBECONFIG_CLIENT=<путь-к-kubeconfig-клиентского-кластера>

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get su -n shturval-update-system shturval-update \
  -o jsonpath='{.status.ready}{"\n"}'

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get ssc shturval-ingress-controller \
  -o jsonpath='{.status.appliedCustomValues.controller.shturval.commonName}{"\n"}'

Этот шаг выполняется на хосте зеркала, не в GUI кластера. Без него клиентский кластер не скачает Helm-чарты Kubeflow.

sudo -i
cd /opt/mirror

Примените архивы из комплекта поставки в этом порядке:

КомпонентЧто добавляет в зеркало
Kubeflow, архивы 1–4базовые чарты и образы Kubeflow
Kubeflow Helm patchобновления Helm-чартов Kubeflow
Kubeflow patchдополнительные исправления Kubeflow

Для каждого архива:

rm -rf shturval-patch && mkdir shturval-patch
wget <URL_архива_из_поставки> -O shturval-patch/<имя-файла>.tgz
./stm patch apply
rm -rf shturval-patch
Обратите внимание! URL архивов берите только из комплекта поставки. Не публикуйте внутренние ссылки на файловые серверы.

Эти значения понадобятся в манифестах следующих шагов.

ПараметрОбязателенНазначениеОткуда взятьГде используется
CERT_CLUSTER_ISSUERДаClusterIssuer для TLS точки входа Kubeflow. Обычно shturval-self-signedимя ClusterIssuer в клиентском кластере: Администрирование → ClusterIssuers. Если своего issuer нет, используйте shturval-self-signedшаг 2, TLS Ingress или Gateway Kubeflow
cookie_secretДадля oauth2-proxy Kubeflowсгенерируйте командой openssl rand -hex 16шаг 2, kubeflow-step-1

Выберите хранилища Kubeflow Pipelines и Katib

Kubeflow Pipelines использует один экземпляр MySQL и одно объектное хранилище для всего кластера — это ограничение исходного проекта Kubeflow. Общая учётная запись KFP UI должна иметь доступ к бакетам всех профилей. Katib хранит метаданные экспериментов в отдельной базе MySQL, которую можно разместить на том же сервере. KFP поддерживает MySQL, но не PostgreSQL.

Обратите внимание! Объектное хранилище должно поддерживать AWS IAM API (создание пользователей и политик), а не только операции S3 вроде PutObject/GetObject. Контроллер профилей Pipelines (sync.py) создаёт IAM-пользователя и policy на каждый Profile. Upstream Kubeflow ориентирован на SeaweedFS. Обычный «S3-compatible» без IAM (часть реализаций Ceph RGW, MinIO без IAM) не подойдёт.

Подготовьте значения внешних MySQL и S3, которые понадобятся на шаге 2:

ПараметрНазначениеГде используется
KFP_MYSQL_HOST / KFP_MYSQL_PORTадрес внешнего MySQL для Pipelinesшаг 2, kubeflow-step-2
KFP_MYSQL_PIPELINE_DB / KFP_MYSQL_METADATA_DBдве базы: pipelines и metadataшаг 2, kubeflow-step-2
KFP_MYSQL_USER / KFP_MYSQL_PASSWORDучётная запись MySQLшаг 2, kubeflow-step-2
KFP_S3_ENDPOINTURL объектного хранилища (со схемой https:// или http://). При HTTPS с эндпойнта снимается CA и передаётся в s3.caCert чарта step-2шаг 2, kubeflow-step-2
KFP_AWS_IAM_ENDPOINTendpoint AWS IAM API того же хранилища: sync.py создаёт per-profile пользователей и policyшаг 2, kubeflow-step-2
KFP_AWS_REGION / KFP_S3_BUCKETрегион и bucket артефактовшаг 2, kubeflow-step-2
KFP_AWS_ACCESS_KEY / KFP_AWS_SECRET_KEYглобальные ключи для KFP UI и controllerшаг 2, kubeflow-step-2
KATIB_MYSQL_HOST / KATIB_MYSQL_PORT / KATIB_MYSQL_DBвнешняя MySQL для Katibшаг 2, kubeflow-step-3
KATIB_MYSQL_USER / KATIB_MYSQL_PASSWORDучётная запись Katibшаг 2, kubeflow-step-3
KATIB_MYSQL_SECRET_NAMEимя Secret с credentials Katib, по умолчанию katib-mysql-secretsшаг 2, kubeflow-step-3

Шаг 1. В кластере управления создайте OIDC-клиент для Kubeflow

OIDC-клиент нужен для доступа в Kubeflow через SSO платформы. Ресурс создаётся в кластере управления, в неймспейсе с именем клиентского кластера.

Клиент должен принимать redirect URI точки входа: для Ingress — kubeflow.<commonName>, для Gateway — <hostname-Gateway>. При providerType: shturval платформа формирует клиента внутреннего провайдера.

  1. Откройте кластер управления.
  2. Импортируйте манифест, использовав свои значения параметров:
apiVersion: auth.shturval.tech/v1beta1
kind: AuthOidcClient
metadata:
  name: <CLUSTER_NAME>-kubeflow
  namespace: <CLUSTER_NAME>
spec:
  providerType: shturval

Либо создайте объект в Администрирование → Кастомные ресурсы → API-группа auth.shturval.tech → AuthOidcClient → + Добавить.

  1. Дождитесь, пока в статусе объекта появится ready: true, заполнятся status.clientInfo.issuerUrl и status.clientSecretRef.
  2. Перейдите в неймспейс <CLUSTER_NAME> и откройте Secret из clientSecretRef (имя вида <CLUSTER_NAME>-kubeflow-<случайный-суффикс>). Скопируйте client_id и client_secret.
  3. Сохраните issuer URL из статуса AuthOidcClient — это OIDC_ISSUER_URL.
export KUBECONFIG_MGMT=<путь-к-kubeconfig-кластера-управления>
export CLUSTER_NAME=<имя-клиентского-кластера>

kubectl --kubeconfig "${KUBECONFIG_MGMT}" apply -f - <<EOF
apiVersion: auth.shturval.tech/v1beta1
kind: AuthOidcClient
metadata:
  name: ${CLUSTER_NAME}-kubeflow
  namespace: ${CLUSTER_NAME}
spec:
  providerType: shturval
EOF

Дождитесь готовности (до ~180 с):

kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get authoidcclient "${CLUSTER_NAME}-kubeflow" -n "${CLUSTER_NAME}" \
  -o jsonpath='{.status.ready}{"\n"}'

Извлеките параметры:

SECRET_NAME="$(kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get authoidcclient "${CLUSTER_NAME}-kubeflow" -n "${CLUSTER_NAME}" \
  -o jsonpath='{.status.clientSecretRef.name}')"

SECRET_NS="$(kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get authoidcclient "${CLUSTER_NAME}-kubeflow" -n "${CLUSTER_NAME}" \
  -o jsonpath='{.status.clientSecretRef.namespace}')"

export OIDC_CLIENT_ID="$(kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get secret "${SECRET_NAME}" -n "${SECRET_NS}" \
  -o jsonpath='{.data.client_id}' | base64 -d)"

export OIDC_CLIENT_SECRET="$(kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get secret "${SECRET_NAME}" -n "${SECRET_NS}" \
  -o jsonpath='{.data.client_secret}' | base64 -d)"

export OIDC_ISSUER_URL="$(kubectl --kubeconfig "${KUBECONFIG_MGMT}" \
  get authoidcclient "${CLUSTER_NAME}-kubeflow" -n "${CLUSTER_NAME}" \
  -o jsonpath='{.status.clientInfo.issuerUrl}')"
ПараметрНазначениеОткуда взятьГде используется
OIDC_CLIENT_IDидентификатор OIDC-клиента KubeflowSecret из status.clientSecretRef у AuthOidcClient <CLUSTER_NAME>-kubeflow в неймспейсе <CLUSTER_NAME>: ключ client_idшаг 2, kubeflow-step-1
OIDC_CLIENT_SECRETсекрет OIDC-клиента Kubeflowтот же Secret: ключ client_secretшаг 2, kubeflow-step-1
OIDC_ISSUER_URLURL платформыстатус AuthOidcClient: status.clientInfo.issuerUrlшаг 2, kubeflow-step-1

Шаг 2. Установите Kubeflow

Обратите внимание! Все действия этого шага — в клиентском кластере. Только OIDC-клиент на шаге 1 создается в кластере управления, далее все в клиентском.

Kubeflow устанавливается с помощью SSC kubeflow-step-0 — kubeflow-step-4. Все пять сервисов можно создать одновременно в режиме Авто: зависимости обеспечат последовательную установку. В спецификации каждого сервиса укажите предыдущий шаг в spec.dependency. Дождитесь, когда все SSC перейдут в состояние Healthy.

Дополнительно примените SSP shturval-networking-for-istio для shturval-networking (Cilium). Kubeflow работает через Istio: в поды добавляется sidecar, который сам ведёт сеть пода. Cilium по умолчанию считает себя единственным сетевым плагином на узле и может перехватывать тот же трафик. Конфигурация SSP разрешает Cilium сосуществовать с sidecar Istio и оставляет socket-балансировку Cilium только на хосте, не внутри подов.

После установки интерфейс доступен по HTTPS. Способ публикации задаётся в customvalues kubeflow-step-2: Ingress (nginx) на https://kubeflow.<commonName>/ или Gateway API (Cilium) на https://<hostname-Gateway>/. Внутри трафик уходит в istio-ingressgateway. DNS должен указывать на адрес точки входа: для Ingress — IP Ingress кластера и хост kubeflow.<commonName>, для Gateway — <IP-Gateway> и хост <hostname-Gateway>.

2.1. ShturvalServicePatch для Cilium

  1. Перейдите в клиентский кластер.
  2. Импортируйте SSP:
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServicePatch
metadata:
  name: shturval-networking-for-istio
spec:
  patchOrder: 100
  customvalues:
    socketLB:
      hostNamespaceOnly: true
    cni:
      exclusive: false
  shturvalServiceConfigName: shturval-networking

Проверить применение ShturvalServicePatch: Установленные сервисы → shturval-networking → вкладка ShturvalServicePatch.

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" apply -f - <<'EOF'
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServicePatch
metadata:
  name: shturval-networking-for-istio
spec:
  patchOrder: 100
  customvalues:
    socketLB:
      hostNamespaceOnly: true
    cni:
      exclusive: false
  shturvalServiceConfigName: shturval-networking
EOF

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get shturvalservicepatch shturval-networking-for-istio

2.2. Установка Kubeflow

Репозиторий shturval, неймспейс default для всех сервисов. Имена экземпляров должны совпадать с именами чартов: kubeflow-step-0 … kubeflow-step-4.

В kubeflow-step-2 выберите способ публикации: вкладка Ingress или Gateway. Для Gateway до установки kubeflow-step-2 создайте CiliumLoadBalancerIPPool со свободным IP — чарт сам Gateway не выделяет адрес из чужого пула. Контроллер Gateway API в Cilium должен быть включён: Как включить контроллер Gateway API в Cilium.

  1. Сервисы и репозитории → Доступные чарты, репозиторий shturval. Действия в клиентском кластере.
  2. Установите kubeflow-step-0: неймспейс default, режим Авто. Customvalues не нужны. Это базовые CRD.
  3. Установите kubeflow-step-1 (Dex и oauth2-proxy). Зависимость: kubeflow-step-0. Режим Авто. В спецификации укажите OIDC-параметры с шага 1 и cookie_secret из раздела «Подготовьте параметры»:
dex:
  oidc:
    client_id: "<OIDC_CLIENT_ID>"
    client_secret: "<OIDC_CLIENT_SECRET>"
oauth2-proxy:
  oauth2Cfg:
    oidc_issuer_url: "<OIDC_ISSUER_URL>"
    redirect_url: https://kubeflow.<commonName>/oauth2/callback
  oidc:
    client_id: "<OIDC_CLIENT_ID>"
    client_secret: "<OIDC_CLIENT_SECRET>"
    cookie_secret: "<cookie_secret>"

Для Gateway в redirect_url укажите https://<hostname-Gateway>/oauth2/callback, не kubeflow.<commonName>.

  1. Установите kubeflow-step-2 (Pipelines, хранилища и точка входа). Зависимость: kubeflow-step-1. Режим Авто. В спецификации укажите внешние MySQL и S3 с поддержкой AWS IAM, поле serviceName оставьте пустым. Блок точки входа — по вкладке вашего кластера.

Если S3 работает по HTTP, оставьте s3.caCert пустым. Если по HTTPS, вставьте PEM корневого сертификата.

platform-agnostic-mutli-user:
  seaweedfs:
    enabled: false
  mysql:
    enabled: false
    external:
      host: "<KFP_MYSQL_HOST>"
      port: <KFP_MYSQL_PORT>
      pipelineDatabase: "<KFP_MYSQL_PIPELINE_DB>"
      metadataDatabase: "<KFP_MYSQL_METADATA_DB>"
      username: "<KFP_MYSQL_USER>"
      password: "<KFP_MYSQL_PASSWORD>"
      serviceName: ""
  pipelinesProfileController:
    env:
      awsEndpointUrl: "<KFP_AWS_IAM_ENDPOINT>"
      s3EndpointUrl: "<KFP_S3_ENDPOINT>"
      awsRegion: "<KFP_AWS_REGION>"
      s3Bucket: "<KFP_S3_BUCKET>"
    awsCredentials:
      accessKeyValue: "<KFP_AWS_ACCESS_KEY>"
      secretKeyValue: "<KFP_AWS_SECRET_KEY>"
  s3:
    caCert: "<PEM-сертификат-CA-если-S3-по-HTTPS>"
  ingress:
    enabled: true
    annotations:
      cert-manager.io/cluster-issuer: "<CERT_CLUSTER_ISSUER>"
      cert-manager.io/revision-history-limit: "5"
    ingressClassName: nginx
    rules:
      - host: kubeflow.<commonName>
        http:
          paths:
            - backend:
                service:
                  name: istio-ingressgateway
                  port:
                    number: 8080
              path: /
              pathType: Prefix
    tls:
      - hosts:
          - kubeflow.<commonName>
        secretName: kubeflow-ingress-tls

Сначала создайте пул. IP в addresses должен совпадать со свободным адресом из этого пула. Если у пула задан serviceSelector, он должен пропускать Service Gateway kubeflow в неймспейсе istio-system.

hostname соберите от IP Gateway, не от commonName Ingress. При схеме *.<CLUSTER_NAME>.ip-<VIP>.shturval.link это kubeflow.<CLUSTER_NAME>.ip-<IP-Gateway>.shturval.link (в IP точки замените на дефисы). Тот же хост укажите в oauth2-proxy.oauth2Cfg.redirect_url у kubeflow-step-1: https://<hostname-Gateway>/oauth2/callback.

Импортируйте манифест пула:

apiVersion: cilium.io/v2
kind: CiliumLoadBalancerIPPool
metadata:
  name: kubeflow-gateway-vip
spec:
  disabled: false
  blocks:
    - start: "<IP-Gateway>"
      stop: "<IP-Gateway>"

Затем в customvalues kubeflow-step-2:

platform-agnostic-mutli-user:
  seaweedfs:
    enabled: false
  mysql:
    enabled: false
    external:
      host: "<KFP_MYSQL_HOST>"
      port: <KFP_MYSQL_PORT>
      pipelineDatabase: "<KFP_MYSQL_PIPELINE_DB>"
      metadataDatabase: "<KFP_MYSQL_METADATA_DB>"
      username: "<KFP_MYSQL_USER>"
      password: "<KFP_MYSQL_PASSWORD>"
      serviceName: ""
  pipelinesProfileController:
    env:
      awsEndpointUrl: "<KFP_AWS_IAM_ENDPOINT>"
      s3EndpointUrl: "<KFP_S3_ENDPOINT>"
      awsRegion: "<KFP_AWS_REGION>"
      s3Bucket: "<KFP_S3_BUCKET>"
    awsCredentials:
      accessKeyValue: "<KFP_AWS_ACCESS_KEY>"
      secretKeyValue: "<KFP_AWS_SECRET_KEY>"
  s3:
    caCert: "<PEM-сертификат-CA-если-S3-по-HTTPS>"
  exposure: gateway
  gateway:
    addresses:
      - type: IPAddress
        value: "<IP-Gateway>"
    create: true
    gatewayClassName: cilium
    hostname: <hostname-Gateway>
    httpRoute:
      backend:
        name: istio-ingressgateway
        port: 80
    name: kubeflow
    namespace: istio-system
    tls:
      clusterIssuer: "<CERT_CLUSTER_ISSUER>"
      revisionHistoryLimit: "5"
      secretName: kubeflow-ingress-tls
  1. Установите kubeflow-step-3 (Katib). Зависимость: kubeflow-step-2. Режим Авто. Спецификация:
katib:
  mysql:
    enabled: false
    external:
      host: "<KATIB_MYSQL_HOST>"
      port: <KATIB_MYSQL_PORT>
      database: "<KATIB_MYSQL_DB>"
      username: "<KATIB_MYSQL_USER>"
      password: "<KATIB_MYSQL_PASSWORD>"
      secretName: "<KATIB_MYSQL_SECRET_NAME>"
      serviceName: ""
  1. Установите kubeflow-step-4 (завершающие компоненты). Customvalues не нужны. Зависимость: kubeflow-step-3. Режим Авто.
  2. Дождитесь, когда kubeflow-step-0 … kubeflow-step-4 перейдут в состояние Healthy. Если сервис долго не переходит в это состояние, найдите причину: Устранение неполадок. Уже готовые шаги не пересоздаются.

Поле spec.dependency в GUI задайте на вкладке Манифест или импортируйте SSC YAML целиком.

Проверьте:

  1. Сервисы и репозитории → Установленные сервисы. У kubeflow-step-0 … kubeflow-step-4 режим Авто, состояние Healthy.
  2. Откройте неймспейс default и проверьте лейбл istio-injection=enabled — его выставляет чарт. Если лейбла нет, см. устранение неполадок.
  3. В браузере откройте URL точки входа: для Ingress — https://kubeflow.<commonName>/, для Gateway — https://<hostname-Gateway>/. Должен открыться вход платформы (SSO), затем интерфейс Kubeflow. Если страница не открывается, проверьте DNS: для Ingress — kubeflow.<commonName> на адрес Ingress, для Gateway — <hostname-Gateway> на <IP-Gateway>.

Создайте все пять SSC сразу с mode: auto.

kubeflow-step-0 — базовые CRD и компоненты, без OIDC.

kubeflow-step-1 — Dex и oauth2-proxy. OIDC-параметры с шага 1 и cookie_secret из раздела «Подготовьте параметры». Для Gateway в redirect_url — https://<hostname-Gateway>/oauth2/callback.

kubeflow-step-2 — Pipelines, хранилища и точка входа. Поле serviceName оставьте пустым. Объектное хранилище должно поддерживать AWS IAM. Если S3 работает по HTTP, оставьте s3.caCert пустым. Если по HTTPS, вставьте PEM корневого сертификата. Блок точки входа — на вкладке Ingress или Gateway.

kubeflow-step-3 — Katib.

kubeflow-step-4 — завершающие компоненты. Customvalues не нужны.

apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-0
spec:
  chart: kubeflow-step-0
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0
---
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-1
spec:
  chart: kubeflow-step-1
  customvalues:
    dex:
      oidc:
        client_id: "<OIDC_CLIENT_ID>"
        client_secret: "<OIDC_CLIENT_SECRET>"
    oauth2-proxy:
      oauth2Cfg:
        oidc_issuer_url: "<OIDC_ISSUER_URL>"
        redirect_url: https://kubeflow.<commonName>/oauth2/callback
      oidc:
        client_id: "<OIDC_CLIENT_ID>"
        client_secret: "<OIDC_CLIENT_SECRET>"
        cookie_secret: "<cookie_secret>"
  dependency:
  - kubeflow-step-0
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-2
spec:
  chart: kubeflow-step-2
  customvalues:
    platform-agnostic-mutli-user:
      seaweedfs:
        enabled: false
      mysql:
        enabled: false
        external:
          host: "<KFP_MYSQL_HOST>"
          port: <KFP_MYSQL_PORT>
          pipelineDatabase: "<KFP_MYSQL_PIPELINE_DB>"
          metadataDatabase: "<KFP_MYSQL_METADATA_DB>"
          username: "<KFP_MYSQL_USER>"
          password: "<KFP_MYSQL_PASSWORD>"
          serviceName: ""
      pipelinesProfileController:
        env:
          awsEndpointUrl: "<KFP_AWS_IAM_ENDPOINT>"
          s3EndpointUrl: "<KFP_S3_ENDPOINT>"
          awsRegion: "<KFP_AWS_REGION>"
          s3Bucket: "<KFP_S3_BUCKET>"
        awsCredentials:
          accessKeyValue: "<KFP_AWS_ACCESS_KEY>"
          secretKeyValue: "<KFP_AWS_SECRET_KEY>"
      s3:
        caCert: "<PEM-сертификат-CA-если-S3-по-HTTPS>"
      ingress:
        enabled: true
        annotations:
          cert-manager.io/cluster-issuer: "<CERT_CLUSTER_ISSUER>"
          cert-manager.io/revision-history-limit: "5"
        ingressClassName: nginx
        rules:
          - host: kubeflow.<commonName>
            http:
              paths:
                - backend:
                    service:
                      name: istio-ingressgateway
                      port:
                        number: 8080
                  path: /
                  pathType: Prefix
        tls:
          - hosts:
              - kubeflow.<commonName>
            secretName: kubeflow-ingress-tls
  dependency:
  - kubeflow-step-1
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0

Пул создайте до SSC kubeflow-step-2. IP в addresses — свободный адрес из этого пула. hostname — хост с IP Gateway (<hostname-Gateway>), не kubeflow.<commonName>. Тот же хост — в redirect_url у kubeflow-step-1.

apiVersion: cilium.io/v2
kind: CiliumLoadBalancerIPPool
metadata:
  name: kubeflow-gateway-vip
spec:
  disabled: false
  blocks:
    - start: "<IP-Gateway>"
      stop: "<IP-Gateway>"
---
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-2
spec:
  chart: kubeflow-step-2
  customvalues:
    platform-agnostic-mutli-user:
      seaweedfs:
        enabled: false
      mysql:
        enabled: false
        external:
          host: "<KFP_MYSQL_HOST>"
          port: <KFP_MYSQL_PORT>
          pipelineDatabase: "<KFP_MYSQL_PIPELINE_DB>"
          metadataDatabase: "<KFP_MYSQL_METADATA_DB>"
          username: "<KFP_MYSQL_USER>"
          password: "<KFP_MYSQL_PASSWORD>"
          serviceName: ""
      pipelinesProfileController:
        env:
          awsEndpointUrl: "<KFP_AWS_IAM_ENDPOINT>"
          s3EndpointUrl: "<KFP_S3_ENDPOINT>"
          awsRegion: "<KFP_AWS_REGION>"
          s3Bucket: "<KFP_S3_BUCKET>"
        awsCredentials:
          accessKeyValue: "<KFP_AWS_ACCESS_KEY>"
          secretKeyValue: "<KFP_AWS_SECRET_KEY>"
      s3:
        caCert: "<PEM-сертификат-CA-если-S3-по-HTTPS>"
      exposure: gateway
      gateway:
        addresses:
          - type: IPAddress
            value: "<IP-Gateway>"
        create: true
        gatewayClassName: cilium
        hostname: <hostname-Gateway>
        httpRoute:
          backend:
            name: istio-ingressgateway
            port: 80
        name: kubeflow
        namespace: istio-system
        tls:
          clusterIssuer: "<CERT_CLUSTER_ISSUER>"
          revisionHistoryLimit: "5"
          secretName: kubeflow-ingress-tls
  dependency:
  - kubeflow-step-1
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-3
spec:
  chart: kubeflow-step-3
  customvalues:
    katib:
      mysql:
        enabled: false
        external:
          host: "<KATIB_MYSQL_HOST>"
          port: <KATIB_MYSQL_PORT>
          database: "<KATIB_MYSQL_DB>"
          username: "<KATIB_MYSQL_USER>"
          password: "<KATIB_MYSQL_PASSWORD>"
          secretName: "<KATIB_MYSQL_SECRET_NAME>"
          serviceName: ""
  dependency:
  - kubeflow-step-2
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0
---
apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServiceConfig
metadata:
  name: kubeflow-step-4
spec:
  chart: kubeflow-step-4
  dependency:
  - kubeflow-step-3
  mode: auto
  namespace: default
  reponame: shturval
  version: 0.1.0

Склейте YAML kubeflow-step-0 / kubeflow-step-1, выбранный kubeflow-step-2 и kubeflow-step-3 / kubeflow-step-4 (разделитель ---) и примените (kubectl apply -f или kubectl apply -f -). Для Gateway сначала примените CiliumLoadBalancerIPPool. Дождитесь состояния Healthy для каждого:

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get ssc kubeflow-step-0 kubeflow-step-1 kubeflow-step-2 kubeflow-step-3 kubeflow-step-4
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get pods -n default

Когда все пять SSC перейдут в состояние Healthy:

kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get ns default -o jsonpath='{.metadata.labels.istio-injection}{"\n"}'
kubectl --kubeconfig "${KUBECONFIG_CLIENT}" get pods -A | grep -v "Running\|Completed"

Ожидаемый лейбл неймспейса default: enabled.


Дальше: