Stable Yogi Leather-Dress-Collection持续集成/部署:使用Docker与K8s管理模型服务

张开发
2026/5/28 19:32:39 15 分钟阅读
Stable Yogi Leather-Dress-Collection持续集成/部署:使用Docker与K8s管理模型服务
Stable Yogi Leather-Dress-Collection持续集成/部署使用Docker与K8s管理模型服务你是不是也遇到过这样的烦恼好不容易在本地把那个能生成各种皮革连衣裙设计图的AI模型——Stable Yogi Leather-Dress-Collection——给调通了效果也挺满意。但一到要把它放到服务器上给团队或者用户用的时候问题就来了环境依赖怎么装版本冲突怎么解决服务挂了怎么自动重启流量大了怎么扩容这些问题单靠手动操作不仅效率低还容易出错。今天我就来跟你聊聊怎么用Docker和Kubernetes简称K8s这套组合拳把我们的AI模型服务管得服服帖帖实现从代码提交到服务上线的自动化流水线。这就像给你的模型服务请了个“全能管家”部署、更新、扩容、监控它全包了。1. 为什么需要CI/CD和容器化在聊具体怎么做之前咱们先得搞清楚为啥要折腾这些。你想想看传统的部署方式是不是这样找台服务器照着文档一步步装Python、装CUDA、装各种奇奇怪怪的库版本还得对上。好不容易装好了换台机器又得重来一遍。更头疼的是如果模型更新了你得手动去每台服务器上操作万一漏了哪台服务就可能不一致。Docker的出现就是为了解决“在我机器上能跑到你那就跑不起来”这个经典难题。它把应用和它需要的所有环境打包成一个叫“镜像”的盒子。这个盒子在任何支持Docker的机器上打开里面的应用都能以一模一样的方式运行。对于我们的Stable Yoji模型来说这意味着再也不用担心服务器环境差异了。而Kubernetes则是管理这些Docker盒子的“超级调度员”。当你有成百上千个服务盒子在运行时K8s能帮你自动安排它们在哪台机器上运行调度某个盒子挂了能自动重启自愈流量大了能自动复制更多盒子出来伸缩还能在不中断服务的情况下更新盒子里的内容滚动更新。把这两者结合起来再配上持续集成/持续部署CI/CD的流程就构成了一套完整的DevOps实践。简单说就是开发者提交代码后自动打包成Docker镜像然后自动部署到K8s集群里。整个过程无需人工干预又快又稳。2. 第一步将Stable Yogi服务Docker化万事开头难咱们先从把模型服务装进“盒子”开始。这里假设你已经有一个能本地运行的Stable Yogi模型Web服务比如用FastAPI写的一个接口。2.1 编写DockerfileDockerfile就像是制作“盒子”的说明书。我们在项目根目录创建一个名为Dockerfile的文件没有后缀名。# 使用一个包含CUDA和Python的官方基础镜像确保能跑深度学习模型 FROM nvidia/cuda:12.1.1-runtime-ubuntu22.04 # 设置工作目录 WORKDIR /app # 安装系统依赖和Python RUN apt-get update apt-get install -y \ python3-pip \ python3-dev \ rm -rf /var/lib/apt/lists/* # 将本地的依赖文件复制到容器内 COPY requirements.txt . # 安装Python依赖使用清华镜像加速 RUN pip3 install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt # 将整个项目代码复制到容器内 COPY . . # 暴露服务运行的端口假设你的FastAPI服务跑在7860端口 EXPOSE 7860 # 设置容器启动时执行的命令 CMD [python3, app/main.py]这个Dockerfile做了几件事选了一个带CUDA的Ubuntu系统作为底板。在“盒子”里安装了Python和pip。根据requirements.txt安装了所有Python库。把我们的代码全部放进“盒子”。告诉外界服务在7860端口。设定好“盒子”一启动就运行我们的主程序。注意你的requirements.txt需要包含fastapi,uvicorn,torch以及Stable Yogi模型所需的所有库。2.2 构建与测试Docker镜像说明书写好了现在来制作“盒子”也就是镜像。打开终端进入项目目录执行构建命令# -t 给镜像打个标签名字叫stable-yogi版本是v1.0 # . 表示Dockerfile在当前目录 docker build -t stable-yogi:v1.0 .这个过程可能会花点时间因为它要下载基础镜像和安装所有依赖。构建成功后你可以用下面的命令看看镜像是否在本地docker images | grep stable-yogi接下来我们运行这个“盒子”测试一下# -p 将容器的7860端口映射到主机的9000端口 # --gpus all 让容器能使用主机的GPU确保主机有NVIDIA驱动和Docker GPU支持 docker run --gpus all -p 9000:7860 --name yogi-test stable-yogi:v1.0如果一切正常你应该能在终端看到服务启动的日志。打开浏览器访问http://你的服务器IP:9000/docs就能看到FastAPI自动生成的API文档界面了。试着调用一下生成皮革连衣裙的接口看看功能是否正常。测试完毕后可以停止并删除这个测试容器docker stop yogi-test docker rm yogi-test3. 第二步使用Kubernetes编排与管理服务现在我们的模型服务已经完美地打包进了Docker镜像。接下来就要请出“超级调度员”K8s来管理这个服务的生老病死了。你需要一个K8s集群可以是云服务商提供的如阿里云ACK、腾讯云TKE也可以是自己用kubeadm搭建的。3.1 创建核心配置文件Deployment在K8s里Deployment是用来定义和管理一组完全相同Pod可以理解为一个或多个容器的主要对象。它保证了指定数量的Pod副本始终运行。创建一个文件叫deployment.yamlapiVersion: apps/v1 kind: Deployment metadata: name: stable-yogi-deployment labels: app: stable-yogi spec: replicas: 2 # 我们希望始终有2个副本在运行 selector: matchLabels: app: stable-yogi template: # 这是Pod的模板 metadata: labels: app: stable-yogi spec: containers: - name: stable-yogi-container image: stable-yogi:v1.0 # 使用我们刚才构建的镜像 imagePullPolicy: IfNotPresent # 如果本地有镜像就不去远程拉取 ports: - containerPort: 7860 # 容器内部端口 resources: limits: nvidia.com/gpu: 1 # 申请1块GPU需要集群有GPU设备插件 memory: 8Gi cpu: 2 requests: memory: 4Gi cpu: 1 livenessProbe: # 存活探针检查容器是否活着 httpGet: path: /health # 假设你的服务有健康检查接口 port: 7860 initialDelaySeconds: 30 # 容器启动30秒后开始检查 periodSeconds: 10 # 每10秒检查一次 readinessProbe: # 就绪探针检查容器是否准备好接收流量 httpGet: path: /ready port: 7860 initialDelaySeconds: 5 periodSeconds: 5这个配置文件定义了一个部署名字叫stable-yogi-deployment。始终维持2个副本Pod。每个Pod里运行一个容器使用我们本地的stable-yogi:v1.0镜像。为每个容器申请了1块GPU、2核CPU和8Gi内存的限制。配置了健康检查K8s会根据这个探针自动重启不健康的容器。3.2 创建服务访问配置ServicePod的IP地址是不固定的而且外部无法直接访问。我们需要一个Service来为这组Pod提供一个稳定的访问入口。创建一个文件叫service.yamlapiVersion: v1 kind: Service metadata: name: stable-yogi-service spec: selector: app: stable-yogi # 选择所有标签为app: stable-yogi的Pod ports: - port: 80 # Service对外的端口 targetPort: 7860 # 转发到Pod的哪个端口 protocol: TCP type: LoadBalancer # 类型可以是ClusterIP集群内访问、NodePort节点端口、LoadBalancer云负载均衡器LoadBalancer类型通常用于云服务商它会自动创建一个外部负载均衡器并分配一个公网IP这样你就能从互联网访问你的模型服务了。3.3 部署到Kubernetes集群假设你已经配置好kubectl命令行工具并连接到了你的K8s集群现在可以部署了# 应用Deployment配置 kubectl apply -f deployment.yaml # 应用Service配置 kubectl apply -f service.yaml部署后可以检查一下状态# 查看Deployment状态 kubectl get deployments # 查看Pod状态应该能看到2个Running的Pod kubectl get pods # 查看Service状态如果是LoadBalancerEXTERNAL-IP列会显示公网IP可能需要等待一会儿 kubectl get svc当Service获得外部IP后你就可以通过http://EXTERNAL-IP/docs来访问你的模型服务了。4. 第三步实现自动化CI/CD流水线手动构建镜像、更新配置还是太麻烦。我们的目标是当我向代码仓库比如GitLab或GitHub提交新代码时自动完成所有部署步骤。这里以GitHub Actions为例。4.1 推送镜像到镜像仓库首先需要把Docker镜像推送到一个公共或私有的镜像仓库如Docker Hub、阿里云容器镜像服务ACR。我们修改一下构建和推送的步骤。假设你使用Docker Hub先登录docker login然后重新构建并打上带仓库地址的标签docker build -t yourdockerhub/stable-yogi:v1.0 . docker push yourdockerhub/stable-yogi:v1.0同时需要修改deployment.yaml中的镜像地址image: yourdockerhub/stable-yogi:v1.04.2 配置GitHub Actions自动化流程在项目根目录创建.github/workflows/cicd-pipeline.yaml文件name: CI/CD Pipeline for Stable Yogi on: push: branches: [ main ] # 当代码推送到main分支时触发 jobs: build-and-push: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Set up Docker Buildx uses: docker/setup-buildx-actionv2 - name: Log in to Docker Hub uses: docker/login-actionv2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push Docker image uses: docker/build-push-actionv4 with: context: . push: true tags: | yourdockerhub/stable-yogi:latest yourdockerhub/stable-yogi:${{ github.sha }} deploy-to-k8s: needs: build-and-push # 等待构建任务完成 runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Set up Kubeconfig run: | echo ${{ secrets.KUBE_CONFIG }} | base64 -d kubeconfig.yaml export KUBECONFIGkubeconfig.yaml - name: Deploy to Kubernetes run: | # 更新deployment.yaml中的镜像标签为本次提交的SHA sed -i s|yourdockerhub/stable-yogi:.*|yourdockerhub/stable-yogi:${{ github.sha }}| deployment.yaml kubectl apply -f deployment.yaml kubectl apply -f service.yaml # 执行滚动更新K8s会逐步用新Pod替换旧Pod kubectl rollout status deployment/stable-yogi-deployment这个流水线做了两件事构建与推送在代码推送后自动构建Docker镜像并推送到Docker Hub同时打上latest和本次提交ID两个标签。部署到K8s使用存储在GitHub Secrets中的K8s集群凭证KUBE_CONFIG更新Deployment中的镜像版本并触发K8s的滚动更新。你需要在GitHub仓库的Settings - Secrets中配置DOCKER_USERNAME,DOCKER_PASSWORD和KUBE_CONFIG后者是你的kubeconfig文件内容经过base64编码后的字符串。从此以后你只需要专注写代码提交到main分支剩下的构建、测试、部署全由这条流水线自动完成。5. 进阶弹性伸缩与监控基础管线搭好了我们再来看看如何让它更智能、更可靠。5.1 配置HPA实现弹性伸缩如果突然有很多用户来生成皮革连衣裙2个Pod可能扛不住。我们可以配置Horizontal Pod AutoscalerHPA让K8s根据CPU或内存使用率自动增减Pod数量。# 创建一个HPA目标Deployment是stable-yogi-deploymentCPU利用率目标为50%Pod数量在1到5之间自动调整 kubectl autoscale deployment stable-yogi-deployment --cpu-percent50 --min1 --max5或者使用YAML文件定义更复杂的规则hpa.yamlapiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: stable-yogi-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: stable-yogi-deployment minReplicas: 1 maxReplicas: 5 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 505.2 添加基础监控与日志服务跑起来我们还得知道它跑得怎么样。查看日志# 查看某个Pod的日志 kubectl logs pod-name # 持续查看日志类似tail -f kubectl logs -f pod-name # 查看指定Deployment所有Pod的日志 kubectl logs -l appstable-yogi --tail50监控资源使用 K8s自带基础监控。你可以使用kubectl top命令查看资源使用情况kubectl top pods kubectl top nodes对于生产环境建议集成更强大的监控系统如Prometheus收集指标 Grafana展示仪表盘以及EFK/ELK栈收集和分析日志。这些工具的部署稍微复杂一些但能让你对服务的健康状况了如指掌。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章