尧图精选

K3S+Hami+Higress+Vip(nginx+keepalived)搭建云原生高可用的大模型部署平台

🕒 发布时间:2026/9/15 11:31:21 📁 来源:尧图网络
由于之前参与了一些私有化云原生结合的大模型部署和应用的项目以及团队内部有想推云原生部署AI模型的想法就尝试在我们测试环境使用K3SHamiHigressVip(nginxkeepalived)来搭建一套高可用的集群部署平台 来验证易用性和便捷性。K3S 这个是一个轻量化的kubernetes专门用来做容器化部署的kuboard:v4 swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v4这一个K3S的数据面板或者说控制台用来管理K3S的集群的各种部署配置以及资源监测等。Hami 这个是一个插件用来给K3S提供GPU资源信息用来管理和调度作用的插件可以对GPU资源进行显存切分有了这个组件多个pod就可以部署在同一个GPU上不然一张显卡就只能一个pod独占了。Higress 阿里开发的一个网关组件支持快速的集成各类LLM 以及 Agent API提供域名管理、路由配置、AI网关管理、插件配置(流量、安全、认证、转换、AI包含 AI模型路由、token统计、MCP服务器、AI缓存)——这个正是我们集成openAI API以及 各种不同模型服务化对外暴露能力的一个易用方便的组件Vip(nginxkeepalived) 使用nginx反向代理keepalived监控 nginx来实现 VIP漂移在服务节点出现故障后自动快速的切换到容灾或者备节点。一、安装上面每个组件安装都比较简单官网都有一个命令执行就能完成安装。我这边是没有自己搭建过以及当前服务器上运行的又一些服务不能重启服务器这个约束下尝试安装的。我们的服务器系统都是ubuntu、helm以及网络都都是拉通了比较麻烦的就是K3S多控制面板集群在安装过单控制面板K3S的机器上怎么安装成功、nginx源码编译安装、hami组件的配置以及higress路由的插件配置这些地方折腾了一些时间最久的还是K3S多控制面板集群在安装过单控制面板K3S的机器上怎么安装成功这个耗时最久。1、K3S多control panel集群的安装就2个命令第一个curl -sfL https://get.k3s.io | sh -s - server \ --cluster-init \ --tls-sanFIXED_IP # Optional, needed if using a fixed registration address在一个节点上执行上述命令使用--cluster-init来开启etcd(内置数据库服务) 国内网络的问题也可以使用加速版本的命令curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | sh -s - server \ --cluster-init注意安装过后这个节点的机器上/var/lib/rancher/k3s/server会有一个token文件其他的节点加入这个集群就需要这个这个token其他节点加入集群(可以是server 也可以是 agent)在每个节点上都执行一次curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | K3S_TOKENSECRET sh -s - server \ --server https://ip or hostname of server1:6443注意如果是非server节点加入就可以用下面的命令curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | K3S_TOKENSECRET sh -s - agent \ --server https://ip or hostname of server1:6443已经部署过单control panel的机器上多control panel的 安装的时候稍微复杂一点点就是要把之前所有node上的k3s 所有的服务下掉同时可以新修改一个K3S_TOKEN. 注意K3S相关的服务就是 k3s server 和 k3s agent停止它们后按照上面的命令进行安装和切换。停止使用如下命令# agent node 停止 sudo systemctl stop k3s-agent # server node 停止 sudo systemctl stop k3s上述安装OK后就可以查看集群的信息了。一些组件k3s也会自动安装例如kubectl执行kubectl get nodes得到如下结果2、kuboard:v4 安装这个是一个dashboard面板、以web形式可以管理集群、查看集群信息、部署之类的。也有k8S官方版本的但是已经不维护之前下载安装也没有搞成功。就用了同事推荐的华为的一个版本 安装使用docker来进行安装对应的docker-compose详情如下configs: create_db_sql: content: | CREATE DATABASE kuboard DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; create user kuboard% identified by kuboardpwd; grant all privileges on kuboard.* to kuboard%; FLUSH PRIVILEGES; services: db: image: swr.cn-east-2.myhuaweicloud.com/kuboard/mariadb:11.3.2-jammy # image: mariadb:11.3.2-jammy # swr.cn-east-2.myhuaweicloud.com/kuboard/mariadb:11.3.2-jammy 与 mariadb:11.3.2-jammy 镜像完全一致 environment: MARIADB_ROOT_PASSWORD: kuboardpwd MYSQL_ROOT_PASSWORD: kuboardpwd TZ: Asia/Shanghai volumes: - ./kuboard-mariadb-data:/var/lib/mysql:Z configs: - source: create_db_sql target: /docker-entrypoint-initdb.d/create_db.sql mode: 0777 networks: kuboard_v4_dev: aliases: - db kuboard: image: swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v4 # image: eipwork/kuboard:v4 environment: - DB_DRIVERorg.mariadb.jdbc.Driver - DB_URLjdbc:mariadb://db:3306/kuboard?serverTimezoneAsia/Shanghai - DB_USERNAMEkuboard - DB_PASSWORDkuboardpwd ports: - 8000:80 volumes: - ./kuboard-log:/app/logs:Z depends_on: - db networks: kuboard_v4_dev: aliases: - kuboard networks: kuboard_v4_dev: driver: bridge安装完成后就可以打开网页进行集群管理和操作了。http//ip:port/8000截图如下3、Hami 安装HAMi 是开源的云原生 GPU 虚拟化中间件为 AI 工作负载提供异构加速器的共享、隔离与调度能力。至此GPU显存和算力的细粒度的切分低于整卡的切分。有了它Kubernetes才能正常、高效、稳定的进行gpu服务的管理和运行。从官方文档或者github上可以一键式的安装在线安装命令如下helm install hami hami-charts/hami --set scheduler.kubeScheduler.imageTagv1.16.8 -n kube-system等待一定的时间安装成功后kubectl get pods -A 查看hami-device-plugin 和 hami-scheduler是否安装成功截图如下我这边的pod正常运行说明就可以使用它来部署模型推理之类的服务了。部署的pod的时候还是会有一个坑之前同事有提醒过但是过了很久才来操作忘记这个坑自己折腾很久了才发现和解决。runtimeClassName: nvidia 这个注解在node containerd 的 config.toml中没有提前全局修改为指定的runtime且deployment也没有显示声明部署会不成功直接报错。部署示例如下apiVersion: v1 kind: Pod metadata: name: gpu-pod-hy-test annotations: # 注解指定显卡id nvidia.com/use-gpuuuid: GPU-5f3b00da-2b13-d66e-f9a4-ad741e987643 spec: runtimeClassName: nvidia # 必须指定——集群没有指定容器启动的运行时、有可能是华为的、nvidia的 containers: - name: ubuntu-container image: ubuntu:18.04 command: [bash, -c, sleep 86400] resources: requests: nvidia.com/gpu: 1 # ✅ 必须添加 requests nvidia.com/gpumem: 300 # 单位是 MiB不要带 k 或 Ki limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 300 # identifies 3000M GPU memory each physical GPU allocates to the pod Optional,Integer affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname # 节点的hostname标签 operator: In values: - kxjl-364、Higress 安装这个组件是阿里开源的一个AI云原生API网关将流量网关、微服务网关和安全网关三合一提供统一的服务暴露、流量管控、API 全生命周期管理能力。在K8S中还能丝滑的替换Ingress这个组件。我们这里使用就是需要用到它的路由以及负载均衡能力(我们自身也是有一个路由功能的自研的组件相当于是在这个组件上再套一层Higree)未来可以扩展安全、流量控制以及一些请求指标的可视化。它是云原生的安装起来也是一句命令的事情命令如下helm repo add higress.io https://higress.io/helm-charts helm install higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes --set global.localtrue --set global.o11y.enabledfalse安装完成后的截图由于没有LoadBalancer负载均衡方案以及我不清楚公司的内网DNS解析服务所以就有必要对higress-console和higress-gateway开启nodeport后使用nodeip来访问控制台页面和网关服务。注意这个开启有多种方式一种是安装的时候修改安装命令指定还有一种就是安装后的我这边就是安装后才发现需要使用nodeport来访问的才采取安装后来修改svc的方式。形如下面的命令注意 -p 后面的具体的nodeport内容项kubectl patch svc higress-console -n higress-system -p {spec:{type:NodePort,ports:[{port:8080,nodePort:30080}]}}kubectl patch svc higress-gateway -n higress-system -p {spec:{type:NodePort,ports:[{port:80,nodePort:30081},{port:443,nodePort:30082}]}}修改完后就可以打开higress的控制台了浏览器输入 nodeip:nodeport 就可以打开了左边就菜单栏就可以进行后端服务的管理了路由、ai服务路由、流量统计、安全管理等5、Vip(nginxkeepalived)安装这里是为了预防访问入口的服务器宕机或者挂掉导致客户访问不到集群上的服务了所以得用高可用容灾的方案。这里采用简单的免费的以及要求不怎么高的方案使用keepalived开启虚ip监控不同机器上的nginx每台机器上的nginx进行反向代理 把访问虚ip的请求中转分发到后端服务中。以上就是主要的功能和作用具体就涉及到keepalived的开启vip、对应的监控任务脚本触发vip漂移、和Nginx的安装以及反向代理的配置。nginx的安装比较简单直接上网搜索一下我直接把nginx的源码下载路径提供下安装是基于nginx的源码编译安装的。nginx下载官网地址使用上面的稳定版本内容如下编译安装(直接看github或者问大模型)./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-stream \ --with-stream_ssl_module make sudo make install运行后的进程对于keepalived这个工具直接给下配置安装使用系统命令就好了。/etc/keepalived路径下的keepalived.conf可以完成vip的一些配置。注意这个vip一定是内网段一个没有使用过的ip可以借助主机的网卡以及keepalived来实现内网直接的漂移。masterglobal_defs { router_id kxjl-31 # 每台机器不同建议用 hostname } # 定义 Nginx 健康检查脚本 vrrp_script check_hy_nginx { script /data02/yanghuang/check_hy_nginx.sh interval 2 # 每 2 秒检查一次 timeout 5 # 脚本执行超时 5 秒 weight -20 # 脚本失败时本机优先级减 20 fall 2 # 连续失败 2 次才判定为失败 rise 1 # 成功 1 次即恢复 } vrrp_instance VI_NGINX { state MASTER # 主服务器: MASTER备用: BACKUP interface ens1f0 # 你的网卡名 virtual_router_id 51 # 主备必须一致 priority 100 # 主: 100备: 90或更低 advert_int 1 # 心跳间隔 1 秒 authentication { auth_type PASS auth_pass 1111 # 主备必须一致 } # 虚拟IP virtual_ipaddress { x.x.x.188/24 # 你的 VIP } # 关联监控脚本 track_script { check_hy_nginx } }backup! Configuration File for keepalived global_defs { router_id kxjl-32 # 每台机器不同建议用 hostname } # 定义 Nginx 健康检查脚本 vrrp_script check_hy_nginx { script /data02/yanghuang/check_hy_nginx.sh interval 2 # 每 2 秒检查一次 timeout 5 # 脚本执行超时 5 秒 weight -20 # 脚本失败时本机优先级减 20 fall 2 # 连续失败 2 次才判定为失败 rise 1 # 成功 1 次即恢复 } vrrp_instance VI_NGINX { state BACKUP # 主服务器: MASTER备用: BACKUP interface ens1f0 # 你的网卡名 virtual_router_id 51 # 主备必须一致 priority 90 # 主: 100备: 90或更低 advert_int 1 # 心跳间隔 1 秒 authentication { auth_type PASS auth_pass 1111 # 主备必须一致 } # 虚拟IP virtual_ipaddress { y.y.y.188/24 # 你的 VIP } # 关联监控脚本 track_script { check_hy_nginx } }查看vip目前是否在本机上ip add show ens1f0 | grep 188 31上有结果inet x.x.x.188/24 scope global secondary ens1f0说明vip目前在31服务器上二、部署实践在上述K3S相关的组件都搭建完毕后结合我司现有的模型部署以及服务架构特点需要部署一个大模型推理服务进行测试验证。调用链是用户请求——keepalived——VIP——Nginx——K3SHigress-gateway——Nus3——model service外部请求流量通过vip进入nginxnginx通过反向代理进入K3S的Higress-Gateway服务(通过Nodeport)然后Higress通过配置的路由把请求转发到Nus3这个组件Nus3在把请求转发到底层的model service这个是通过请求中的请求体有关字段来确定转发的目标服务。架构中有一个隐藏的点就是底层模型服务通过service name 向nus3 组件发送心跳(http post 请求上报pod ip 和port)这里由于是K3S内 ClusterIP DNS服务以及Iptables 做的tcp的负载和转发上报心跳的服务是长连接就会导致pod粘连的问题——解决的办法就是修改为短连接或者nus3组件的服务采用headless的形式在其他pod内手动发现nus3的pod ip请求级别的做负载均衡就不会导致pod粘连了。1、模型服务部署采用vllm框架以及sidecar 容器把模型能力上报到nus中另外模型权重的挂载并没有采用任何pvc的类型例如local-path和longhorn-path这类单节点和分布式的存储类似和docker -v 一样的 hostPath方案containers: - name: dialog-agent-model image: 172.19.13.36:18182/ai/vllm-openai:v0.23.0 # 替换为你的实际镜像地址 volumeMounts: - name: kxjl-models-storge mountPath: /model volumes: - name: kxjl-models-storge hostPath: path: /data02/yanghuang/deployment/docker/chat_sglang/merged_models/dialog_agent/merge type: Directory模型权重的挂载就类似上述方案一般规范性的使用还是要使用PVC底层使用NFS做到分布式多节点高可用。当然部署的时候还关注到测试环境显卡可用性选择固定的显卡以及节点 所有使用了节点亲和性把服务部署到对应的node使用注解来实现固定显卡的使用。最终所有的deployment.yml详情如下configMap、deployment以及service都写在一起了。apiVersion: v1 kind: ConfigMap metadata: name: nus-sidecar-config # ConfigMap 的名称 namespace: default # 与 Deployment 相同的命名空间 data: # 键是文件名值是文件内容。请将 YOUR_TOML_CONFIG_CONTENT_HERE 替换为 toml.config 文件的实际内容。 # 注意如果内容包含特殊字符如 $, {, }, # 等可能需要用引号包围或使用 |- 块样式。 config.yaml: | nus: nus3:8888 node_name: dialogagent.model.20260806 openai: api_key: none base_url: http://127.0.0.1:8888/v1 --- apiVersion: apps/v1 kind: Deployment metadata: name: dialog-agent-model namespace: default labels: app: dialog-agent-model spec: replicas: 1 selector: matchLabels: app: dialog-agent-model strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 template: metadata: labels: app: dialog-agent-model annotations: # 注解指定显卡id nvidia.com/use-gpuuuid: GPU-a750cfe1-e711-d85f-27f7-aae74bf4c6a3 spec: runtimeClassName: nvidia # 必须指定——集群没有指定容器启动的运行时、有可能是华为的、nvidia的 # 使用私有仓库的 Secret imagePullSecrets: - name: 36-harbor-secret containers: - name: dialog-agent-model image: ip:port/ai/vllm-openai:v0.23.0 # 替换为你的实际镜像地址 imagePullPolicy: IfNotPresent # command: [sleep, infinity] command: [vllm, serve] args: - --model - /model # 替换为你的模型路径 - --port - 8888 - --host - 0.0.0.0 - --max-num-seqs - 32 - --tensor-parallel-size - 1 - --gpu-memory-utilization - 0.95 ports: - containerPort: 8888 name: vllm-http volumeMounts: - name: kxjl-models-storge mountPath: /model resources: # limits: # nvidia.com/gpu: 1 # 每个 Pod 申请 1 张 GPU 独占的 # requests: # nvidia.com/gpu: 1 # 每个 Pod 申请 1 张 GPU 独占的 requests: nvidia.com/gpu: 1 # requests 和 limits 必须相同 nvidia.com/gpumem: 23000 # 单位是 MiB cpu: 2 memory: 10Gi limits: nvidia.com/gpu: 1 # 申请 1 个 vGPU nvidia.com/gpumem: 23000 # 分配 20000 MiB 显存 cpu: 3 memory: 12Gi # env: # - name: VLLM_LOGGING_LEVEL # value: INFO - name: nus-sidecar image: ip:port/ai/nus_sidecar:1.0.0 # 替换为你的实际镜像地址 imagePullPolicy: IfNotPresent ports: - containerPort: 8887 name: sidecar-http volumeMounts: - name: config-volume # 与下面 volumes.name 对应 # 指定挂载到容器内的路径 # mountPath: /app/config # subPath 允许将 ConfigMap 中的单个文件挂载到已有文件或非空目录下的文件 # mountPath: /app/config/config.json # subPath: config.json mountPath: /app/config.yaml subPath: config.yaml volumes: - name: kxjl-models-storge hostPath: path: /data02/yanghuang/deployment/docker/chat_sglang/merged_models/dialog_agent/merge type: Directory - name: config-volume configMap: name: nus-sidecar-config # 引用上面创建的 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname # 节点的hostname标签 operator: In values: - kxjl-31 --- apiVersion: v1 kind: Service metadata: name: dialog-agent-service namespace: default labels: app: dialog-agent-model spec: selector: app: dialog-agent-model ports: - protocol: TCP port: 8888 # Service 端口 targetPort: 8888 # Pod 端口 type: ClusterIPkubectl apply -f depolyment.yaml 执行就可以了 也可以在k3s的控制台使用 前端页面来操作部署后可以在控制台页面看到很多deployment我们测试的dialog-agent-model已经部署成功了2、Higress配置由于采用higress以及使用了nus和一些自研的组件如果是想higess自己访问模型服务不走nus也是可以做到的当然我们可以把nus3以及model service的路由都在Higress中配置好。还有一个点就要住了 model service 配置的时候 使用addProviderHeader: x-higress-llm-provider要特别注意只有vllm启动的时候openAI输入model模型参数是带/模型提供商之类的它会以/来切割这个参数把最后的字段作为model参数最后的值输入到模型服务中。3、调用展示使用kubectl 来查看 kubectl get pods-o wide 看详细信息调用展示higress——nus——model service中间的nus日志转发成功并收到响应也可以直连model服务使用openAI的调用方案k3s官网文档hami官网
上一篇/下一篇内容由系统自动关联 返回资讯列表 →