Kubeflow v1.8 离线部署实战:从镜像准备到内网Harbor的全流程指南

Kubeflow v1.8 离线部署实战:从镜像准备到内网Harbor的全流程指南 1. Kubeflow v1.8离线部署的核心挑战在企业内网环境中部署Kubeflow v1.8就像在没有超市的荒岛上搭建完整的厨房系统。你需要提前准备好所有食材容器镜像建立自己的储物柜Harbor仓库还要确保每道菜的配料比例镜像版本完全正确。我去年在金融行业客户现场实施时就遇到过因为漏掉一个关键镜像导致整个训练管道无法启动的情况。离线环境最头疼的问题就是镜像依赖。Kubeflow v1.8涉及200个容器镜像来自docker.io、gcr.io、quay.io等20多个不同仓库。更麻烦的是其中有些镜像是用sha256摘要标识的比如gcr.io/knative-releases/knative.dev/serving/cmd/webhooksha256:4305209...这种形式直接推送到私有Harbor会报格式错误。2. 离线镜像全量准备工作2.1 镜像清单生成实战首先获取官方manifest文件wget https://github.com/kubeflow/manifests/archive/refs/tags/v1.8.0.tar.gz tar -zxvf manifests-1.8.0.tar.gz用这个命令提取全部镜像列表cd manifests-1.8.0 kustomize build example | grep image: | awk $2 ! { print $2 } | sort -u image-list.txt这里有个坑要注意某些组件如kfp-driver的镜像是硬编码在代码里的不会出现在manifest中。建议额外补充这些镜像gcr.io/ml-pipeline/kfp-drivergcr.io/ml-pipeline/kfp-launchergcr.io/ml-pipeline/metadata-envoy2.2 镜像下载与转存技巧对于无法直接访问的gcr.io镜像推荐通过第三方镜像仓库中转。比如# 先拉取到本地 docker pull gcr.io/ml-pipeline/api-server:2.0.3 # 重新打tag后推送到私有Harbor docker tag gcr.io/ml-pipeline/api-server:2.0.3 192.168.5.200:5000/ml/gcr.io/ml-pipeline/api-server:2.0.3 docker push 192.168.5.200:5000/ml/gcr.io/ml-pipeline/api-server:2.0.3处理sha256格式镜像的特殊方法# 原始格式 name: gcr.io/knative-releases/knative.dev/serving/cmd/webhooksha256:4305209... # 在kustomization.yaml中需要转换为 images: - name: 192.168.5.200:5000/ml/gcr.io/knative-releases/knative.dev/serving/cmd/webhooksha256:4305209... newName: 192.168.5.200:5000/ml/gcr.io/knative-releases/knative.dev/serving/cmd/webhook newTag: sha2563. Harbor仓库高级配置3.1 批量镜像同步方案建议在Harbor中创建名为ml的独立项目然后使用脚本批量处理#!/bin/bash while read image; do repo$(echo $image | awk -F/ {print $NF} | cut -d: -f1) docker pull $image docker tag $image 192.168.5.200:5000/ml/${image#*/} docker push 192.168.5.200:5000/ml/${image#*/} done image-list.txt3.2 访问控制关键配置在values.yaml中需要设置externalURL: https://harbor.example.com harborAdminPassword: your_secure_password persistence: persistentVolumeClaim: registry: size: 1Ti chartmuseum: enabled: false notary: enabled: false trivy: enabled: false4. 部署过程中的典型问题解决4.1 镜像拉取失败排查流程当出现ImagePullBackOff错误时检查事件详情kubectl describe pod -n kubeflow pod-name确认镜像路径是否正确检查Harbor网络连通性验证镜像是否真的存在curl -X GET https://harbor.example.com/v2/ml/image-path/manifests/tag \ -H Authorization: Basic $(echo -n admin:password | base64)4.2 组件特定问题解决方案Notebook报错403问题kubectl edit deployments.apps -n kubeflow jupyter-web-app-deployment # 修改环境变量 - name: APP_SECURE_COOKIES value: falseTensorBoard权限问题securityContext: runAsNonRoot: true runAsUser: 65532 runAsGroup: 65534MySQL初始化失败rm -rf /nfs/mysql-pv-claim/*5. 网络隔离下的持续维护5.1 离线环境下的PyPI管理建议搭建Devpi私有仓库# 服务端配置 devpi-server --start --init --serverdir /var/lib/devpi # 客户端使用 pip install --index-urlhttp://devpi.example.com:3141/root/pypi/simple/ \ --trusted-host devpi.example.com kserve5.2 版本升级策略在新环境测试完整流程使用diff工具对比yaml变更diff -r manifests-1.7.0 manifests-1.8.0特别注意CRD的变化提前备份关键数据velero backup create kubeflow-backup --include-namespaces kubeflow6. 性能优化实战建议6.1 资源分配黄金比例根据节点数量推荐配置3节点集群16C32Gistio: pilot: resources: requests: cpu: 2 memory: 4Gi5节点集群32C64Gkatib: controller: resources: requests: cpu: 4 memory: 8Gi6.2 存储性能调优对于训练任务密集的场景persistentVolume: accessModes: - ReadWriteMany nfs: server: 192.168.1.100 path: /data/kubeflow mountOptions: - hard - nfsvers4.1 - noatime