Azure 上使用 Kubeflow 和 MinIO 的机器学习管道

Azure 上使用 Kubeflow 和 MinIO 的机器学习管道

机器学习 (ML) 计划可以将计算和存储基础设施推向极限。许多 DataOps 团队依靠基于 Kubernetes 的混合云架构来满足计算和对象存储对可扩展性、效率、可靠性、多租户和 RESTful API 支持的要求。DataOps 团队已经标准化了工具,这些工具依赖于高性能 S3 API 兼容的对象存储来满足他们的管道、训练和推理需求。

KubeflowKubernetes的标准机器学习工具包,它需要 S3 API 兼容性。Kubeflow 在整个数据科学社区中被广泛使用,但对 S3 API 兼容对象存储的要求限制了部署选项。如果 Azure 或 GCP 的对象存储产品缺乏 S3 API 支持,您将如何在它们上运行 Kubeflow?

MinIO Kubernetes 原生对象存储与 S3 API 兼容,因此您可以在任何托管 Kubernetes 服务(Azure Kubernetes ServiceGoogle Kubernetes EngineAmazon Kubernetes Service)和任何 Kubernetes 发行版(VMware TanzuRed Hat OpenShift、甚至Minikube。        

在这篇文章中,我们将使用 Azure Kubernetes 服务 (AKS) 设置一个 Kubeflow 集群,使用 MinIO 作为整个设置的底层存储,并对其进行端到端测试,我们将部署一个管道来访问 MinIO 上的数据和也将生成的模型存储在那里。我们将要使用的问题是传统的 MNIST 挑战,它包含一个光学字符识别 (OCR) 问题。

设置 Kubernetes 集群

让我们首先设置名为KubeFlowMinIO的 AKS 集群,该集群在名为MinIOKubeFlow的资源组中有四个节点

export RESOURCE_GROUP_NAME=MinIOKubeFlow
export LOCATION=westus

az group create -n $RESOURCE_GROUP_NAME -l $LOCATION


export NAME=KubeFlowMinIO

export AGENT_SIZE=Standard_D4s_v3

export AGENT_COUNT=4


az aks create -g $RESOURCE_GROUP_NAME -n $NAME -s $AGENT_SIZE -c $AGENT_COUNT -l $LOCATION --generate-ssh-keys



此过程将需要几分钟时间,之后您将拥有一个可以运行的 Kubernetes 集群。您只需要使用此集群的访问权限配置本地kubectl

az aks get-credentials -n $NAME -g $RESOURCE_GROUP_NAME

设置 MinIO

下一步是设置 MinIO Operator 来管理 Azure 上的对象存储。我们在Kubernetes 上简化了 MinIO 的管理,因此有多种安装 MinIO operator 的方法,您可以选择最适合您的工作流程的一种。在这篇文章中,我们将使用 MinIO 的 krew 插件来设置 MinIO Operator 和我们的对象存储。

下载 MinIO Krew 插件。

kubectl krew install minio


然后初始化操作符。

kubectl minio init


现在,让我们进入 MinIO Operator UI 创建我们的第一个租户。输入以下命令以接收本地可访问端点和登录令牌。

kubectl minio proxy -n minio-operator 


预期的输出是:

Starting port forward of the Console UI.

To connect open a browser and go to http://localhost:9090

Current JWT to login: eyJhbGciOiJSUzI1NiIsImtpZCI6IkhWclVWMmc2YjNuZlRKcGY1YUxJTTh1Mjd2d3ZKZmh5dzBKaE10cm5QYUUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtaW5pby1vcGVyYXRvciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjb25zb2xlLXNhLXRva2VuLTh2cDRxIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNvbnNvbGUtc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI4MDJkMmFlZi02ZTQxLTQyMzctYjIyYS04OGVkNjhhNTFkMWMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bWluaW8tb3BlcmF0b3I6Y29uc29sZS1zYSJ9.CxaS7Xy6l63Z90FLDL0XV0FB4iYYD93-EZ9lT6dUxHTkaYIwGzuVAOVYKclIAslpJqvANzurnuCQv2DSYuptBokqNyJqBZ_Mdfxk_BD8k9LNvvhH2B75FXJOlLUvO43HZp-vWqiBLHvhWD86KI5YdCqgXq0KB2Yuw03pIeAkGhdo-QN7EnTVt-mu6OniB6q_oSC61wUoToHCZKbq7OLeg2zzwqo9JGCBvghBbiVFzeMTYAQHdad69PsWjBRBlUKbG7v5eNWiVPiV44r0-fUZxdCr-1JEP9e4Ag-8J2GzIU1-yBIc_Yn1ok59HxXwiT-_fmp2tpe2WsArY7Hwzza2qLoVSkITzPX6eMVbGfRdzbcxd396LcQfg8GJn4Rbs1Z4YCRqMK_DpoQqYOFf-pjZ6Oa91GlZpMVSH_6_H4xxBuuobyn3WK7XyuBxJuFcl7KoIKoa4qwi87eUE139RXPOZKsCrMX-YmKxTAixKlGux2U4jRaN2lav6_y-ayUvHt0syEJqu0uhqdPNVxGIWW0sabJJ0sSfQdacmrBY1VazIYsN2NAL1N2QCwmQvvjRlqpEAWPF_uhuVwGtgcDX8-CxRKtfoY-8gn7ujwCKl1GMpyr-nE8p88eMIxEkaXqBia0erRLwUGTHrS2ymGN0Ii85_2wRZmDuCGA9QiQ01r89ZXU

Forwarding from 0.0.0.0:9090 -> 9090




现在让我们进入http://localhost:9090并使用建议的令牌登录。


Screen Shot 2021-06-29 at 11.21.21 AM.png


登录后,我们会看到一个空的租户列表,让我们通过单击右上角的+ 创建租户来创建一个


Screen Shot 2021-06-29 at 11.21.54 AM.png


为了在此设置过程中保持简单,我们将在集群默认命名空间创建一个名为machine-learning-cluster的租户当然,您可以将其更改为适合您需要的任何命名空间。然后我们将选择一个存储类,因为我们的目标是高性能数据存储库,我们将使用Azure 的托管高级存储来为我们的 Kubeflow 管道获得最佳性能。完成这些字段后,选择高级。您可以在此处配置高级功能,例如自定义 Docker 注册表、身份提供者、加密和 Pod 放置。现在,我们将单击下一步直到我们到达安全步骤并关闭 TLS,这样我们就可以完成本指南而无需设置域和外部 TLS 证书。


Screen Shot 2021-06-29 at 2.44.53 PM.png


关闭此租户的 TLS。


Screen Shot 2021-06-29 at 2.45.09 PM.png



现在,我们将告诉 MinIO Operator 我们想要我们的租户有多大。我将使用 4 个节点来匹配我们当前的设置和1 TB的容量,但您可以根据需要进行调整。


Screen Shot 2021-06-29 at 2.45.32 PM.png



最后一步是回顾将要发生的事情。只需单击“创建”,MinIO 即可完成剩下的工作!


Screen Shot 2021-06-29 at 2.45.40 PM.png



记下自动生成的凭据以访问您的对象存储,我们将使用这些凭据访问底层存储。


Screen Shot 2021-06-29 at 11.29.37 AM.png



而已!您已经配置了一个高性能对象存储,并且只用了几分钟。再过几分钟,您将看到租户已初始化并准备就绪。


Screen Shot 2021-06-29 at 11.36.29 AM.png


您可以在租户详细信息中更新和扩展对象存储。我们还可以看到,我们的对象存储和管理我们的对象存储有一个公共 IP。我们不会在本指南中使用它,但您可以使用它来从该集群外部开始使用对象存储。

我们已经准备好进入对象存储领域——我们已经建立了一个高性能集群,现在我们需要在我们的 Kubeflow 管道中利用它。

设置 Kubeflow

要在 AKS 上设置 Kubeflow,我们将使用命令行实用程序kfctl,它可以从kfctl 发布页面下载有适用于 Mac 和 Linux 的二进制文件,但如果您使用的是 Windows,则必须从源代码编译该二进制文件。只需确保 kfctl 二进制文件在您的 PATH 中。

运行以下命令,这些命令取自Kubeflow on Azure 安装文档。

# Set KF_NAME to the name of your Kubeflow deployment. You also use this
# value as directory name when creating your configuration directory.
# For example, your deployment name can be 'my-kubeflow' or 'kf-test'.
export KF_NAME=my-kubeflow

# Set the path to the base directory where you want to store one or more
# Kubeflow deployments. For example, /opt/.
# Then set the Kubeflow application directory for this deployment.
export BASE_DIR=kubeflowsetup
export KF_DIR=${BASE_DIR}/${KF_NAME}

# Set the configuration file to use when deploying Kubeflow.
# The following configuration installs Istio by default. Comment out
# the Istio components in the config file to skip Istio installation.
# See https://github.com/kubeflow/kubeflow/pull/3663
export CONFIG_URI="https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_k8s_istio.v1.2.0.yaml"

mkdir -p ${KF_DIR}
cd ${KF_DIR}
kfctl apply -V -f ${CONFIG_URI}



按照配置,此过程大约需要八分钟,因此请喝杯咖啡并使用以下命令监控完成情况。

kubectl get all -n kubeflow


一旦所有 pod 都运行起来,我们就准备好继续构建一个利用 MinIO 的 Kubeflow 管道。

通过运行以下 port-foward 命令并转到http://localhost:8080来打开 Kubeflow 仪表板

kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80


然后通过创建机器学习命名空间来完成 Kubeflow 设置


Screen Shot 2021-06-29 at 12.02.59 PM.png


配置命名空间后,Kubeflow 仪表板将打开。


Screen Shot 2021-06-29 at 12.03.12 PM.png



让我们设置一个 Jupyter 笔记本服务器并从那里配置它。使用 Tensorflow 1.15图像,创建一个名为setup-pipeline的笔记本


Screen Shot 2021-06-29 at 12.12.21 PM.png


服务器准备就绪后,连接到它,然后创建一个名为Setup PipelinePython 3 notebook 


Screen Shot 2021-06-29 at 12.16.09 PM.png



最后一步是配置您的 Docker 帐户。Kubeflow 会将您在整个管道中构建的每个新模型推送到 Docker,您可能很快就会达到每小时 100 个请求的限制。当您使用 Docker 帐户时,限制会提高到每小时 200 个请求。

USER=; PASSWORD=; echo -n $USER:$PASSWORD | base64 |  xargs echo -n |xargs -0 printf '{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "%s"
        }
    }
}\n' > /tmp/config.json && kubectl create --namespace ${NAMESPACE} configmap docker-config --from-file=/tmp/config.json && rm /tmp/config.json



运行 Kubeflow 管道

现在回到我们的笔记本。从这里开始,我们将遵循Kubeflow 团队提供的vanilla kubernetes优秀示例我们将学习如何将模型提交到 Kubeflow 进行分布式训练,以及如何部署和服务它们。

你需要一些文件来让这个 notebook 工作,主要是model.py、k8s_util.py、notebook_setup.py、requirements.txt 和 Dockerfile.model来构建你的模型,将它提交到 Kubeflow 然后部署它。让我们从以下代码段开始,将这些文件下载到我们的笔记本中。

import urllib.request
import shutil

file_list = ["https://raw.githubusercontent.com/kubeflow/examples/master/mnist/k8s_util.py","https://raw.githubusercontent.com/kubeflow/examples/master/mnist/Dockerfile.model","https://raw.githubusercontent.com/kubeflow/examples/master/mnist/model.py","https://raw.githubusercontent.com/kubeflow/examples/master/mnist/notebook_setup.py","https://raw.githubusercontent.com/kubeflow/examples/master/mnist/requirements.txt"]

for url in file_list:
    file_name = url.split("/").pop()
    with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
        shutil.copyfileobj(response, out_file)

现在,让我们准备命名空间并配置我们的 MinIO 凭据。对于我们的端点,我们将使用内部 Kubernetes 服务名称minio.default.svc.cluster.local,对于DOCKER_REGISTRY,我们将输入我们的 Docker 用户名。

from kubernetes import client as k8s_client
from kubernetes.client import rest as k8s_rest
from kubeflow import fairing  
from kubeflow.fairing import utils as fairing_utils
from kubeflow.fairing.builders import append
from kubeflow.fairing.deployers import job
from kubeflow.fairing.preprocessors import base as base_preprocessor

DOCKER_REGISTRY = "miniodev"
namespace = fairing_utils.get_current_k8s_namespace()

from kubernetes import client as k8s_client
from kubernetes.client.rest import ApiException

api_client = k8s_client.CoreV1Api()
minio_service_endpoint = "minio.default.svc.cluster.local"

s3_endpoint = minio_service_endpoint
minio_endpoint = "http://"+s3_endpoint
minio_username = "AXNENHDUBB2LU24Y"
minio_key = "GPONOCU0IDQZBMP55TTELR00D4HGFPJK"
minio_region = "us-east-1"

logging.info(f"Running in namespace {namespace}")
logging.info(f"Using docker registry {DOCKER_REGISTRY}")
logging.info(f"Using minio instance with endpoint '{s3_endpoint}'")



接下来,我们将通过安装依赖项并下载所需数据来准备本地笔记本。所有这些都可以在一个单独的块中完成,但我使用了与示例笔记本相同的单独块,以便您更容易理解。

import logging
import os
import uuid
from importlib import reload
import notebook_setup
reload(notebook_setup)
notebook_setup.notebook_setup(platform='none')

import k8s_util
# Force a reload of kubeflow; since kubeflow is a multi namespace module
# it looks like doing this in notebook_setup may not be sufficient
import kubeflow
reload(kubeflow)
from kubernetes import client as k8s_client
from kubernetes import config as k8s_config
from kubeflow.tfjob.api import tf_job_client as tf_job_client_module
from IPython.core.display import display, HTML
import yaml

# TODO(https://github.com/kubeflow/fairing/issues/426): We should get rid of this once the default
# Kaniko image is updated to a newer image than 0.7.0.
from kubeflow.fairing import constants
constants.constants.KANIKO_IMAGE = "gcr.io/kaniko-project/executor:v0.14.0"

from kubeflow.fairing.builders import cluster

# output_map is a map of extra files to add to the notebook.
# It is a map from source location to the location inside the context.
output_map =  {
    "Dockerfile.model": "Dockerfile",
    "model.py": "model.py"
}

preprocessor = base_preprocessor.BasePreProcessor(
    command=["python"], # The base class will set this.
    input_files=[],
    path_prefix="/app", # irrelevant since we aren't preprocessing any files
    output_map=output_map)

preprocessor.preprocess()

# Use a Tensorflow image as the base image
# We use a custom Dockerfile
from kubeflow.fairing.cloud.k8s import MinioUploader
from kubeflow.fairing.builders.cluster.minio_context import MinioContextSource

minio_uploader = MinioUploader(endpoint_url=minio_endpoint, minio_secret=minio_username, minio_secret_key=minio_key, region_name=minio_region)
minio_context_source = MinioContextSource(endpoint_url=minio_endpoint, minio_secret=minio_username, minio_secret_key=minio_key, region_name=minio_region)

cluster_builder = cluster.cluster.ClusterBuilder(registry=DOCKER_REGISTRY,
                                                base_image="", # base_image is set in the Dockerfile
                                                preprocessor=preprocessor,
                                                image_name="mnist",
                                                dockerfile_path="Dockerfile",
                                                context_source=minio_context_source)
cluster_builder.build()
logging.info(f"Built image {cluster_builder.image_tag}")



此时,您可以转到您的个人 Docker 注册表并确认为 MNIST 模型创建了一个新的 Docker 映像。


Screen Shot 2021-06-30 at 2.36.03 PM.png


下一步是创建一个 MinIO Bucket。

mnist_bucket = f"{DOCKER_REGISTRY}-mnist"
minio_uploader.create_bucket(mnist_bucket)
logging.info(f"Bucket {mnist_bucket} created or already exists")

接下来,我们简单地构建一个TFJobDeployments来训练我们的模型,使用TensorBoard检查它,最后为它提供服务,所有中间步骤都存储在您的 MinIO 租户中。

让我们开始浏览这些块,记住这些块是从kubeflow vanilla kubernete example逐字复制的

train_name = f"mnist-train-{uuid.uuid4().hex[:4]}"
num_ps = 1
num_workers = 2
model_dir = f"s3://{mnist_bucket}/mnist"
export_path = f"s3://{mnist_bucket}/mnist/export"
train_steps = 200
batch_size = 100
learning_rate = .01
image = cluster_builder.image_tag

train_spec = f"""apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
  name: {train_name} 
spec:
  tfReplicaSpecs:
    Ps:
      replicas: {num_ps}
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "false"
        spec:
          serviceAccount: default-editor
          containers:
          - name: tensorflow
            command:
            - python
            - /opt/model.py
            - --tf-model-dir={model_dir}
            - --tf-export-dir={export_path}
            - --tf-train-steps={train_steps}
            - --tf-batch-size={batch_size}
            - --tf-learning-rate={learning_rate}
            env:
            - name: S3_ENDPOINT
              value: {s3_endpoint}
            - name: AWS_ENDPOINT_URL
              value: {minio_endpoint}
            - name: AWS_REGION
              value: {minio_region}
            - name: BUCKET_NAME
              value: {mnist_bucket}
            - name: S3_USE_HTTPS
              value: "0"
            - name: S3_VERIFY_SSL
              value: "0"
            - name: AWS_ACCESS_KEY_ID
              value: {minio_username}
            - name: AWS_SECRET_ACCESS_KEY
              value: {minio_key}
            image: {image}
            workingDir: /opt
          restartPolicy: OnFailure
    Chief:
      replicas: 1
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "false"
        spec:
          serviceAccount: default-editor
          containers:
          - name: tensorflow
            command:
            - python
            - /opt/model.py
            - --tf-model-dir={model_dir}
            - --tf-export-dir={export_path}
            - --tf-train-steps={train_steps}
            - --tf-batch-size={batch_size}
            - --tf-learning-rate={learning_rate}
            env:
            - name: S3_ENDPOINT
              value: {s3_endpoint}
            - name: AWS_ENDPOINT_URL
              value: {minio_endpoint}
            - name: AWS_REGION
              value: {minio_region}
            - name: BUCKET_NAME
              value: {mnist_bucket}
            - name: S3_USE_HTTPS
              value: "0"
            - name: S3_VERIFY_SSL
              value: "0"
            - name: AWS_ACCESS_KEY_ID
              value: {minio_username}
            - name: AWS_SECRET_ACCESS_KEY
              value: {minio_key}
            image: {image}
            workingDir: /opt
          restartPolicy: OnFailure
    Worker:
      replicas: 1
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "false"
        spec:
          serviceAccount: default-editor
          containers:
          - name: tensorflow
            command:
            - python
            - /opt/model.py
            - --tf-model-dir={model_dir}
            - --tf-export-dir={export_path}
            - --tf-train-steps={train_steps}
            - --tf-batch-size={batch_size}
            - --tf-learning-rate={learning_rate}
            env:
            - name: S3_ENDPOINT
              value: {s3_endpoint}
            - name: AWS_ENDPOINT_URL
              value: {minio_endpoint}
            - name: AWS_REGION
              value: {minio_region}
            - name: BUCKET_NAME
              value: {mnist_bucket}
            - name: S3_USE_HTTPS
              value: "0"
            - name: S3_VERIFY_SSL
              value: "0"
            - name: AWS_ACCESS_KEY_ID
              value: {minio_username}
            - name: AWS_SECRET_ACCESS_KEY
              value: {minio_key}
            image: {image}
            workingDir: /opt
          restartPolicy: OnFailure
"""



接下来我们通过 Kubernetes Python SDK 提交作业。

tf_job_client = tf_job_client_module.TFJobClient()

tf_job_body = yaml.safe_load(train_spec)
tf_job = tf_job_client.create(tf_job_body, namespace=namespace) 

logging.info(f"Created job {namespace}.{train_name}")

from kubeflow.tfjob import TFJobClient
tfjob_client = TFJobClient()
tfjob_client.wait_for_job(train_name, namespace=namespace, watch=True)



然后我们得到作业的日志。

tfjob_client.get_logs(train_name, namespace=namespace)


我们准备在 MinIO 上检查模型。我们可以通过我们的笔记本或通过 MinIO 控制台来做到这一点。首先,我将展示如何通过笔记本执行此操作。

from botocore.exceptions import ClientError

try:
    model_response = minio_uploader.client.list_objects(Bucket=mnist_bucket)
    # Minimal check to see if at least the bucket is created
    if model_response["ResponseMetadata"]["HTTPStatusCode"] == 200:
        logging.info(f"{model_dir} found in {mnist_bucket} bucket")
except ClientError as err:
    logging.error(err)

现在我将展示如何使用操作员控制台执行此操作。进入操作员 GUI 中的租户详细信息,然后单击控制台 URL。


Screen Shot 2021-06-30 at 3.06.08 PM.png


从这里,登录到 MinIO 控制台,进入对象浏览器并探索miniodev-mnist存储区,我们可以在其中看到检查点和模型本身。


Screen Shot 2021-06-30 at 3.07.01 PM.png



让我们来看看培训是如何进行的。使用TensorBoard,我们将创建一个部署。

tb_name = "mnist-tensorboard"
tb_deploy = f"""apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mnist-tensorboard
  name: {tb_name}
  namespace: {namespace}
spec:
  selector:
    matchLabels:
      app: mnist-tensorboard
  template:
    metadata:
      labels:
        app: mnist-tensorboard
        version: v1
    spec:
      serviceAccount: default-editor
      containers:
      - command:
        - /usr/local/bin/tensorboard
        - --logdir={model_dir}
        - --port=80
        image: tensorflow/tensorflow:1.15.2-py3
        env:
        - name: S3_ENDPOINT
          value: {s3_endpoint}
        - name: AWS_ENDPOINT_URL
          value: {minio_endpoint}
        - name: AWS_REGION
          value: {minio_region}
        - name: BUCKET_NAME
          value: {mnist_bucket}
        - name: S3_USE_HTTPS
          value: "0"
        - name: S3_VERIFY_SSL
          value: "0"
        - name: AWS_ACCESS_KEY_ID
          value: {minio_username}
        - name: AWS_SECRET_ACCESS_KEY
          value: {minio_key} 
        name: tensorboard
        ports:
        - containerPort: 80
"""
tb_service = f"""apiVersion: v1
kind: Service
metadata:
  labels:
    app: mnist-tensorboard
  name: {tb_name}
  namespace: {namespace}
spec:
  ports:
  - name: http-tb
    port: 80
    targetPort: 80
  selector:
    app: mnist-tensorboard
  type: ClusterIP
"""

tb_virtual_service = f"""apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: {tb_name}
  namespace: {namespace}
spec:
  gateways:
  - kubeflow/kubeflow-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /mnist/{namespace}/tensorboard/
    rewrite:
      uri: /
    route:
    - destination:
        host: {tb_name}.{namespace}.svc.cluster.local
        port:
          number: 80
    timeout: 300s
"""

tb_specs = [tb_deploy, tb_service, tb_virtual_service]

k8s_util.apply_k8s_specs(tb_specs, k8s_util.K8S_CREATE_OR_REPLACE)



现在访问http://localhost:8080/mnist/machine-learning/ui/?ns=machine-learning,您将看到与 MinIO 直接提供的模型交互的漂亮 UI。


Screen Shot 2021-06-29 at 3.11.50 PM.png



MinIO 使数据科学和 DataOps 无处不在

好吧!我们到了这个大型指南的结尾,它解释了如何在 Azure Kubernetes 服务上设置 MinIO,然后部署 Kubeflow 以开箱即用地使用 MinIO。由于高度自动化,最简单的部分是设置 AKS、MinIO 和 Kubeflow 的构建块。这让您可以专注于更重要的任务,例如构建机器学习管道以在 Kubeflow 上平稳运行、直接利用来自 MinIO 的大型数据集以及直接从对象存储存储和部署模型。


下载 MinIO以开始使用,如果您有任何问题,请加入我们的Slack 频道

上一篇 下一篇