基于Containerd与Kubernetes 1.28构建生产就绪型AI推理集群
1. 从单节点到生产集群思路与架构升级上次我们聊了怎么用一台机器快速搭个Kubernetes单节点集群跑个AI模型试试水。说实话那更像是个“玩具”或者开发测试环境真要把这套东西搬到线上去服务真实的用户请求那完全是另一回事了。想象一下半夜三点你的AI问答服务因为某个节点挂了瞬间全瘫用户投诉电话被打爆……这画面太美不敢看。所以今天咱们就来点“硬核”的聊聊怎么把那个单节点的“演示工程”升级改造为一个**生产就绪Production-Ready**的AI推理集群。所谓“生产就绪”我的理解是它得满足几个核心要求高可用、可弹性伸缩、资源隔离精细、并且完全可观测。你不能让业务因为基础设施的脆弱而提心吊胆。基于这个目标我们的技术栈依然坚定地选择Containerd和Kubernetes 1.28。Containerd 作为容器运行时比 Docker 更轻量、更专注也更容易维护是云原生社区的“标准答案”。Kubernetes 1.28 版本带来了很多稳定性增强和性能优化是构建稳健集群的可靠基础。那么一个生产级的AI推理集群架构应该长什么样呢我画个简单的蓝图给你看控制面高可用至少三个 Master 节点通过负载均衡器对外暴露 API Server任何一个 Master 挂了集群管理功能依然正常业务 Pod 不受影响。GPU工作节点池根据模型和负载需求规划多个 GPU 节点。这些节点需要能根据推理请求的压力自动扩缩容。GPU资源精细化管理不是简单地把整张卡扔给一个 Pod。对于 A100、H100 这类高端卡要利用 NVIDIA 的MIGMulti-Instance GPU或MPSMulti-Process Service技术把一块物理 GPU 切成多个“虚拟GPU”让更多的小模型或任务可以共享硬件提升利用率。全面的监控告警集群本身、容器、GPU 的各类指标使用率、温度、显存、功耗都需要被实时采集、可视化。一旦出现异常能第一时间通过钉钉、企业微信、邮件等方式告警把问题扼杀在摇篮里。听起来有点复杂别怕我们一步一步来。我会把我在实际项目中踩过的坑、验证过的方案用最直白的方式分享给你。咱们的目标是让你看完就能动手搭建出一个真正能扛住线上流量的 AI 推理底座。2. 构建高可用的Kubernetes控制平面单 Master 节点是最大的单点故障源。在生产环境我们必须部署多 Master 节点。这里我推荐使用kubeadm配合外部etcd集群来搭建这是官方支持且经过大量实践验证的方案。2.1 节点规划与前置准备假设我们规划了3台 Master 节点和2台初始GPU Worker 节点。所有节点都需要完成我们在单节点教程中提到的基础环境配置包括关闭防火墙、swap、配置内核参数、安装 ipvs 模块等。这里我强调几个生产环境需要特别注意的点主机名与解析每台机器的主机名必须唯一且易于识别比如k8s-master-01,k8s-master-02,k8s-master-03,gpu-node-01,gpu-node-02。不仅要在/etc/hosts里做好所有节点的 IP 映射更佳实践是搭建一个内部 DNS 服务器如 CoreDNS实现动态解析。时间同步集群内所有节点的时间必须高度一致否则会导致证书错误、调度混乱等问题。除了安装chrony最好配置它们指向同一个可靠的 NTP 服务器源并设置强制同步。系统资源预留Master 节点虽然不跑业务 Pod但kube-apiserver,kube-controller-manager,kube-scheduler,etcd这些核心组件也需要消耗 CPU 和内存。务必在/etc/kubernetes/manifests/下的对应 Pod 定义中或通过 kubelet 的--system-reserved参数为系统组件预留资源防止它们因资源竞争被 OOM Killer 干掉。所有节点安装 Containerd 和 kubeadm 的步骤与之前单节点一致这里不再重复。关键在于kubeadm的配置文件。2.2 使用 kubeadm 初始化高可用集群我们不能再用单节点的初始化命令了。首先你需要准备一个负载均衡器LB可以是硬件 F5、软件 HAProxy或者云服务商的负载均衡服务。LB 后端指向三个 Master 节点的 6443 端口并提供一个虚拟 IPVIP作为集群的入口。接下来创建我们的kubeadm-config.yaml。这个文件是核心apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.1.101 # 当前初始化节点的IP bindPort: 6443 nodeRegistration: criSocket: unix:///var/run/containerd/containerd.sock name: k8s-master-01 taints: - effect: NoSchedule key: node-role.kubernetes.io/control-plane --- apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.28.3 controlPlaneEndpoint: k8s-api-vip.example.com:6443 # 重要指向LB的VIP或域名 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 国内加速 networking: podSubnet: 172.16.0.0/16 # 需要与你选的CNI插件匹配这里以Calico为例 serviceSubnet: 10.96.0.0/12 etcd: external: # 关键使用外部etcd集群 endpoints: - https://192.168.1.101:2379 - https://192.168.1.102:2379 - https://192.168.1.103:2379 caFile: /etc/kubernetes/pki/etcd/ca.crt certFile: /etc/kubernetes/pki/etcd/etcd-client.crt keyFile: /etc/kubernetes/pki/etcd/etcd-client.key注意etcd部分配置为外部集群意味着你需要先独立部署一个三节点的 etcd 集群并生成好相应的证书。这是生产环境推荐的做法可以实现控制面组件与数据存储的解耦便于独立运维和扩展。如果图省事也可以让 kubeadm 自动管理内部 etcd不配置external字段但故障恢复会稍麻烦。初始化第一个 Master 节点在k8s-master-01上执行kubeadm init --configkubeadm-config.yaml --upload-certs这个--upload-certs参数会将证书加密后上传方便后续其他 Master 节点加入时自动获取。命令成功后你会看到两条重要的kubeadm join命令。一条用于其他Control-Plane 节点一条用于Worker 节点。务必保存好。添加其他 Master 节点分别在k8s-master-02和k8s-master-03上使用刚才生成的Control-Plane join命令。这个命令里包含了证书密钥可以让新节点安全地加入控制平面。添加 Worker 节点在gpu-node-01和gpu-node-02上使用Worker join命令。全部完成后在任意 Master 节点执行kubectl get nodes应该能看到所有 5 个节点状态都是Ready。2.3 安装高可用网络插件Calico单节点时我们用 Flannel 没问题但在生产环境尤其是对网络性能、策略有更高要求的 AI 场景比如某些分布式训练框架我更喜欢Calico。它支持更复杂的网络策略性能也更好并且原生支持我们上面配置的podSubnet: 172.16.0.0/16。安装非常简单# 在Master节点上执行 kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/custom-resources.yaml等待所有calico-system命名空间下的 Pod 变成Running。至此一个高可用的 Kubernetes 控制平面就搭建完成了。即使其中一个 Master 节点宕机你的集群管理操作和业务 Pod 的网络通信依然不会中断。3. GPU节点接入与弹性伸缩策略控制面稳了接下来就是干活的 GPU 节点。我们的目标不仅是把节点加进来还要让它能“聪明地”应对流量波动。3.1 为GPU节点打标签与污点不同的 GPU 型号V100, A100, T4能力不同适合的推理任务也不同。我们需要通过标签来区分它们。# 假设 gpu-node-01 是 A100 节点 kubectl label node gpu-node-01 acceleratornvidia-a100 gpu-typehigh-performance # 假设 gpu-node-02 是 T4 节点 kubectl label node gpu-node-02 acceleratornvidia-t4 gpu-typegeneral-purpose # 给所有GPU节点打上一个污点防止普通Pod调度上来 kubectl taint node gpu-node-01 gputrue:NoSchedule kubectl taint node gpu-node-02 gputrue:NoSchedule这样只有容忍Toleration了gputrue:NoSchedule这个污点的 Pod也就是我们的AI推理服务才能被调度到这些 GPU 节点上。3.2 安装NVIDIA设备插件与容器运行时这一步和单节点类似但需要确保在每个 GPU 节点上都执行。核心是配置 Containerd 使用nvidia-container-runtime。安装 NVIDIA Container Toolkit以 CentOS 8 为例distribution$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo sudo yum install -y nvidia-container-toolkit nvidia-container-runtime配置 Containerdsudo nvidia-ctk runtime configure --runtimecontainerd --set-as-default sudo systemctl restart containerd这个命令会自动修改/etc/containerd/config.toml添加nvidia这个运行时。部署 NVIDIA Device Plugin DaemonSetkubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.15.0/deployments/static/nvidia-device-plugin.yml这个插件会在每个 GPU 节点上以 Pod 形式运行负责向 Kubernetes 汇报节点上的 GPU 数量、型号等信息。部署成功后执行kubectl describe node gpu-node-01你应该能在Capacity和Allocatable段看到nvidia.com/gpu: 1假设节点有一张卡这样的资源。这标志着 Kubernetes 已经能识别并调度 GPU 资源了。3.3 配置GPU节点自动伸缩CA线上流量有高峰低谷。半夜请求少所有 GPU 节点全开太浪费电白天高峰期又需要快速扩容。这就需要Cluster Autoscaler (CA)。CA 的工作原理是当 Kubernetes 调度器发现没有足够资源运行新的 Pod出现Pending状态的 Pod并且这些 Pod 无法被重新调度时CA 就会通知你的云服务商或对接的私有云平台创建新的节点加入集群。反之当节点利用率过低时CA 会安全地驱逐其上的 Pod 并删除节点。这里以阿里云 ACK或自建集群配合模拟器为例简述其配置思路为 GPU 节点组配置自动伸缩组在云平台上创建一个包含 GPU 实例的伸缩组并设置最小、最大实例数。部署 Cluster Autoscaler你需要一个拥有相应云 API 权限的 ServiceAccount 和 Deployment。CA 的启动参数需要指定你的节点组。# 简化的Deployment示例片段 spec: containers: - command: - ./cluster-autoscaler - --cloud-provideralicloud # 根据你的云环境修改 - --nodes1:10:gpu-node-group # 最小1台最大10台组名 - --scale-down-unneeded-time10m # 节点空闲10分钟后开始缩容 image: registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-autoscaler:v1.28.0为AI推理Deployment配置HPA光有节点伸缩不够Pod本身也要能伸缩。结合Horizontal Pod Autoscaler (HPA)根据 GPU 利用率或请求 QPS 等指标自动调整推理服务 Pod 的副本数。kubectl autoscale deployment my-ai-inference --cpu-percent50 --min2 --max10这样当服务压力增大Pod 副本数先增加。当节点资源不足时CA 再触发扩容新节点。两者结合实现了从应用到基础设施的完整弹性。4. 高级GPU资源管理MIG与MPS实战默认情况下一个 Pod 会请求nvidia.com/gpu: 1即独占一整张物理 GPU。这对于大模型推理是合理的但对于一些轻量级模型或高并发小任务这就造成了巨大的资源浪费。NVIDIA 提供了两种主要的 GPU 切分技术。4.1 NVIDIA MIG硬件级隔离MIG 可以将一块 A100/H100 等高端 GPU 物理分割成多个最多7个称为GPU实例GI的独立单元每个实例拥有独立的内存、计算核心和带宽。隔离彻底性能可预测适合多租户安全隔离场景。在Kubernetes中使用MIG在节点上启用MIG模式这需要在 GPU 节点的 BIOS/OS 层面操作通常使用nvidia-smi命令设置。例如将一张 A100 80G 设置为MIG 1g.10gb模式创建7个10GB的实例。sudo nvidia-smi -mig 1 # 启用MIG sudo nvidia-smi mig -cgi 1g.10gb -C # 创建实例配置部署支持MIG的Device PluginNVIDIA 提供了专门的gpu-feature-discovery和nvidia-device-plugin来发现并上报 MIG 实例。你需要部署它们并给节点打上对应的标签如nvidia.com/mig.configall-1g.10gb。在Pod中请求MIG资源在 Pod 的resources.limits中不再请求nvidia.com/gpu而是请求具体的 MIG 实例资源例如nvidia.com/mig-1g.10gb: 1。注意MIG 的配置是持久的但管理相对复杂且一旦划分实例大小就固定了。它更适合长期稳定、需要强隔离的部署模式。4.2 NVIDIA MPS时间片共享MPS 是一种软件层面的多进程服务。它允许多个 CUDA 进程对应多个容器共享同一个 GPU 的上下文从而减少上下文切换和内存重复占用的开销提升 GPU 利用率和吞吐量。它不提供硬隔离一个进程的错误可能影响同卡上的其他进程。在Kubernetes中启用MPS在节点上启动MPS守护进程这通常通过一个在 GPU 节点上以DaemonSet或Systemd服务运行的容器来完成。配置容器使用MPS需要在 Pod 的securityContext和volumeMounts中做一些配置让容器能访问到 MPS 的 Unix Domain Socket (/tmp/nvidia-mps)。我个人在推理集群中的经验是对于追求极致吞吐量、任务同质化高、且对隔离性要求不严苛的场景比如同一团队的多个相似模型推理MPS 是性价比更高的选择它能显著提升小批量、高并发推理任务的性能。而对于需要严格隔离不同用户或不同业务模型的生产环境MIG 则是更安全可靠的选择。你可以根据业务特点在集群中混合部署不同配置的节点。5. 集成监控告警体系Prometheus与Grafana“可观测性”是生产系统的生命线。对于 AI 推理集群我们至少要监控四层集群基础设施节点、网络、Kubernetes 对象Pod、Deployment、容器资源CPU、内存和GPU 硬件利用率、显存、温度、功耗。5.1 部署Prometheus Stack这里我强烈推荐使用kube-prometheus-stack原名 Prometheus Operator。它把 Prometheus、Alertmanager、Grafana 以及一大堆针对 K8s 的监控规则和面板都打包好了一键部署极其方便。# 添加 Prometheus Community Helm 仓库 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update # 创建命名空间 kubectl create namespace monitoring # 安装 kube-prometheus-stack helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValuesfalse \ --set grafana.adminPasswordyour-strong-password安装完成后你可以通过端口转发访问 Grafanakubectl port-forward svc/kube-prometheus-stack-grafana -n monitoring 8080:80然后用admin和上面设置的密码登录。里面已经预置了 Kubernetes 集群的监控面板非常全面。5.2 监控GPU指标默认的 kube-prometheus-stack 不包含 GPU 监控。我们需要部署NVIDIA DCGM Exporter。DCGMData Center GPU Manager是 NVIDIA 提供的用于监控和管理数据中心 GPU 的工具其 Exporter 会将 GPU 指标以 Prometheus 格式暴露出来。部署 DCGM Exporter DaemonSetkubectl create -f https://raw.githubusercontent.com/NVIDIA/dcgm-exporter/main/deployments/kubernetes/dcgm-exporter.yaml创建 ServiceMonitor告诉 Prometheus 去抓取 DCGM Exporter 的指标。# gpu-service-monitor.yaml apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: dcgm-exporter namespace: monitoring labels: release: kube-prometheus-stack # 这个label很重要要匹配Prometheus的selector spec: selector: matchLabels: app: dcgm-exporter namespaceSelector: any: true endpoints: - port: metrics interval: 15skubectl apply -f gpu-service-monitor.yaml等待几分钟在 Grafana 中导入NVIDIA 官方提供的 DCGM 仪表板Dashboard ID 为12239你就能看到每个 GPU 的详细运行状态了包括 SM 利用率、显存利用率、温度、功耗、PCIe 带宽等一目了然。5.3 配置关键告警规则监控是为了发现问题告警是为了及时通知你。我们需要在 Prometheus 里配置一些针对 AI 推理集群的关键告警规则。GPU 相关告警GPU 温度过高DCGM_FI_DEV_GPU_TEMP 85GPU 显存即将用尽DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_FREE 0.9GPU 设备异常nvidia_gpu_dcgm_health 0DCGM健康状态非0表示异常节点与Pod告警节点 NotReadykube_node_status_condition{conditionReady, statusfalse} 1Pod 持续重启rate(kube_pod_container_status_restarts_total[5m]) 0节点内存压力node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes 0.1这些规则可以通过创建PrometheusRuleCRD 资源来添加。配置好后在 Alertmanager 中设置接收器Receiver将告警信息发送到钉钉、企业微信、Slack 或邮件。确保任何影响服务的异常都能在 5 分钟内触达你的手机。6. 生产环境运维要点与故障排查集群搭起来只是开始日常运维才是真正的考验。这里分享几个我踩过坑才学到的经验。镜像拉取优化AI 模型镜像动辄几十 GB从公网拉取慢且不稳定。务必搭建私有镜像仓库如 Harbor并将常用基础镜像如 PyTorch、TensorFlow 的 CUDA 镜像缓存到本地。在containerd配置中配置镜像加速器mirror和私有仓库认证。日志与事件集中管理使用Loki或Elasticsearch Fluentd方案将所有容器日志和 Kubernetes 事件收集到中心存储方便故障回溯。AI 推理服务的输入输出日志尤其重要是调试模型行为和分析请求异常的关键。GPU 节点故障隔离当某个 GPU 节点硬件故障或驱动异常时需要快速将其隔离防止调度器继续分配任务。除了手动打cordon可以结合Node Problem Detector和自定义的监控规则实现自动标记和驱逐。一个常见的 GPU 设备插件故障排查流程发现 Pod 调度到 GPU 节点后容器启动失败提示无法找到 GPU 设备。首先检查节点状态kubectl describe node gpu-node看Capacity里是否有nvidia.com/gpu。如果没有登录节点检查nvidia-smi是否正常驱动是否安装。检查containerd配置cat /etc/containerd/config.toml | grep -A 5 nvidia确认nvidiaruntime 已配置。检查 NVIDIA Device Plugin Pod 日志kubectl logs -n kube-system nvidia-device-plugin-pod。常见问题驱动版本与 Container Toolkit 版本不兼容、containerd配置未生效、节点未安装nvidia-container-runtime。按照这个路径大部分问题都能定位。最后记住备份备份备份定期备份etcd集群数据etcdctl snapshot save和所有重要的 Kubernetes 资源定义YAML 文件。同时像Velero这样的工具可以实现整个命名空间甚至集群级别的应用数据备份与迁移在灾难恢复时能救你于水火。构建生产级的 AI 推理集群是一个系统工程涉及稳定性、性能、成本、可维护性等多方面的权衡。今天分享的这套基于 Containerd 和 Kubernetes 1.28 的方案融合了高可用控制面、GPU 弹性伸缩、精细资源管理和全方位监控是我们团队经过多个项目锤炼后的实践总结。它可能不是最简单的但绝对是能让你晚上睡得着觉的方案。技术细节很多动手时肯定会遇到各种小问题但每解决一个你对这套体系的理解就会更深一层。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2412061.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!