前言

在现代数据中心里,经常存在两座”孤岛”:一座是运行传统 HPC 和批处理作业的 LSF 集群,另一座是运行微服务和 AI 服务的 Kubernetes (K8s) 集群。这种割裂不仅导致资源利用率低,也增加了管理复杂度。

IBM Spectrum LSF Suite(HPC 版和 Enterprise 版)内置了 LSF Connector for Kubernetes,旨在打破这一边界。它允许 LSF 作为 K8s 的调度器,让 K8s Pods 与 LSF 批处理作业在同一套基础设施上共存。

本篇将带您了解这一集成的架构原理,并演示如何通过 LSF 调度器提交 K8s Pod 和并行作业。

一、集成架构:告别资源孤岛

LSF 与 Kubernetes 的集成方案并非简单的双系统并排,而是深度的调度融合。

1. 逻辑架构

特性 说明
单一资源池 LSF 和 Kubernetes 共享底层物理机器,无需物理隔离
角色分离 LSF Master 和 Kubernetes Master 必须部署在不同物理机
统一调度 LSF 充当 K8s 的调度器,决定 Pod 放置位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────┐
│              LSF + Kubernetes 融合架构                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   ┌─────────────┐              ┌─────────────┐              │
│   │ LSF Master  │              │  K8s Master │              │
│   │  (独立节点)  │              │  (独立节点)  │              │
│   └──────┬──────┘              └──────┬──────┘              │
│          │                            │                      │
│          │      LSF Connector         │                      │
│          └────────────┬───────────────┘                      │
│                       ↓                                      │
│   ┌─────────────────────────────────────────────────────┐   │
│   │              共享计算节点池                          │   │
│   │   ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐          │   │
│   │   │Node1│ │Node2│ │Node3│ │Node4│ │Node5│          │   │
│   │   │LSF  │ │LSF  │ │LSF  │ │LSF  │ │LSF  │          │   │
│   │   │+K8s │ │+K8s │ │+K8s │ │+K8s │ │+K8s │          │   │
│   │   └─────┘ └─────┘ └─────┘ └─────┘ └─────┘          │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

这种架构使得管理员可以维护一套统一的环境,根据实际负载动态分配资源,而不是维护两个僵化的孤岛。

2. 调度流程

1
2
3
4
5
6
7
8
9
10
11
12
13
用户提交 K8s Pod (schedulerName: lsf)
              ↓
K8s API Server 接收请求
              ↓
LSF Connector 监听到 Pending Pod
              ↓
LSF 调度器评估资源、队列策略、公平共享
              ↓
LSF 决定目标节点
              ↓
Pod 在指定节点上启动
              ↓
LSF 持续跟踪 Pod 状态

二、实战演练:像提交 Job 一样提交 Pod

集成启用后,用户依然可以使用熟悉的 Kubernetes CLI (kubectl) 来提交任务,只需指定调度器即可。

1. 定义使用 LSF 调度的 Job

编写一个标准的 K8s Job YAML 文件(例如 job-1.yaml),关键在于 spec 中添加 schedulerName: lsf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: batch/v1
kind: Job
metadata:
  name: job-1
spec:
  template:
    metadata:
      annotations:
        lsf.ibm.com/queue: "normal"  # 指定 LSF 队列
    spec:
      schedulerName: lsf             # 关键:指定 LSF 为调度器
      containers:
      - name: myjob
        image: ubuntu:latest
        command: ["sleep", "120"]
        resources:
          requests:
            cpu: "1"
            memory: "512Mi"
          limits:
            cpu: "2"
            memory: "1Gi"
      restartPolicy: Never

关键配置说明

配置项 说明
schedulerName: lsf 指定 LSF 为调度器(必需)
lsf.ibm.com/queue 指定 LSF 队列(可选)
resources.requests 资源请求,LSF 用于调度决策
resources.limits 资源限制,K8s 用于 cgroups 约束

2. 提交与验证

使用 kubectl 提交作业:

1
2
$ kubectl create -f job-1.yaml
job.batch/job-1 created

状态流转

阶段 状态 说明
1 Pending 作业在 K8s 中等待调度
2 Scheduled LSF 接管调度,分配资源
3 Running Pod 开始在指定节点运行
4 Completed 作业完成

查看 Pod 状态

1
2
3
$ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
job-1-abc12   1/1     Running   0          30s

3. 可观测性与排错

LSF 会自动将作业信息作为 Label(标签)Annotation(注解) 注入到 Pod 中,方便追踪。

1
$ kubectl describe pod job-1-abc12

注入的 LSF 元数据

标签/注解 示例值 说明
lsf.ibm.com/jobId 305 关联的 LSF 作业 ID
lsf.ibm.com/queue normal 使用的队列
lsf.ibm.com/pendingReason - 排错神器

排错技巧

如果作业一直 Pending,查看 Annotations 中的 lsf.ibm.com/pendingReason

1
2
$ kubectl get pod job-1-abc12 -o jsonpath='{.metadata.annotations.lsf\.ibm\.com/pendingReason}'
Blocked by Kubernetes policies (Insufficient cpu)

这会直接显示 LSF 的拒绝原因,帮助快速定位问题。

三、高级功能:在 K8s 上运行并行作业 (Parallel Jobs)

Kubernetes 原生对并行作业(如 MPI 任务、分布式 AI 训练)的支持相对有限。LSF Connector 引入了自定义资源定义 (CRD) paralleljobs.ibm.com,填补了这一空白。

1. 并行作业结构

LSF 定义的 ParallelJob 包含多个 任务组 (Task Groups)

例如,在 AI 训练场景中:

任务组 角色 副本数
group0 Parameter Server 1
group1 Worker 4

每个组内可以包含多个运行相同镜像的 Pod。

2. 定义并行作业

创建一个 YAML 文件(例如 pjob-3.yaml),使用 kind: ParallelJob

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: ibm.com/v1alpha1
kind: ParallelJob
metadata:
  name: pjob-3
spec:
  schedulerName: lsf
  taskGroups:
  # Parameter Server 组
  - metadata:
      name: ps
    spec:
      replica: 1
      template:
        spec:
          containers:
          - name: ps-container
            image: tensorflow/tensorflow:latest
            command: ["python", "ps_server.py"]
            resources:
              requests:
                cpu: "2"
                memory: "4Gi"
  # Worker 组
  - metadata:
      name: worker
    spec:
      replica: 4
      template:
        spec:
          containers:
          - name: worker-container
            image: tensorflow/tensorflow:latest-gpu
            command: ["python", "train.py"]
            resources:
              requests:
                cpu: "4"
                memory: "8Gi"
                nvidia.com/gpu: "1"

3. 提交与管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 提交并行作业
$ kubectl create -f pjob-3.yaml
paralleljob.ibm.com/pjob-3 created

# 查看并行作业状态
$ kubectl describe pj pjob-3
Name:         pjob-3
Namespace:    default
Status:       Running
Task Groups:
  Name:     ps
  Replica:  1
  Status:   Running
  Name:     worker
  Replica:  4
  Status:   Running

# 查看所有相关 Pod
$ kubectl get pods -l paralleljob=pjob-3
NAME              READY   STATUS    RESTARTS   AGE
pjob-3-ps-0       1/1     Running   0          2m
pjob-3-worker-0   1/1     Running   0          2m
pjob-3-worker-1   1/1     Running   0          2m
pjob-3-worker-2   1/1     Running   0          2m
pjob-3-worker-3   1/1     Running   0          2m

LSF 会协调启动所有组内的 Pod。当您看到所有 Pod 成功运行时,证明 LSF 已经成功在 Kubernetes 环境中编排了复杂的并行工作负载。

集成优势总结

优势 传统方案 LSF + K8s 融合
资源利用率 两套独立资源池,利用率低 统一资源池,按需分配
管理复杂度 维护两套系统 统一管理界面
调度策略 K8s 原生调度较简单 LSF 丰富的调度策略(公平共享、优先级、抢占)
并行作业 K8s 原生支持有限 ParallelJob CRD 完美支持
可观测性 分散在两个系统 LSF 标签注入,统一追踪
1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────────────────────────┐
│                    工作负载统一视图                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   传统 LSF 作业  ───┐                                        │
│                     │                                        │
│   K8s Pods      ────┼────→  LSF 调度器  ────→  统一资源池   │
│                     │                                        │
│   K8s ParallelJob ─┘                                        │
│                                                              │
└─────────────────────────────────────────────────────────────┘

下期预告:

随着集群运行时间的增长,日志和历史数据会不断累积,导致磁盘空间告急。Elasticsearch 索引该如何维护?数据盘满了怎么迁移?在系列的最后一篇《IBM Spectrum LSF Suite 最佳实践 (7):Explorer 数据维护与 Elasticsearch 管理技巧》中,我们将关注长期运维中的数据管理问题。

参考资料

  1. IBM Spectrum LSF Suite - Installation Best Practices Guide (Redbooks)
  2. IBM Spectrum LSF Documentation - Kubernetes integration
  3. Kubernetes Custom Resources