3. 平台基础设施与云原生底座运维
药物研发数据平台承载的是化合物筛选、基因测序、分子对接、临床数据管理等混合负载,其基础设施既要支撑长时间高吞吐的批处理,又要应对交互式查询和模型推理的突发流量。因此,这一层的运维对象不是单一服务器,而是“物理/虚拟服务器 → 容器运行时 → Kubernetes 编排 → 服务网格”四层叠加的云原生底座。理解这四层各自负责什么、边界在哪里,是后续监控与生命周期管理的前提。
四层底座的职责划分
服务器层提供 CPU、内存、GPU、本地 NVMe 与网络带宽,是算力与存储的物理来源;容器层通过镜像与运行时把应用及其依赖封装为可移植单元,解决“环境不一致”问题;Kubernetes 层负责调度、副本管理、服务发现、配置与存储编排,是弹性与自愈的核心;服务网格层则把服务间通信的流量治理、mTLS 加密、重试与可观测性从应用代码中剥离出来。四层之间是逐层抽象、逐层增强的关系,而不是互相替代。
部署:从节点纳管到工作负载上线
部署的第一步是节点纳管。以 kubeadm 为例,控制平面初始化后,计算节点通过 kubeadm join 加入集群。药物研发场景中,GPU 节点需要额外安装 NVIDIA Device Plugin,使 nvidia.com/gpu 成为可调度资源。一个典型的分子对接工作负载可以这样声明资源:
resources:
limits:
nvidia.com/gpu: 1
cpu: "8"
memory: 32Gi
requests:
cpu: "4"
memory: 16Gi
nodeSelector:
node-pool: gpu-a100
这里 requests 决定调度时的资源预留,limits 决定运行时上限。若 requests 设置过低,多个任务会被挤到同一节点导致争抢;若 limits 设置过高,则节点利用率下降。实践中建议 GPU 任务 requests 与 limits 的 GPU 数量一致,避免超卖。
服务网格的注入通常在命名空间级别开启。为 drug-pipeline 命名空间打上 istio-injection=enabled 标签后,新建 Pod 会自动注入 sidecar。需要注意,批处理任务若对启动延迟敏感,可对该工作负载关闭注入,避免 sidecar 启动拖慢任务。
监控:分层指标与关键阈值
监控体系应覆盖四层,每层关注不同信号。服务器层看节点 CPU、内存、磁盘 IO、GPU 利用率与显存;容器层看容器重启次数、OOMKilled 事件、CPU throttling;Kubernetes 层看 Pod 就绪状态、Deployment 副本偏差、PVC 使用率、API Server 延迟;服务网格层看请求成功率、P95 延迟、连接池饱和度。
以 Prometheus 为例,节点 GPU 利用率可通过 DCGM Exporter 暴露为 DCGM_FI_DEV_GPU_UTIL。一个实用的告警规则示例:当某 GPU 节点连续 10 分钟利用率低于 5% 且该节点上存在待调度 GPU 任务时,触发“GPU 资源闲置”告警。这类规则能帮助运维发现调度器因亲和性配置不当而“卡住”的任务。
生命周期管理:滚动更新、扩缩容与节点轮换
工作负载的生命周期包括创建、更新、扩缩容、下线。Deployment 的滚动更新通过 maxSurge 和 maxUnavailable 控制节奏。对于数据预处理服务,可设置 maxSurge: 1, maxUnavailable: 0,保证更新期间始终有可用副本;对于可容忍短暂中断的批处理,可放宽为 maxUnavailable: 1 以加快发布。
节点轮换是容易被忽视的一环。当需要升级内核或更换 GPU 驱动时,应先 kubectl cordon 标记节点不可调度,再 kubectl drain 驱逐 Pod。若节点上运行着带本地存储的 Pod,需确认其 PVC 是否支持迁移,否则应等待任务自然结束再驱逐。驱逐完成后执行维护,重启后 uncordon 恢复调度。
扩缩容方面,HPA 适合无状态服务,依据 CPU 或自定义指标调整副本数;对于 GPU 批处理任务,更常用的是 KEDA 或集群自动扩缩容(Cluster Autoscaler),按队列长度触发节点扩容。需要注意的是,节点扩容通常需要数分钟,因此队列积压时应提前触发,而不是等到任务全部阻塞。
一次典型的排障路径
假设某基因比对任务长时间处于 Pending。排查顺序应为:先 kubectl describe pod 查看 Events,若提示 0/12 nodes available: insufficient nvidia.com/gpu,说明 GPU 资源不足或节点未正确暴露 GPU;若提示 node(s) had taint,则检查 toleration 配置;若 Pod 已 Running 但任务无进展,则进入容器查看进程与日志,并检查 sidecar 是否拦截了出站流量。这条路径把四层结构串成了可操作的判断链,也是日常运维中最常复用的思路。