3. 环境准备:Python环境、Docker、Kubernetes、云服务基础
3.1 核心原理:MLOps 环境的分层模型
MLOps 平台并非单一软件,而是一套需要协同运作的技术栈。在动手安装任何工具之前,必须先理解其底层逻辑:环境分层。从下至上依次为:基础设施层(云服务或裸金属)、容器编排层(Kubernetes)、容器运行时层(Docker)、应用依赖层(Python 虚拟环境)。每一层都为其上一层提供抽象与隔离,任何一层的配置失误都会向上传导,最终表现为模型服务异常或 CI/CD 流水线中断。
Python 环境解决的是依赖隔离问题——不同项目可能依赖同一库的不同版本;Docker 解决的是环境一致性问题——将 Python 环境连同系统库、配置一起打包成镜像;Kubernetes 解决的是资源调度与弹性问题——让多个容器副本可以自动部署、伸缩和自愈;云服务则提供托管的基础设施组件——对象存储、托管数据库、负载均衡器等,避免重复造轮子。
3.2 方法流程:四步搭建本地开发环境
推荐采用“由内向外”的顺序搭建环境——先解决 Python 依赖,再容器化,最后接入 Kubernetes 和云服务。这样可以尽早暴露代码层面的兼容性问题,避免在容器和集群层面排查低级错误。
步骤一:Python 虚拟环境配置
使用 venv 创建隔离环境,并锁定依赖版本。建议使用 pyproject.toml 或 requirements.txt 管理依赖,确保可复现性。
# 创建虚拟环境(Python 3.10+)
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# 升级 pip 并安装核心工具
pip install --upgrade pip setuptools wheel
pip install "mlflow==2.12.1" "pytest==8.0.0" "pre-commit==3.6.0"
# 导出依赖清单
pip freeze > requirements.txt
pip install -r requirements.txt 时,务必指定 --no-cache-dir 避免缓存污染;同时将 Python 版本固定为 3.10.x,因为部分 ML 库(如 TensorFlow)对 3.11+ 的支持可能滞后。
步骤二:Docker 镜像构建
编写 Dockerfile 时,应遵循分层缓存原则:先复制依赖清单文件,再安装依赖,最后复制源代码。这样当源码变更时,可以复用已缓存的依赖层,显著加速构建。
# Dockerfile 示例(面向 ML 训练任务)
FROM python:3.10-slim
WORKDIR /app
# 先复制依赖清单,利用 Docker 层缓存
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 再复制源代码
COPY src/ ./src/
COPY models/ ./models/
# 非 root 用户运行(安全加固)
RUN useradd -m mluser
USER mluser
CMD ["python", "src/train.py"]
步骤三:Kubernetes 本地集群
本地开发推荐使用 kind(Kubernetes in Docker)或 minikube。kind 更轻量,适合 CI 环境;minikube 功能更全,适合本地交互调试。
# 使用 kind 创建本地集群
kind create cluster --name mlops-dev --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
extraMounts:
- hostPath: /data/models
containerPath: /models
EOF
# 验证集群状态
kubectl cluster-info --context kind-mlops-dev
kubectl get nodes
步骤四:云服务对接
以阿里云或 AWS 为例,核心是配置 IAM 凭证与环境变量。切勿将密钥硬编码到代码或镜像中,应使用云厂商的密钥管理服务(如 AWS Secrets Manager 或阿里云 KMS)。
# 配置云服务 CLI(以阿里云为例)
aliyun configure --mode AK
# 设置 AccessKey ID / Secret / Region
# 通过环境变量注入运行时配置
export MLFLOW_TRACKING_URI="http://mlflow-server:5000"
export AWS_ACCESS_KEY_ID="$(cat /etc/secret/access-key)"
export AWS_SECRET_ACCESS_KEY="$(cat /etc/secret/secret-key)"
3.3 案例场景:从零搭建一个可复现的 ML 训练环境
假设团队需要训练一个图像分类模型,要求环境可复现、可迁移到云端 GPU 集群。以下是完整的操作链路:
- 本地 Python 环境:创建
.venv,安装torch==2.1.0、torchvision==0.16.0、mlflow,导出requirements.txt。 - Docker 化:基于
pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime基础镜像,安装项目依赖,将训练脚本打包为镜像registry.cn-hangzhou.aliyuncs.com/team/trainer:1.0.0。 - Kubernetes 部署:编写
train-job.yaml,使用Job资源运行一次性训练任务,挂载 PVC 存储模型输出。 - 云服务集成:将训练日志输出到云日志服务,模型产物保存到对象存储,通过 MLflow 记录实验参数。
| 层级 | 工具/服务 | 关键配置项 | 验证命令 |
|---|---|---|---|
| Python | venv + pip | Python 3.10, requirements.txt | python -c "import torch; print(torch.__version__)" |
| Docker | Docker Engine 24+ | 基础镜像、非root用户 | docker run --rm trainer:1.0.0 python -c "import torch" |
| Kubernetes | kind / minikube | 资源配额、PVC、节点亲和性 | kubectl logs job/train-job |
| 云服务 | OSS/S3 + IAM | Bucket 权限、生命周期规则 | aws s3 ls s3://ml-models/ |
3.4 常见误区与复盘
误区二:忽略 Kubernetes 资源配额。在本地开发时,如果未设置 resources.requests 和 limits,训练任务可能耗尽节点内存导致 OOMKilled。复盘发现,应在 Job 定义中显式声明:
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
nvidia.com/gpu: 1
memory: "8Gi"
误区三:云服务凭证直接写入镜像。某团队将 AccessKey 写入 Dockerfile 的环境变量,导致镜像推送到公共仓库后密钥泄露。复盘结论:必须使用 Kubernetes Secret 或云厂商的 IAM Role 进行临时凭证注入,并启用审计日志追踪访问行为。
误区四:Python 依赖未锁定传递依赖。仅锁定直接依赖版本,导致某次 pip install 拉取了不兼容的传递依赖,模型训练结果出现微小偏差。复盘后改用 pip-tools 生成完整的 requirements.lock 文件,并在 CI 中校验哈希值。
dvc 或 mlflow 记录数据与模型的环境指纹。建议在团队内推行“环境即代码”文化,所有环境配置均以声明式文件(Dockerfile、YAML、pyproject.toml)管理,杜绝手工操作。