3. 平台基础设施与云原生底座运维

药物研发数据平台承载的是化合物筛选、基因测序、分子对接、临床数据管理等混合负载,其基础设施既要支撑长时间高吞吐的批处理,又要应对交互式查询和模型推理的突发流量。因此,这一层的运维对象不是单一服务器,而是“物理/虚拟服务器 → 容器运行时 → Kubernetes 编排 → 服务网格”四层叠加的云原生底座。理解这四层各自负责什么、边界在哪里,是后续监控与生命周期管理的前提。

四层底座的职责划分

服务器层提供 CPU、内存、GPU、本地 NVMe 与网络带宽,是算力与存储的物理来源;容器层通过镜像与运行时把应用及其依赖封装为可移植单元,解决“环境不一致”问题;Kubernetes 层负责调度、副本管理、服务发现、配置与存储编排,是弹性与自愈的核心;服务网格层则把服务间通信的流量治理、mTLS 加密、重试与可观测性从应用代码中剥离出来。四层之间是逐层抽象、逐层增强的关系,而不是互相替代。

药物研发数据平台云原生底座四层结构 服务网格层(Istio / Linkerd) Sidecar 代理 mTLS 加密 流量路由/重试 调用链追踪 Kubernetes 编排层 调度 Scheduler GPU/亲和性 副本控制器 自愈/扩缩容 Service/Ingress 服务发现 ConfigMap/PVC 配置与存储 容器运行时层(containerd / Docker) 镜像仓库 Harbor 镜像分层与缓存 资源限制 cgroup 健康探针 服务器基础设施层 CPU/GPU 计算节点 NVMe/分布式存储 高速网络 25/100GbE BMC/IPMI 带外管理 监控贯穿四层:节点指标 → 容器指标 → K8s 对象状态 → 网格流量指标

部署:从节点纳管到工作负载上线

部署的第一步是节点纳管。以 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 资源闲置”告警。这类规则能帮助运维发现调度器因亲和性配置不当而“卡住”的任务。

建议为药物研发平台单独建立“任务队列等待时长”指标。当等待时长持续上升而节点利用率不高时,问题往往出在调度约束(如 nodeSelector、taint/toleration)而非算力不足。

生命周期管理:滚动更新、扩缩容与节点轮换

工作负载的生命周期包括创建、更新、扩缩容、下线。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 是否拦截了出站流量。这条路径把四层结构串成了可操作的判断链,也是日常运维中最常复用的思路。

服务网格的 mTLS 在提升安全性的同时,也会让未注入 sidecar 的旧工作负载无法访问网格内服务。启用严格模式前,务必确认所有相关命名空间和工作负载已完成注入,否则会出现“服务正常但调用失败”的隐蔽故障。