stable-diffusion-webui-docker K8s Helm Chart:包管理与部署简化

stable-diffusion-webui-docker K8s Helm Chart:包管理与部署简化

【免费下载链接】stable-diffusion-webui-docker Easy Docker setup for Stable Diffusion with user-friendly UI 【免费下载链接】stable-diffusion-webui-docker 项目地址: https://gitcode.com/gh_mirrors/st/stable-diffusion-webui-docker

引言:容器化部署的痛点与解决方案

你是否在部署 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

这种方案存在以下局限性:

  1. 环境配置管理复杂:通过环境变量和 profiles 实现的环境差异化,在多环境场景下难以维护
  2. 资源调度能力有限:仅支持简单的资源预留,无法实现复杂的资源调度和自动扩缩容
  3. 部署流程手动化:缺乏自动化部署和版本控制机制
  4. 扩展性受限:难以集成监控、日志等 Kubernetes 生态系统组件

为什么选择 Helm Chart?

Helm 是 Kubernetes 的包管理工具,它提供了以下优势:

  1. 标准化部署:通过 Chart 封装应用的所有 Kubernetes 资源,实现标准化部署
  2. 配置模板化:使用 Go 模板引擎实现配置的动态生成,支持多环境差异化
  3. 版本管理:支持 Chart 版本控制,便于回滚和升级
  4. 依赖管理:可以定义和管理 Chart 之间的依赖关系
  5. 钩子机制:支持在部署的不同阶段执行自定义脚本,如数据库迁移、初始化等

Docker Compose 与 Helm Chart 对比

特性Docker ComposeHelm 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 资源至关重要:

  1. GPU 共享:在开发环境中,可以使用 GPU 共享技术(如 Time-Slicing)提高 GPU 利用率:
# values-dev.yaml
resources:
  limits:
    nvidia.com/gpu: 0.5  # 共享 GPU,分配 50% 的资源
  requests:
    nvidia.com/gpu: 0.5
  1. 多 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"

存储优化

  1. 使用高性能存储:对于模型数据和输出目录,使用高性能存储类:
persistence:
  data:
    storageClass: "nfs-high-performance"
  output:
    storageClass: "nfs-high-performance"
  1. 缓存策略:利用 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 监控

  1. 添加监控注解
podAnnotations:
  prometheus.io/scrape: "true"
  prometheus.io/path: "/metrics"
  prometheus.io/port: "7860"
  1. Grafana Dashboard:可以导入 Stable Diffusion 专用的 Grafana Dashboard,监控生成速度、GPU 利用率等指标。

日志管理

  1. 配置日志输出:确保应用输出结构化日志:
env:
  - name: LOG_LEVEL
    value: "INFO"
  - name: LOG_FORMAT
    value: "json"
  1. 集成 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,实现了:

  1. 标准化部署:通过 Helm Chart 实现了部署流程的标准化,简化了部署过程
  2. 多环境支持:通过环境特定的 Values 文件,实现了开发、测试、生产环境的差异化部署
  3. 资源优化:针对 GPU 资源进行了优化配置,提高了资源利用率
  4. 自动化部署:集成 CI/CD 流程,实现了自动化测试和部署
  5. 可扩展性:利用 Kubernetes 的特性,实现了应用的自动扩缩容和高可用

未来改进方向

  1. 高级调度策略:结合 Volcano 等高级调度器,实现更优的 GPU 资源调度
  2. 模型管理:集成模型版本管理系统,实现模型的自动更新和回滚
  3. 性能监控:开发专用的性能监控指标和 Dashboard,优化生成性能
  4. 安全加固:实现更严格的安全策略,包括网络隔离、镜像安全扫描等
  5. 多租户支持:实现多租户隔离,支持多用户共享集群资源

结语

通过本文介绍的方法,你可以将 stable-diffusion-webui-docker 的部署流程标准化、自动化,提高系统的可靠性和可维护性。无论你是个人用户还是企业团队,Helm Chart 都能为你提供灵活、强大的部署解决方案。

如果你觉得本文对你有帮助,请点赞、收藏并关注作者,以获取更多关于 Stable Diffusion 和 Kubernetes 集成的技术文章。下期我们将介绍如何使用 Prometheus 和 Grafana 监控 Stable Diffusion 的性能指标,敬请期待!

【免费下载链接】stable-diffusion-webui-docker Easy Docker setup for Stable Diffusion with user-friendly UI 【免费下载链接】stable-diffusion-webui-docker 项目地址: https://gitcode.com/gh_mirrors/st/stable-diffusion-webui-docker

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值