运行 Stable Diffusion webui 文生图推理服务
本示例演示如何在 Kubernetes 上部署 Stable Diffusion webui 提供一个完备推理服务。
前提
- 本地已经安装命令行工具 kubectl (opens in a new tab)
- 获取了 kubeconfig
存储 PVC
利用持久卷可确保文件持久存在,即使当前运行 Pod 的节点失败。在此示例中,分配了持久卷以保留模型和前端用户数据。
通过 Kubernetes PersistentVolumeClaim 进行持久卷存储的分配,通常称为 PVC,它请求存储大小和要使用的后端存储类型(例如: shared-nvme)。在此示例中,PVC 在 pvc.yaml
文件中定义。
pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: models
spec:
storageClassName: shared-nvme
accessModes:
- ReadWriteMany
resources:
requests:
storage: 30Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: extensions
spec:
storageClassName: shared-nvme
accessModes:
- ReadWriteMany
resources:
requests:
storage: 30Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: outputs
spec:
storageClassName: shared-nvme
accessModes:
- ReadWriteMany
resources:
requests:
storage: 30Gi
部署 Deployment
在这个例子中,使用一个 Kubernetes manifests 来部署一个包含 Stable Diffusion webui 前端和后端推理服务。
metadata.labels
用于为 Pod 设置上标签,selector.matchLabels
用于为 Deployment 选中标签为name: sd
的 Pod 进行控制spec.containers
描述 Container- 一个名字为
sdw
的 Container 用于提供推理 API + WebUI 服务- 把 models pvc 挂在 Container 内的
/app/stable-diffusion-webui/models
目录下存放模型文件 - 把 extensions pvc 挂在 Container 内的
/app/stable-diffusion-webui/extensions
目录下存放扩展组件 - 把 outputs pvc 挂在 Container 内的
/app/stable-diffusion-webui/outputs
目录下存放输出数据 - 配置 HF_ENDPOINT 代理,用于连接 huggingface 下载模型数据
- 申请并限制 8 vCPU, 24Gi 内存和 1 个 GPU
- 把 models pvc 挂在 Container 内的
- 一个名字为
spec.volumes
描述使用上面创建 pvc 持久卷spec.tolerations
描述容忍nvidia.com/gpu
污点存在,即可以使用 GPU 节点。通常在 K8S 使用污点以确保 Pod (例如纯 CPU 负载) 不会被调度到不适当节点上。spec.affinity
描述节点亲和性,用于控制偏好或者必须使用那些类型的节点,例如示例必须使用 RTX 4090 节点
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sd-webui
namespace: sd
spec:
selector:
matchLabels:
name: sd
template:
metadata:
labels:
name: sd
spec:
containers:
- name: sd
image: siutin/stable-diffusion-webui-docker:cuda-v1.9.4-2024-06-12
command: ["bash", "webui.sh", "--share", "--listen", "--log-startup", "--gradio-debug", "--loglevel=DEBUG"]
env:
- name: HF_ENDPOINT
value: https://hf-mirror.com
imagePullPolicy: IfNotPresent
resources:
limits:
nvidia.com/gpu: 1
ports:
- name: sd-webui
containerPort: 7860
protocol: TCP
volumeMounts:
- name: models
subPath: models
mountPath: /app/stable-diffusion-webui/models
- name: extensions
subPath: extensions
mountPath: /app/stable-diffusion-webui/extensions
- name: outputs
subPath: outputs
mountPath: /app/stable-diffusion-webui/outputs
volumes:
- name: models
persistentVolumeClaim:
claimName: models
- name: extensions
persistentVolumeClaim:
claimName: extensions
- name: outputs
persistentVolumeClaim:
claimName: outputs
securityContext:
fsGroup: 10000
tolerations:
- key: nvidia.com/gpu
operator: Exists
服务 Service
提供一个集群内的负载均衡器到 Stable Diffusion webui 容器实例。
下面示例是:
- 使用
selector
选中标签为name: sd
的 Pod - Pod 端口名字为
targetPort: sd-webui
(对应 Deployment 中的定义) - 并以
port: 7860
及名字name: http
提供集群内type: ClusterIP
的负载均衡服务
service.yaml
apiVersion: v1
kind: Service
metadata:
name: sd-webui
spec:
type: ClusterIP
selector:
name: sd
ports:
- port: 7860
name: http
targetPort: sd-webui
protocol: TCP
入口 Ingress
Ingress 用于暴露应用程序到互联网,从而通过 https 协议访问应用程序。
下面示例是:
- 将
rules.host: sd.wh-389a8e0c7dfc.ing.zw1.paratera.com
- 路由
path: /
- 到 Service
name: sd-webui
的port: 7860
- 同时开启
spec.tls
并设置自动申请cert-manager.io/cluster-issuer: zerossl-prod
证书
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sd-ingress
annotations:
cert-manager.io/cluster-issuer: zerossl-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- sd.wh-389a8e0c7dfc.ing.zw1.paratera.com
secretName: sd-tls
rules:
- host: sd.wh-389a8e0c7dfc.ing.zw1.paratera.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sd-webui
port:
number: 7860
运行示例
-
部署
kubectl apply -f pvc.yaml kubectl apply -f deployment.yaml kubectl apply -f service.yaml kubectl apply -f ingress.yaml
-
查看已创建 Pod
kubectl get pods
等待 Pod 进入 Running 状态.
如果 Pod 一直不能进入 Running,可以通过下面的命令查看 Pod 的详细信息
kubectl describe pod [pod_id]
-
查看 Ingress
kubectl get ing
如果 Ingress 准备好,一般在输出 ADDRESS 字段会分配一个 IP 地址
-
访问服务
使用从 Ingress 获取 Hosts 地址,然后在浏览器中访问。
🎉 恭喜!您已在 Kubernetes 上部署一个带 UI 的 Stable Diffusion 推理服务了!