stable-diffusion-webui-docker K8s Helm Chart:包管理与部署简化
引言:容器化部署的痛点与解决方案
你是否在部署 Stable Diffusion WebUI 时遇到过以下问题:复杂的 Docker Compose 配置难以维护?多环境部署时的配置差异难以管理?资源分配不合理导致性能瓶颈?本文将介绍如何使用 K8s Helm Chart 解决这些问题,实现 Stable Diffusion WebUI 的标准化、可扩展部署。
读完本文后,你将能够:
- 理解 Helm Chart 如何简化 stable-diffusion-webui-docker 的部署流程
- 掌握自定义 Helm Chart 的核心配置方法
- 实现多环境(开发、测试、生产)的差异化部署
- 优化资源分配以提高性能和稳定性
- 实现自动化部署和版本管理
背景:从 Docker Compose 到 Kubernetes
现有 Docker Compose 方案分析
当前 stable-diffusion-webui-docker 项目使用 Docker Compose 进行部署,其核心配置如下:
x-base_service: &base_service
ports:
- "${WEBUI_PORT:-7860}:7860"
volumes:
- &v1 ./data:/data
- &v2 ./output:/output
stop_signal: SIGKILL
tty: true
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ['0']
capabilities: [compute, utility]
services:
download:
build: ./services/download/
profiles: ["download"]
volumes:
- *v1
auto: &automatic
<<: *base_service
profiles: ["auto"]
build: ./services/AUTOMATIC1111
image: sd-auto:78
environment:
- CLI_ARGS=--allow-code --medvram --xformers --enable-insecure-extension-access --api
这种方案存在以下局限性:
- 环境配置管理复杂:通过环境变量和 profiles 实现的环境差异化,在多环境场景下难以维护
- 资源调度能力有限:仅支持简单的资源预留,无法实现复杂的资源调度和自动扩缩容
- 部署流程手动化:缺乏自动化部署和版本控制机制
- 扩展性受限:难以集成监控、日志等 Kubernetes 生态系统组件
为什么选择 Helm Chart?
Helm 是 Kubernetes 的包管理工具,它提供了以下优势:
- 标准化部署:通过 Chart 封装应用的所有 Kubernetes 资源,实现标准化部署
- 配置模板化:使用 Go 模板引擎实现配置的动态生成,支持多环境差异化
- 版本管理:支持 Chart 版本控制,便于回滚和升级
- 依赖管理:可以定义和管理 Chart 之间的依赖关系
- 钩子机制:支持在部署的不同阶段执行自定义脚本,如数据库迁移、初始化等
Docker Compose 与 Helm Chart 对比
| 特性 | Docker Compose | Helm Chart |
|---|---|---|
| 环境隔离 | 依赖 profiles 和环境变量 | 基于 Values 文件的多环境配置 |
| 资源管理 | 基础的 CPU/内存限制 | 细粒度的资源请求和限制,支持 GPU 调度 |
| 扩展性 | 有限,需手动配置 | 支持自动扩缩容、滚动更新 |
| 版本控制 | 无内置支持 | 完整的版本管理和回滚机制 |
| 生态系统 | 有限 | 丰富的 Kubernetes 生态系统集成 |
| 学习曲线 | 较低 | 较高,但长期收益显著 |
Helm Chart 设计与实现
Chart 目录结构设计
一个典型的 stable-diffusion-webui Helm Chart 目录结构如下:
stable-diffusion-webui/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── values-dev.yaml # 开发环境配置
├── values-prod.yaml # 生产环境配置
├── templates/ # 模板目录
│ ├── _helpers.tpl # 辅助模板
│ ├── deployment.yaml # Deployment 模板
│ ├── service.yaml # Service 模板
│ ├── ingress.yaml # Ingress 模板
│ ├── configmap.yaml # ConfigMap 模板
│ ├── secret.yaml # Secret 模板
│ ├── pvc.yaml # PersistentVolumeClaim 模板
│ └── NOTES.txt # 部署后提示信息
└── charts/ # 依赖 Chart
核心模板实现
1. Deployment 模板
Deployment 模板是 Helm Chart 的核心,负责定义应用的部署方式。以下是基于原有 Docker Compose 转换的 Deployment 模板:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "stable-diffusion-webui.fullname" . }}
labels:
{{- include "stable-diffusion-webui.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "stable-diffusion-webui.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "stable-diffusion-webui.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "stable-diffusion-webui.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
env:
- name: WEBUI_PORT
value: "{{ .Values.service.port }}"
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
{{- if .Values.gpu.enabled }}
- name: NVIDIA_VISIBLE_DEVICES
value: {{ .Values.gpu.deviceIds | join "," | quote }}
{{- end }}
args:
- python
- -u
- webui.py
- --listen
- --port
- "{{ .Values.service.port }}"
{{- range .Values.cliArgs }}
- {{ . }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /data
- name: output
mountPath: /output
{{- if .Values.config.enabled }}
- name: config
mountPath: /data/config/auto
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ .Values.persistence.data.claimName | default (include "stable-diffusion-webui.fullname" .) }}-data
- name: output
persistentVolumeClaim:
claimName: {{ .Values.persistence.output.claimName | default (include "stable-diffusion-webui.fullname" .) }}-output
{{- if .Values.config.enabled }}
- name: config
configMap:
name: {{ include "stable-diffusion-webui.fullname" . }}-config
{{- end }}
2. Service 模板
Service 模板定义了如何访问 Deployment 创建的 Pod:
apiVersion: v1
kind: Service
metadata:
name: {{ include "stable-diffusion-webui.fullname" . }}
labels:
{{- include "stable-diffusion-webui.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "stable-diffusion-webui.selectorLabels" . | nindent 4 }}
3. ConfigMap 模板
ConfigMap 用于管理应用的配置文件,替代原有 Docker Compose 中的环境变量和配置文件挂载:
{{- if .Values.config.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "stable-diffusion-webui.fullname" . }}-config
labels:
{{- include "stable-diffusion-webui.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.config.files }}
{{ $key }}: |
{{- $value | nindent 4 }}
{{- end }}
{{- end }}
4. PersistentVolumeClaim 模板
PVC 模板定义了应用需要的持久化存储:
{{- if .Values.persistence.enabled }}
{{- if .Values.persistence.data.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Values.persistence.data.claimName | default (include "stable-diffusion-webui.fullname" .) }}-data
labels:
{{- include "stable-diffusion-webui.labels" . | nindent 4 }}
spec:
accessModes:
{{- toYaml .Values.persistence.data.accessModes | nindent 4 }}
resources:
requests:
storage: {{ .Values.persistence.data.size }}
{{- with .Values.persistence.data.storageClass }}
storageClassName: {{ . }}
{{- end }}
{{- end }}
{{- if .Values.persistence.output.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Values.persistence.output.claimName | default (include "stable-diffusion-webui.fullname" .) }}-output
labels:
{{- include "stable-diffusion-webui.labels" . | nindent 4 }}
spec:
accessModes:
{{- toYaml .Values.persistence.output.accessModes | nindent 4 }}
resources:
requests:
storage: {{ .Values.persistence.output.size }}
{{- with .Values.persistence.output.storageClass }}
storageClassName: {{ . }}
{{- end }}
{{- end }}
{{- end }}
Values.yaml 配置
Values.yaml 是 Helm Chart 的配置中心,定义了可自定义的参数:
# Default values for stable-diffusion-webui.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: sd-auto
tag: "78"
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 7860
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources:
limits:
nvidia.com/gpu: 1
requests:
memory: "8Gi"
cpu: "2"
nvidia.com/gpu: 1
nodeSelector: {}
tolerations: []
affinity: {}
# GPU configuration
gpu:
enabled: true
deviceIds: ["0"]
# CLI arguments
cliArgs:
- --allow-code
- --medvram
- --xformers
- --enable-insecure-extension-access
- --api
# Environment variables
env: []
# - name: EXAMPLE_VAR
# value: "example value"
# Configuration files
config:
enabled: false
files: {}
# config.json: |
# {
# "key": "value"
# }
# Persistence configuration
persistence:
enabled: true
data:
enabled: true
size: "10Gi"
accessModes:
- ReadWriteOnce
storageClass: ""
claimName: ""
output:
enabled: true
size: "20Gi"
accessModes:
- ReadWriteOnce
storageClass: ""
claimName: ""
多环境部署策略
环境特定配置文件
为不同环境创建专用的 Values 文件:
values-dev.yaml (开发环境)
replicaCount: 1
resources:
limits:
nvidia.com/gpu: 1
requests:
memory: "4Gi"
cpu: "1"
nvidia.com/gpu: 1
persistence:
data:
size: "5Gi"
output:
size: "10Gi"
cliArgs:
- --allow-code
- --medvram
- --xformers
- --enable-insecure-extension-access
- --api
- --debug
values-prod.yaml (生产环境)
replicaCount: 3
resources:
limits:
nvidia.com/gpu: 1
requests:
memory: "16Gi"
cpu: "4"
nvidia.com/gpu: 1
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
persistence:
data:
size: "50Gi"
storageClass: "fast"
output:
size: "100Gi"
storageClass: "fast"
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: sd-webui.example.com
paths: ["/"]
tls:
- secretName: sd-webui-tls
hosts:
- sd-webui.example.com
config:
enabled: true
files:
config.json: |
{
"max_batch_size": 4,
"auto_launch_browser": false,
"show_progress_every_n_steps": 10
}
部署命令示例
开发环境部署
helm install sd-webui-dev ./stable-diffusion-webui \
-f ./stable-diffusion-webui/values-dev.yaml \
--namespace sd-dev --create-namespace
生产环境部署
helm install sd-webui-prod ./stable-diffusion-webui \
-f ./stable-diffusion-webui/values-prod.yaml \
--namespace sd-prod --create-namespace
升级部署
helm upgrade sd-webui-prod ./stable-diffusion-webui \
-f ./stable-diffusion-webui/values-prod.yaml \
--namespace sd-prod
回滚版本
# 查看历史版本
helm history sd-webui-prod --namespace sd-prod
# 回滚到指定版本
helm rollback sd-webui-prod 2 --namespace sd-prod
资源优化与性能调优
GPU 资源管理
Stable Diffusion 对 GPU 资源要求较高,合理配置 GPU 资源至关重要:
- GPU 共享:在开发环境中,可以使用 GPU 共享技术(如 Time-Slicing)提高 GPU 利用率:
# values-dev.yaml
resources:
limits:
nvidia.com/gpu: 0.5 # 共享 GPU,分配 50% 的资源
requests:
nvidia.com/gpu: 0.5
- 多 GPU 支持:在生产环境中,可以配置多 GPU 支持:
# values-prod.yaml
replicaCount: 2 # 部署两个副本,每个副本使用一个 GPU
resources:
limits:
nvidia.com/gpu: 1
requests:
nvidia.com/gpu: 1
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- stable-diffusion-webui
topologyKey: "kubernetes.io/hostname"
存储优化
- 使用高性能存储:对于模型数据和输出目录,使用高性能存储类:
persistence:
data:
storageClass: "nfs-high-performance"
output:
storageClass: "nfs-high-performance"
- 缓存策略:利用 Kubernetes 的 EmptyDir 缓存临时文件:
# 在 deployment.yaml 中添加
volumes:
- name: cache
emptyDir: {}
volumeMounts:
- name: cache
mountPath: /root/.cache
自动扩缩容配置
配置基于 GPU 利用率的自动扩缩容:
# values-prod.yaml
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
targetGPUUtilizationPercentage: 80
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
监控与日志
Prometheus + Grafana 监控
- 添加监控注解:
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "7860"
- Grafana Dashboard:可以导入 Stable Diffusion 专用的 Grafana Dashboard,监控生成速度、GPU 利用率等指标。
日志管理
- 配置日志输出:确保应用输出结构化日志:
env:
- name: LOG_LEVEL
value: "INFO"
- name: LOG_FORMAT
value: "json"
- 集成 EFK 栈:使用 Elasticsearch、Fluentd 和 Kibana 实现日志收集和分析:
podAnnotations:
fluentd.io/parser: "json"
fluentd.io/tag: "sd-webui"
自动化部署流程
GitLab CI/CD 配置示例
创建 .gitlab-ci.yml 文件,实现自动化部署:
stages:
- lint
- package
- deploy-dev
- test
- deploy-prod
variables:
CHART_NAME: stable-diffusion-webui
DEV_NAMESPACE: sd-dev
PROD_NAMESPACE: sd-prod
helm-lint:
stage: lint
image: alpine/helm:latest
script:
- helm lint ./$CHART_NAME
package-chart:
stage: package
image: alpine/helm:latest
script:
- helm package ./$CHART_NAME --version $CI_COMMIT_SHORT_SHA
artifacts:
paths:
- ./*.tgz
deploy-dev:
stage: deploy-dev
image: bitnami/kubectl:latest
script:
- kubectl config use-context $KUBE_CONTEXT
- kubectl create namespace $DEV_NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
- helm upgrade --install sd-webui-dev ./$CHART_NAME-$CI_COMMIT_SHORT_SHA.tgz -f ./$CHART_NAME/values-dev.yaml --namespace $DEV_NAMESPACE
dependencies:
- package-chart
only:
- develop
deploy-prod:
stage: deploy-prod
image: bitnami/kubectl:latest
script:
- kubectl config use-context $KUBE_CONTEXT
- kubectl create namespace $PROD_NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
- helm upgrade --install sd-webui-prod ./$CHART_NAME-$CI_COMMIT_SHORT_SHA.tgz -f ./$CHART_NAME/values-prod.yaml --namespace $PROD_NAMESPACE
dependencies:
- package-chart
only:
- main
when: manual
总结与展望
主要成果
本文介绍了如何将 stable-diffusion-webui-docker 从 Docker Compose 迁移到 Kubernetes Helm Chart,实现了:
- 标准化部署:通过 Helm Chart 实现了部署流程的标准化,简化了部署过程
- 多环境支持:通过环境特定的 Values 文件,实现了开发、测试、生产环境的差异化部署
- 资源优化:针对 GPU 资源进行了优化配置,提高了资源利用率
- 自动化部署:集成 CI/CD 流程,实现了自动化测试和部署
- 可扩展性:利用 Kubernetes 的特性,实现了应用的自动扩缩容和高可用
未来改进方向
- 高级调度策略:结合 Volcano 等高级调度器,实现更优的 GPU 资源调度
- 模型管理:集成模型版本管理系统,实现模型的自动更新和回滚
- 性能监控:开发专用的性能监控指标和 Dashboard,优化生成性能
- 安全加固:实现更严格的安全策略,包括网络隔离、镜像安全扫描等
- 多租户支持:实现多租户隔离,支持多用户共享集群资源
结语
通过本文介绍的方法,你可以将 stable-diffusion-webui-docker 的部署流程标准化、自动化,提高系统的可靠性和可维护性。无论你是个人用户还是企业团队,Helm Chart 都能为你提供灵活、强大的部署解决方案。
如果你觉得本文对你有帮助,请点赞、收藏并关注作者,以获取更多关于 Stable Diffusion 和 Kubernetes 集成的技术文章。下期我们将介绍如何使用 Prometheus 和 Grafana 监控 Stable Diffusion 的性能指标,敬请期待!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



