铜陵市网站建设_网站建设公司_代码压缩_seo优化
2025/12/19 7:32:53 网站建设 项目流程

基于K8s的高性能Web服务器构建实践

在AIGC浪潮席卷内容生产的今天,如何将强大的AI模型转化为稳定、可扩展的在线服务,已成为工程落地的核心挑战。尤其是文本到视频(T2V)这类计算密集型任务,既要保证生成质量,又要实现秒级响应和高并发处理——这对底层基础设施提出了极高要求。

我们选择Wan2.2-T2V-5B这款轻量级但高效的50亿参数模型作为切入点,尝试在一个基于消费级GPU的Kubernetes集群中,构建一套面向真实业务场景的高性能Web服务系统。目标很明确:让AI视频生成像调用普通API一样简单、可靠,并能随负载自动伸缩。

整个系统不仅需要完成基础部署,更要集成持久化存储、统一接入、自动扩缩容与全链路监控等关键能力。这不仅是技术组件的堆叠,更是一次对MLOps工程化思维的实战检验。


架构设计与环境准备

项目采用单Master双Worker的经典K8s架构,所有节点运行 CentOS 7.9,Kubernetes 版本为 v1.28,Docker 使用 24.0.2。两台 Worker 节点均配备 NVIDIA T4 GPU,用于承载模型推理负载。

各主机IP规划如下:

主机名IP 地址角色说明
master192.168.0.20Kubernetes 控制平面节点
worker1192.168.0.21工作节点(含 NVIDIA T4 GPU)
worker2192.168.0.22工作节点(含 NVIDIA T4 GPU)
nfs-server192.168.0.36NFS 文件共享服务器
harbor192.168.0.34私有容器镜像仓库
prometheus192.168.0.33Prometheus + Grafana 监控中心
ansible192.168.0.30运维自动化中控机

在正式搭建前,需确保所有节点的基础环境一致:关闭防火墙与SELinux是必须步骤,否则可能引发网络策略或挂载异常。

systemctl stop firewalld && systemctl disable firewalld sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

静态IP配置也需提前完成,避免因DHCP变动导致集群通信中断。以ens33接口为例:

BOOTPROTO=static ONBOOT=yes IPADDR=192.168.0.20 NETMASK=255.255.255.0 GATEWAY=192.168.0.2 DNS1=8.8.8.8 DNS2=114.114.114.114

重启网络服务后,务必通过pingssh验证连通性。


批量运维:Ansible 的引入

面对多节点协同管理的需求,手动操作显然不可持续。我们在独立主机ansible上部署 Ansible,实现对整个集群的批量控制。

首先生成SSH密钥对并分发至各目标主机:

ssh-keygen -t rsa -b 2048 ssh-copy-id master ssh-copy-id worker1 # ... 其他主机同理

随后安装 Ansible 并定义主机清单:

[masters] 192.168.0.20 [workers] 192.168.0.21 192.168.0.22 [nfs] 192.168.0.36 [harbor] 192.168.0.34 [prometheus] 192.168.0.33

使用ansible all -m ping测试连通性成功后,即可编写 Playbook 实现初始化脚本统一下发、软件包批量安装等任务。这种“声明式+幂等”的管理模式,极大降低了后期维护成本。


持久化存储:NFS 与 PV/PVC 设计

AI视频生成会产生大量输出文件,这些结果必须持久化保存且可供多个Pod共享访问。我们选用 NFS 作为共享存储方案,因其配置简单、兼容性好,非常适合中小规模部署。

nfs-server上安装并启动 NFS 服务:

yum install nfs-utils -y mkdir -p /nfs/videos && chmod 777 /nfs/videos

编辑/etc/exports允许子网内所有节点读写:

/nfs/videos 192.168.0.0/24(rw,sync,no_root_squash,no_all_squash)

导出并启用服务:

exportfs -arv systemctl restart nfs-server && systemctl enable nfs-server

在每个 K8s 节点上测试挂载:

mkdir /mnt/video-share mount -t nfs 192.168.0.36:/nfs/videos /mnt/video-share df -Th | grep nfs

确认无误后,在K8s中创建PV和PVC资源对象:

# pv-video.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-video-output spec: capacity: storage: 50Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs nfs: path: /nfs/videos server: 192.168.0.36
# pvc-video.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-video-output spec: accessModes: - ReadWriteMany resources: requests: storage: 20Gi storageClassName: nfs

应用后验证状态是否为Bound

kubectl apply -f pv-video.yaml kubectl apply -f pvc-video.yaml kubectl get pvc pvc-video-output

这一设计使得后续部署的模型服务可以安全地将视频写入统一目录,避免数据丢失或分散。


模型服务封装与镜像构建

Wan2.2-T2V-5B 模型本身是一个PyTorch项目,我们需要将其封装成可通过HTTP触发的微服务。为此,在worker1上开发一个轻量Go语言API层。

编写服务入口(main.go)

package main import ( "fmt" "log" "net/http" "os/exec" "time" ) func generateVideo(w http.ResponseWriter, r *http.Request) { prompt := r.URL.Query().Get("prompt") if prompt == "" { http.Error(w, "missing prompt", http.StatusBadRequest) return } outputPath := fmt.Sprintf("/shared/videos/%d.mp4", time.Now().Unix()) cmd := exec.Command("python", "/app/generate.py", "--prompt", prompt, "--output", outputPath) err := cmd.Run() if err != nil { http.Error(w, "generation failed: "+err.Error(), http.StatusInternalServerError) return } w.Write([]byte(fmt.Sprintf("Video generated at %s\n", outputPath))) } func healthz(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) } func main() { http.HandleFunc("/generate", generateVideo) http.HandleFunc("/healthz", healthz) log.Println("Server starting on :8080...") log.Fatal(http.ListenAndServe(":8080", nil)) }

其中/healthz是健康检查接口,供探针调用。

Dockerfile 构建镜像

使用 NVIDIA 官方 PyTorch 镜像为基础,预装依赖库:

FROM nvcr.io/nvidia/pytorch:23.10-py3 WORKDIR /app COPY . /app RUN pip install torch torchvision transformers diffusers flask pillow \ && chmod +x /app/start.sh EXPOSE 8080 ENTRYPOINT ["python", "server.py"]

注:generate.py为实际调用 HuggingFace Diffusers 加载 Wan2.2-T2V-5B 模型并执行推理的脚本。

构建并推送至私有 Harbor 仓库:

docker build -t 192.168.0.34:5001/ai/wan2.2-t2v-5b:v1 . docker login 192.168.0.34:5001 docker push 192.168.0.34:5001/ai/wan2.2-t2v-5b:v1

镜像托管于内部Harbor,既保障安全性,又提升拉取效率。


K8s部署:GPU支持与资源配置

要让Pod正确调度到GPU节点并使用显卡资源,必须先在所有Worker节点安装nvidia-container-toolkit

distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ sudo tee /etc/yum.repos.d/nvidia-docker.repo yum install -y nvidia-container-toolkit systemctl restart docker

接着创建带GPU限制的Deployment:

# deployment-wan22.yaml apiVersion: apps/v1 kind: Deployment metadata: name: wan22-t2v-deployment spec: replicas: 2 selector: matchLabels: app: wan22-t2v template: metadata: labels: app: wan22-t2v spec: containers: - name: wan22-t2v image: 192.168.0.34:5001/ai/wan2.2-t2v-5b:v1 ports: - containerPort: 8080 resources: limits: nvidia.com/gpu: 1 memory: "8Gi" cpu: "4" requests: nvidia.com/gpu: 1 memory: "6Gi" cpu: "2" volumeMounts: - name: video-storage mountPath: /shared/videos livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 3 volumes: - name: video-storage persistentVolumeClaim: claimName: pvc-video-output

这里的关键点包括:
- 显式声明nvidia.com/gpu: 1,确保调度器识别GPU需求;
- 设置合理的内存与CPU请求/限制,防止资源争抢;
- 挂载PVC实现视频输出持久化;
- 添加 Liveness 和 Readiness 探针,增强服务自愈能力。

部署后查看Pod分布情况:

kubectl apply -f deployment-wan22.yaml kubectl get pods -o wide | grep wan22

正常情况下,两个副本应分别运行在worker1worker2上。

再创建NodePort类型Service暴露端口:

# service-wan22.yaml apiVersion: v1 kind: Service metadata: name: wan22-service spec: selector: app: wan22-t2v type: NodePort ports: - protocol: TCP port: 8080 targetPort: 8080 nodePort: 31080
kubectl apply -f service-wan22.yaml

此时可通过任意Worker节点IP加31080端口访问服务。


统一接入:Ingress-Nginx 的部署与配置

NodePort虽然可用,但在生产环境中不够灵活。我们通过 Ingress 实现基于域名的统一入口管理。

使用 Helm 安装 Ingress-Nginx Controller:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm install ingress-nginx ingress-nginx/ingress-nginx \ --set controller.nodeSelector."node-role\.kubernetes\.io/master"="" \ --set service.type=NodePort

注意:若Master节点默认污点存在,需添加容忍或设置节点选择器。

然后定义Ingress规则:

# ingress-wan22.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: wan22-ingress annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: t2v.sanchuang.ai http: paths: - path: / pathType: Prefix backend: service: name: wan22-service port: number: 8080

应用后,在本地hosts添加解析:

192.168.0.21 t2v.sanchuang.ai

即可通过域名发起请求:

curl "http://t2v.sanchuang.ai/generate?prompt=a%20cat%20dancing%20in%20the%20rain" # 返回:Video generated at /shared/videos/1714567890.mp4

这种方式更贴近真实线上环境,也为未来多服务共用同一个LB打下基础。


自动扩缩容:HPA 的实现逻辑

当用户并发增加时,固定副本数可能导致响应延迟甚至超时。我们借助 HorizontalPodAutoscaler(HPA)实现基于CPU利用率的动态扩缩。

首先部署 Metrics Server,它是HPA获取指标的数据源:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

修改其Deployment配置,加入跳过证书验证选项(适用于测试环境):

args: - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP

等待几分钟后,验证指标采集是否正常:

kubectl top nodes kubectl top pods

接着创建HPA策略:

# hpa-wan22.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: wan22-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: wan22-t2v-deployment minReplicas: 2 maxReplicas: 6 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60

应用后观察HPA状态:

kubectl apply -f hpa-wan22.yaml kubectl get hpa -w

初始状态通常显示类似12%/60%,表示当前平均CPU使用率为12%,低于60%的目标阈值,因此不会扩容。


全链路监控:Prometheus + Grafana 搭建

没有监控的系统如同盲人驾车。我们独立部署 Prometheus 与 Grafana,实现从节点到应用层的全方位观测。

prometheus主机解压并安装二进制包:

wget https://github.com/prometheus/prometheus/releases/download/v2.43.0/prometheus-2.43.0.linux-amd64.tar.gz tar xvf prometheus-2.43.0.linux-amd64.tar.gz mv prometheus-2.43.0.linux-amd64 /opt/prometheus

配置 systemd 服务开机自启:

[Unit] Description=Prometheus After=network.target [Service] ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml Restart=always [Install] WantedBy=multi-user.target
systemctl daemon-reload systemctl start prometheus systemctl enable prometheus

关键在于prometheus.yml中的抓取配置:

scrape_configs: - job_name: 'kubernetes-nodes' kubernetes_sd_configs: - role: node relabel_configs: - source_labels: [__address__] regex: '(.*):10250' target_label: __address__ replacement: '${1}:9100' - job_name: 'wan22-service' static_configs: - targets: ['192.168.0.21:31080', '192.168.0.22:31080']

其中第一个任务通过Node Exporter采集节点资源使用率;第二个则直接轮询服务端口,可用于记录QPS、延迟等业务指标。

Grafana 安装同样简单:

yum install grafana-enterprise-9.1.2-1.x86_64.rpm -y systemctl start grafana-server systemctl enable grafana-server

登录http://192.168.0.33:3000,添加Prometheus为数据源,并导入社区流行的 Node Exporter 和 K8s 监控仪表板模板,即可获得直观的可视化视图。


性能压测与弹性验证

一切就绪后,使用ab工具模拟高并发请求,验证系统的稳定性与弹性表现。

安装工具:

yum install httpd-tools -y

发起1000次请求,保持50个并发连接:

ab -n 1000 -c 50 "http://t2v.sanchuang.ai/generate?prompt=a%20dog%20running"

同时开启监控面板,重点关注以下变化:

kubectl get hpa --watch kubectl top pods

理想情况下会看到:
- CPU利用率迅速上升,突破60%后HPA开始扩容;
- 新Pod陆续启动并加入服务,负载逐渐回落;
- Grafana中QPS曲线平稳上升,无明显错误率 spike;
- NFS共享目录持续生成新视频文件,命名唯一不冲突。

这表明整套系统具备良好的弹性和健壮性,能够应对突发流量冲击。


实践反思与演进建议

回顾整个部署过程,有几个关键经验值得总结:

  1. GPU驱动与CUDA版本匹配至关重要。初期曾因驱动版本过低导致容器内无法识别GPU设备,最终通过升级至CUDA 12.1配套驱动解决。

  2. NFS权限问题容易被忽视。若未设置no_root_squash,容器以root身份写入时会被映射为nobody,造成权限拒绝。建议生产环境结合UID/GID映射做精细化控制。

  3. 探针配置需合理延时。模型首次加载耗时较长(约30~60秒),若initialDelaySeconds设置过短,会导致Pod反复重启。根据实际warm-up时间调整是必要操作。

  4. 轻量化模型的价值凸显。尽管Wan2.2-T2V-5B画质不及百亿参数大模型,但其能在消费级GPU上实现秒级生成,非常适合快速原型验证、短视频模板生成等高频交互场景,性价比极高。

未来可进一步优化方向包括:
- 引入 Kafka 实现异步任务队列,避免长时间请求阻塞HTTP连接;
- 使用 Redis 缓存热门提示词的结果,降低重复推理开销;
- 增加 JWT/OAuth 认证机制,提升API安全性;
- 将部分静态资源(如前端页面)交由Nginx或CDN托管,减轻核心服务压力。


在AIGC时代,算法创新固然重要,但真正决定技术能否落地的,往往是背后的工程体系。本次实践证明,借助 Kubernetes 的强大编排能力,即使是50亿参数级别的AI模型,也能被轻松封装为高性能、可伸缩的Web服务。这种“轻量化+实时性”的组合,正在成为新一代AI应用的标准范式。

下一步,我们将探索更大规模模型的服务化路径,比如通过TensorRT优化推理性能,或采用KEDA实现事件驱动的细粒度扩缩,持续推动AI能力向业务前线高效输送。

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

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

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

立即咨询