Stable Yogi Leather-Dress-Collection持续集成/部署:使用Docker与K8s管理模型服务
2026/4/16 18:48:44 网站建设 项目流程

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 编写Dockerfile

Dockerfile就像是制作“盒子”的说明书。我们在项目根目录创建一个名为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做了几件事:

  1. 选了一个带CUDA的Ubuntu系统作为底板。
  2. 在“盒子”里安装了Python和pip。
  3. 根据requirements.txt安装了所有Python库。
  4. 把我们的代码全部放进“盒子”。
  5. 告诉外界,服务在7860端口。
  6. 设定好“盒子”一启动,就运行我们的主程序。

注意:你的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-test

3. 第二步:使用Kubernetes编排与管理服务

现在我们的模型服务已经完美地打包进了Docker镜像。接下来,就要请出“超级调度员”K8s,来管理这个服务的生老病死了。你需要一个K8s集群,可以是云服务商提供的(如阿里云ACK、腾讯云TKE),也可以是自己用kubeadm搭建的。

3.1 创建核心配置文件:Deployment

在K8s里,Deployment是用来定义和管理一组完全相同Pod(可以理解为一个或多个容器)的主要对象。它保证了指定数量的Pod副本始终运行。

创建一个文件叫deployment.yaml

apiVersion: 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 创建服务访问配置:Service

Pod的IP地址是不固定的,而且外部无法直接访问。我们需要一个Service来为这组Pod提供一个稳定的访问入口。

创建一个文件叫service.yaml

apiVersion: 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状态,如果是LoadBalancer,EXTERNAL-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.0

4.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/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log in to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push Docker image uses: docker/build-push-action@v4 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/checkout@v3 - name: Set up Kubeconfig run: | echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig.yaml export KUBECONFIG=kubeconfig.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

这个流水线做了两件事:

  1. 构建与推送:在代码推送后,自动构建Docker镜像,并推送到Docker Hub,同时打上latest和本次提交ID两个标签。
  2. 部署到K8s:使用存储在GitHub Secrets中的K8s集群凭证(KUBE_CONFIG),更新Deployment中的镜像版本,并触发K8s的滚动更新。

你需要在GitHub仓库的Settings -> Secrets中配置DOCKER_USERNAME,DOCKER_PASSWORDKUBE_CONFIG(后者是你的kubeconfig文件内容经过base64编码后的字符串)。

从此以后,你只需要专注写代码,提交到main分支,剩下的构建、测试、部署全由这条流水线自动完成。

5. 进阶:弹性伸缩与监控

基础管线搭好了,我们再来看看如何让它更智能、更可靠。

5.1 配置HPA实现弹性伸缩

如果突然有很多用户来生成皮革连衣裙,2个Pod可能扛不住。我们可以配置Horizontal Pod Autoscaler(HPA),让K8s根据CPU或内存使用率自动增减Pod数量。

# 创建一个HPA,目标Deployment是stable-yogi-deployment,CPU利用率目标为50%,Pod数量在1到5之间自动调整 kubectl autoscale deployment stable-yogi-deployment --cpu-percent=50 --min=1 --max=5

或者,使用YAML文件定义更复杂的规则(hpa.yaml):

apiVersion: 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: 50

5.2 添加基础监控与日志

服务跑起来,我们还得知道它跑得怎么样。

查看日志

# 查看某个Pod的日志 kubectl logs <pod-name> # 持续查看日志(类似tail -f) kubectl logs -f <pod-name> # 查看指定Deployment所有Pod的日志 kubectl logs -l app=stable-yogi --tail=50

监控资源使用: K8s自带基础监控。你可以使用kubectl top命令查看资源使用情况:

kubectl top pods kubectl top nodes

对于生产环境,建议集成更强大的监控系统,如Prometheus(收集指标) + Grafana(展示仪表盘),以及EFK/ELK栈(收集和分析日志)。这些工具的部署稍微复杂一些,但能让你对服务的健康状况了如指掌。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询