
Kubeflow ML 流水线 K8s 部署教程机器学习工作流编排全攻略机器学习项目的工程化落地往往卡在工作流管理这一环。从数据预处理、特征工程、模型训练、超参调优到最终部署每个步骤都需要精确的依赖管理和资源调度。Kubeflow 正是为解决这一痛点而生——作为专为 Kubernetes 设计的机器学习平台它将 ML 工作流的每个阶段都封装为可复用、可观测、可版本化的 Pipeline 组件实现模型训练、调参Katib与部署KServe的一体化编排。Kubeflow 的核心价值在于将 ML 实验的手工艺提升为可工程化复现的流水线生产。通过 Kubeflow Pipelines数据科学家可以用 Python 代码定义 DAG有向无环图工作流每个节点在独立容器中运行天然支持并行执行、断点续跑和资源隔离。结合 Katib 的自动超参搜索和 KServe 的模型推理服务整个 MLOps 生命周期在同一个 Kubernetes 平台上形成闭环。本教程详细介绍如何在 Kubernetes 集群上通过 Helm 部署 Kubeflow并编写一个完整的图像分类 Pipeline从数据准备到模型服务一步到位。服务器配置机器学习工作负载对计算资源要求较高。推荐在雨云服务器 rainyun-com上部署 Kubeflow 集群注册填优惠码2026off领 5 折优惠券。建议选择8 核 16GB 机型作为控制节点和主要工作节点GPU 节点可按需额外挂载。推荐硬件配置Kubeflow 控制面8 核 16GB本教程使用此规格训练工作节点视模型规模而定GPU 节点最佳存储至少 100GB SSD用于模型存储和 Pipeline 缓存操作系统Ubuntu 22.04 LTSKubernetesv1.27软件前置依赖kubectl、helmv3.12kustomizev5.0Python 3.9用于编写 PipelinekfpSDK 2.x准备工作安装 kustomizecurl-shttps://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh|bashmvkustomize /usr/local/bin/ kustomize version安装 Kubeflow Pipelines SDKpipinstallkfp2.7.0 pipinstallkfp-kubernetes1.2.0前置 K8s 组件检查# 确认 StorageClass 已配置Kubeflow 需要动态 PVC 供给kubectl get storageclass# 如无默认 StorageClass可安装 local-path-provisioner测试环境kubectl apply-fhttps://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.26/deploy/local-path-storage.yaml kubectl patch storageclass local-path-p{metadata: {annotations:{storageclass.kubernetes.io/is-default-class:true}}}详细配置部署 Kubeflow方式一使用官方 manifests推荐# 克隆官方仓库指定稳定版本gitclone https://github.com/kubeflow/manifests.gitcdmanifestsgitcheckout v1.9.0# 完整安装包含所有组件while!kustomize build example|kubectl apply-f-;doechoRetrying to apply resources...sleep20done完整安装包含Kubeflow Pipelines、Katib、KServe、Central Dashboard、Jupyter Notebooks、Profile Controller 等核心组件。方式二仅安装 Kubeflow Pipelines轻量部署# 仅部署 KFP 组件适合资源有限的环境kustomize build apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user|kubectl apply-f-# 等待所有 Pod 就绪kubectlwait--forconditionReady pods--all-nkubeflow--timeout300s访问 Kubeflow Dashboard# 端口转发访问 Central Dashboardkubectl port-forward svc/istio-ingressgateway-nistio-system8080:80# 或配置 NodePort生产环境建议配置 Ingresskubectl patch svc istio-ingressgateway-nistio-system\-p{spec: {type: NodePort}}默认登录账号userexample.com/12341234验证部署状态kubectl get pods-nkubeflow kubectl get pods-nistio-system kubectl get pods-ncert-manager# 检查 Pipeline 服务kubectl get svc-nkubeflow|grepml-pipeline核心功能编写 ML Pipeline定义一个完整的训练流水线以下示例演示一个 MNIST 图像分类的完整 Pipeline包含数据下载、预处理、训练和评估四个步骤# pipeline_mnist.pyfromkfpimportdsl,compilerfromkfp.dslimportDataset,Model,Output,Input,Metrics# 步骤一下载并准备数据集dsl.component(base_imagepython:3.9-slim,packages_to_install[tensorflow-datasets,numpy])defdownload_data(dataset_output:Output[Dataset],num_samples:int10000):importtensorflow_datasetsastfdsimportnumpyasnpimportos(ds_train,ds_test),ds_infotfds.load(mnist,split[train[:{}].format(num_samples),test[:1000]],as_supervisedTrue,with_infoTrue)os.makedirs(dataset_output.path,exist_okTrue)# 保存数据到输出路径np.save(os.path.join(dataset_output.path,train_data.npy),[(x.numpy(),y.numpy())forx,yinds_train])# 步骤二训练模型dsl.component(base_imagetensorflow/tensorflow:2.13.0,packages_to_install[numpy])deftrain_model(dataset:Input[Dataset],model_output:Output[Model],epochs:int5,learning_rate:float0.001):importtensorflowastfimportnumpyasnpimportos# 加载数据datanp.load(os.path.join(dataset.path,train_data.npy),allow_pickleTrue)Xnp.array([item[0]foritemindata])/255.0ynp.array([item[1]foritemindata])# 构建模型modeltf.keras.Sequential([tf.keras.layers.Flatten(input_shape(28,28)),tf.keras.layers.Dense(128,activationrelu),tf.keras.layers.Dropout(0.2),tf.keras.layers.Dense(10,activationsoftmax)])model.compile(optimizertf.keras.optimizers.Adam(learning_ratelearning_rate),losssparse_categorical_crossentropy,metrics[accuracy])model.fit(X,y,epochsepochs,validation_split0.1,verbose1)# 保存模型os.makedirs(model_output.path,exist_okTrue)model.save(model_output.path)print(fModel saved to:{model_output.path})# 步骤三评估模型dsl.component(base_imagetensorflow/tensorflow:2.13.0,)defevaluate_model(model:Input[Model],metrics_output:Output[Metrics]):importtensorflowastf modeltf.keras.models.load_model(model.path)# 在测试集上评估简化示例metrics_output.log_metric(accuracy,0.98)metrics_output.log_metric(loss,0.07)# 组合 Pipelinedsl.pipeline(nameMNIST 训练流水线,description完整的 MNIST 图像分类训练、评估流水线)defmnist_pipeline(num_samples:int10000,epochs:int5,learning_rate:float0.001):download_taskdownload_data(num_samplesnum_samples)download_task.set_cpu_request(500m).set_memory_request(1Gi)train_tasktrain_model(datasetdownload_task.outputs[dataset_output],epochsepochs,learning_ratelearning_rate)train_task.set_cpu_request(2).set_memory_request(4Gi)train_task.after(download_task)eval_taskevaluate_model(modeltrain_task.outputs[model_output])eval_task.after(train_task)# 编译为 YAMLif__name____main__:compiler.Compiler().compile(pipeline_funcmnist_pipeline,package_pathmnist_pipeline.yaml)print(Pipeline compiled: mnist_pipeline.yaml)提交 Pipeline 到 Kubeflow# submit_pipeline.pyimportkfp# 连接 KFP 服务端clientkfp.Client(hosthttp://localhost:8080)# 上传并运行runclient.create_run_from_pipeline_package(pipeline_filemnist_pipeline.yaml,arguments{num_samples:50000,epochs:10,learning_rate:0.001},run_namemnist-training-v1,experiment_nameMNIST Experiments)print(fRun ID:{run.run_id})print(fView at: http://localhost:8080/#/runs/details/{run.run_id})python submit_pipeline.py配置 Katib 超参调优# katib-experiment.yamlapiVersion:kubeflow.org/v1beta1kind:Experimentmetadata:name:mnist-hp-tuningnamespace:kubeflow-user-example-comspec:objective:type:maximizegoal:0.99objectiveMetricName:accuracyalgorithm:algorithmName:bayesianoptimizationparallelTrialCount:3maxTrialCount:12maxFailedTrialCount:3parameters:-name:learning_rateparameterType:doublefeasibleSpace:min:0.0001max:0.01-name:epochsparameterType:intfeasibleSpace:min:5max:20trialTemplate:primaryContainerName:training-containertrialParameters:-name:learningRatedescription:Learning ratereference:learning_ratetrialSpec:apiVersion:batch/v1kind:Jobspec:template:spec:containers:-name:training-containerimage:docker.io/myrepo/mnist-trainer:latestcommand:-python-train.py---lr${trialParameters.learningRate}kubectl apply-fkatib-experiment.yaml使用技巧1. Pipeline 组件缓存KFP 支持组件级缓存相同输入的步骤不会重复执行dsl.pipelinedefmy_pipeline():taskmy_component()task.set_caching_options(enable_cachingTrue)# 默认开启2. 使用 PVC 共享大型数据集fromkfp.kubernetesimportuse_field_path,mount_pvcdsl.pipelinedefpipeline_with_pvc():taskheavy_preprocessing()mount_pvc(task,pvc_namedataset-pvc,mount_path/data)3. 设置资源配额与 GPUtrain_tasktrain_model(dataset...)train_task.set_gpu_limit(1)train_task.set_memory_limit(8Gi)train_task.add_node_selector_constraint(cloud.google.com/gke-accelerator,nvidia-tesla-t4)4. Pipeline 版本管理通过 KFP UI 或 SDK 管理 Pipeline 版本便于 A/B 对比不同版本的训练效果client.upload_pipeline_version(pipeline_package_pathmnist_pipeline_v2.yaml,pipeline_version_namev2.0-improved-augmentation,pipeline_idexisting_pipeline_id)常见问题排查QPod 因 OOMKilled 崩溃ML 训练步骤内存消耗大需在组件定义中合理设置memory_limit。检查实际用量kubectltoppods-nkubeflowQPVC 无法绑定Pipeline 卡在 Pending检查 StorageClass 是否正确配置并设为默认kubectl get pvc-nkubeflow-user-example-com kubectl describe pvcpvc-name-nkubeflow-user-example-comQIstio sidecar 注入导致 Pipeline 组件启动慢在命名空间级别配置 Istio 注入策略减少不必要的 sidecarkubectl label namespace kubeflow istio-injectionenabledQKFP UI 无法访问显示 “502 Bad Gateway”检查 Istio Ingress Gateway 和 KFP 后端服务状态kubectl get pods-nistio-system kubectl logs-nkubeflow deployment/ml-pipeline-fQKatib 实验长时间未完成检查 Trial Pod 日志确认训练脚本正确输出指标Katib 通过 stdout 的特定格式采集指标kubectl logs-nkubeflowtrial-pod-name|grepaccuracyKubeflow 将 MLOps 最佳实践固化为平台能力让机器学习工程化不再依赖个人经验的堆积。稳定的基础设施是 ML 平台可靠运行的前提——推荐选用雨云服务器 rainyun-com的8 核 16GB 机型部署 Kubeflow大内存配置可以从容应对多个并发训练任务的内存压力。注册填优惠码2026off享 5 折优惠券以超高性价比开启你的 MLOps 之旅。