如果你已经会用 Docker(或 Singularity)在单机上跑分析镜像,下一步常常会遇到两类需求:一是任务变多、需要排队与资源限额;二是希望同一套流程在实验室服务器、机房集群或云上尽量一致地跑。Kubernetes(常写作 K8s)就是为「在很多台机器上可靠地跑大量容器」而设计的系统。本文只做整体感知:它解决什么问题、和你熟悉的生信/容器经验怎么衔接、后面值得拆成哪些专题再读。涉及网络、存储、权限等实现细节,概述里刻意不写透,避免一上来被概念淹没。
阅读与编号约定(全文统一)
| 符号 | 含义 |
|---|---|
| 图 1~图 5 | 本文导读插图;与图中英文标题 Fig.1~Fig.5 一一对应(同一图)。 |
| 图 5 中的 1~5 | 从「提交工作负载」到「节点上容器运行」的主路径步骤,与下文「步骤 1~5 速查表」及 Fig.5 内标注一致。 |
| kube-apiserver | 首次出现用全称;后文可简写为 apiserver(语义相同)。 |
导读:几张架构示意图
下图采用与 引物设计-01.概述-03.应用场景 相同的插图方式:独立矢量图文件 + 图题说明(),便于印刷与排版;样式为白底、细线框、统一配色(科研示意图常用风格)。图中 英文标注(Fig.1–5)可避免字体编码问题;中文解读见各小节标题与图下文字。图片为 SVG,若站点对 SVG 支持不佳,可用 Inkscape 等导出为 PNG 后替换同路径 .png。
导读顺序建议:图 1(单机 vs 集群)→ 图 2(控制面与节点)→ 图 3(声明式)→ 图 4(与 Argo/生信栈)→ 图 5(总览:组件、信息流、调度);图 5 是全文信息密度最高的一张,可反复对照步骤表阅读。
图 1 单机容器 vs Kubernetes 集群(角色对比)
左侧是你直接触达容器;右侧是你先向 API 声明期望,由控制面在多台节点上落实为 Pod(内再跑容器)。
图 2 控制面与工作节点(极简)
入门阶段不必记清每个组件名称,只需有印象:调度决定 Pod 落在哪台 Node;控制器负责让实际状态跟上你的 YAML。
图 3 声明式:期望状态与实际状态
你不是逐条 ssh 敲命令,而是描述期望;集群反复收敛到该状态(与「只提交作业脚本、调度器负责跑」的体感相近)。
图 4 生信栈:容器镜像 → Kubernetes → Argo Workflows
Argo 不替代 K8s:它在 K8s 之上声明「第几步跑哪个容器」;镜像仍是你的生信环境单位。
前四张图按主题拆分;图 5 将控制面、数据面、步骤 1~5 主路径合在一张总览中,可与紧随其后的「步骤 1~5 速查表」对照阅读。
图 5 整体业务逻辑:控制面 / 数据面、信息流与调度(总览)
步骤 1~5 速查表(与 Fig.5 图中标注一致)
下列顺序与 Fig.5 中 1~5 及图底英文 Numbered flow 一致,便于对照插图阅读。
| 步骤 | 主信息流 | 说明 |
|---|---|---|
| 1 | 客户端 → kube-apiserver | 通过 kubectl、API 客户端或 CI 提交/变更资源(Deployment、Job 等)。 |
| 2 | kube-apiserver ↔ etcd | 对象状态持久化;集群的“单一事实来源”经 apiserver 访问,典型部署下仅 apiserver 直连 etcd。其它组件通过 apiserver watch/list 变化。 |
| 3 | kube-controller-manager ↔ apiserver | 控制循环(reconcile):如 ReplicaSet 按副本数创建/删除 Pod;Job 控制器管理 Job/Pod 生命周期等。 |
| 4 | kube-scheduler ↔ apiserver | 仅处理尚未绑定节点的 Pod:Predicates(可行)→ Priorities(打分)→ Bind 写入 spec.nodeName。调度器不在节点上起进程。 |
| 5 | kubelet ↔ apiserver;kubelet → CRI → runtime | 各节点 kubelet 仅执行已调度到本节点的 Pod;经 CRI 调用 containerd/CRI-O 等拉镜像、起停容器;Pod 状态经 apiserver 回写,最终进入 etcd。 |
与图 1~4 的关系:图 1、2 对应上表中谁在发请求、控制面与节点如何分工;图 3 对应步骤 2~5 背后的声明式收敛;图 4 说明 Argo 在 apiserver 之上增加工作流语义,不改变步骤 1~5 的主干。
主要组件与职责(与图 5 及步骤对照)
| 组件 | 位置 | 职责(一句话) | 常见步骤 |
|---|---|---|---|
| kube-apiserver | 控制面 | 集群 API 统一入口:认证/授权/准入后持久化对象;提供 watch/list。 | 1、2 及全程枢纽 |
| etcd | 控制面侧 | 保存 Kubernetes 对象与集群元数据;高可用多为多副本。 | 2 |
| kube-controller-manager | 控制面 | 内嵌多路控制器,使实际状态向期望 spec 对齐(副本、Job、Node 等)。 | 3 |
| kube-scheduler | 控制面 | 为未绑定节点的 Pod 选节点并 bind。 | 4 |
| kubelet | 工作节点 | 本节点 Pod 生命周期:创建容器、探针、卷挂载等。 | 5 |
| kube-proxy | 工作节点 | 实现 Service 到 Pod 的节点侧转发(iptables/IPVS 等);不在图 5 主路径上逐条画出。 | (并行于业务流量) |
| container runtime | 工作节点 | 经 CRI 被 kubelet 调用,真正运行容器。 | 5 |
调度原理(入门版,与步骤 4、5 衔接)
- 输入:
spec.nodeName为空、且可被调度器处理的 Pod。 - 处理链:Predicates(资源、污点/容忍、亲和性等硬条件)→ Priorities(软偏好打分)→ Bind(更新 Pod 与节点绑定)。
- 与 kubelet 分工:调度器只做绑定决策;拉起容器在步骤 5 由 kubelet + runtime 完成;失败则反映为 Pod 状态,由控制器与 kubelet 协同重试或上报。
1. 本文默认你知道什么、不假设什么
- 默认你已了解:镜像、容器、挂载卷这类容器级概念(本目录 Docker / Singularity 相关文已覆盖)。
- 不假设你有:公有云账号经验、VPC、负载均衡等云平台产品经验,也不假设你装过或使用 K8s。
- 阅读目标:读完能用自己的话说明「K8s 在栈里大概处于哪一层」「为什么 Argo 这类工具总提到它」,并知道后续该补哪类文档。
2. 用生信场景直觉理解:从「一台机跑容器」到「一群机器交给一个调度大脑」
在单机上,你通常自己决定:什么时候起容器、用多少 CPU/内存、目录挂哪里。机器多了以后,手工协调会很痛苦。可以把 K8s 粗想成:
- 许多台物理机或虚拟机(节点)组成一个集群;
- 你不再登录某一台机去
docker run,而是向集群提交一份声明(常见是 YAML):希望运行哪些容器镜像、要多少资源、希望如何扩缩或重启; - 集群里的控制面负责把这份声明落实成「具体在哪个节点上起 Pod、挂了怎么再起」等——你关心期望状态,而不是每一台机上的进程细节。
这和在 HPC 上提交作业、在云平台点「创建实例」不完全一样,但心理模型可以类比:你提交的是「工作描述」,系统负责在资源池里找位置执行。
3. Kubernetes 三个字里先抓住的三件事
为避免概述变成术语表,这里只保留三个足够支撑整体图景的抓手:
容器编排(Orchestration)
在多台机器上调度容器、处理崩溃重启、滚动更新等。你已熟悉的「容器」是积木,K8s 是管理很多积木怎么摆、怎么换的那套规则与控制器。声明式(Declarative)
你描述「我想要什么状态」(例如运行某个镜像的 3 个副本),而不是逐步手写「先 ssh 到 A 机再启动」。集群会持续把实际状态往期望状态靠拢。云无关的一层抽象(可运行在多种环境上)
同一套 K8s 概念既出现在自建机房,也出现在托管 Kubernetes(各云厂商的「托管 K8s」)。云平台提供底层虚拟机、网络、磁盘;K8s 不负责替你开账单,但负责在已有机器上编排容器。没有云经验时,只需先建立「集群 = 一组可跑容器的资源池」这一层即可。
4. 一张「最小概念地图」(知道名字即可,细节留给后续篇)
下面几个词在几乎所有 K8s 入门里都会出现,这里只给一句话定位,避免展开:
| 概念 | 一句话 |
|---|---|
| 集群(Cluster) | 一组协同工作的机器 + 控制组件,对外像一个「大资源池」。 |
| 节点(Node) | 集群里真正跑工作负载的机器(工作节点);控制面节点常单独说明,入门可先混为一个整体。 |
| Pod | 最小调度单位,通常内含一个或多个紧密协作的容器,共享网络与部分存储视角。 |
| 工作负载资源(如 Deployment、Job 等) | 描述「跑哪些 Pod、几个副本、如何更新」的对象类型;生信批任务常会碰到 Job/CronJob 这类语义。 |
你不必在概述阶段分清所有资源类型;只要记住:日常对话里说的「往 K8s 上丢一个任务」,多数时候最终会落成集群里的一批 Pod。
5. 和生信流水线、Argo 的关系(为什么总一起出现)
本系列已有 Argo Workflows 入门:Argo 把工作流定义成 Kubernetes 上的资源,步骤往往是容器。因此:
- 没有 K8s,通常就没有「标准形态」的 Argo 集群版(本地 minikube 也算一种小型 K8s);
- 你会在 Argo 文档里反复看到 Pod、YAML、
kubectl——它们不是 Argo 发明的,而是 K8s 通用语言。
可以把关系想成:K8s 提供「在哪、用多少资源、如何跑容器」;Argo 在之上提供「步骤依赖、DAG、重试、制品传递」等工作流语义。先建立 K8s 的整体感,再读 Argo 会顺很多。
6. 技术复杂度:为什么建议拆成系列文档
K8s 的学习曲线陡,一半来自概念多,一半来自与网络、存储、身份强绑定。比较稳妥的顺序是:
- 概述与心智模型(本文):解决「它是什么、为什么要存在」。
- 集群从哪来:本地 minikube/kind、实验室 kubeadm、云托管,各选一两条路径即可,不必一次比较完所有厂商。
- 日常交互:
kubectl、命名空间、最基本的查看 Pod/日志(与生信「查作业、看日志」对应)。 - 与工作负载相关:Job、资源请求与限制、调度与排队(和生信资源申请直接相关)。
- 再按需深入:存储卷、网络、RBAC、Ingress 等——用到再查,避免概述里一次性铺开。
对应系列文档按相同前缀编号,建议按顺序阅读(详见各篇文首导航):
| 序号 | 文档 | 主题 |
|---|---|---|
| 01 | 本文 | 概述与心智模型;图 1~图 5、步骤 1~5(图 5) |
| 02 | pipeline-frameworks-k8s-02.集群与运行环境 | 集群从哪来:本地 kind/minikube、常见路径 |
| 03 | pipeline-frameworks-k8s-03.kubectl与日常观测 | kubectl、命名空间、Pod/日志 |
| 04 | pipeline-frameworks-k8s-04.工作负载与资源调度 | Job、资源请求与限额、调度直觉 |
| 05 | pipeline-frameworks-k8s-05.存储网络与权限入门 | 卷、Service/Ingress 入门、RBAC 概念 |
7. 小结
- 整体:Kubernetes 在多台机器上做容器编排,核心可记为 声明式期望状态 + 控制循环 + 调度 + 节点执行(导读 图 3~图 5,步骤 1~5)。
- 与单机 Docker 对比:从「
docker run直达容器」变为「声明 → apiserver → etcd → 控制器/调度器 → kubelet → 运行时」(图 1、图 5)。 - 与生信栈:镜像仍是环境单位;Argo 等在 apiserver 之上编排步骤,底层仍走 图 5 的主路径(图 4)。
- 后续阅读:系列 k8s-02~k8s-05 分别从集群来源、
kubectl、工作负载与资源、存储/网络/RBAC 展开;文中术语与 本文「阅读与编号约定」 保持一致。
建议动手顺序:在本地起 kind/minikube 等最小集群 → 用 kubectl 跑通一个 Pod → 对照 图 5 在日志里观察 Pending / Scheduled / Running 与节点绑定 —— 比单纯背组件名更有效。