HPCGame kube 集群使用指南¶
Tl;Dr;
- 用 vscode 连接到集群,可以 attach 到容器,比较方便
- 需要注意 kubectl 版本,至少 1.30,否则无法连接,可以使用我们的二进制文件
- kubeconfig 要放到
~/.kube/config下,可以省去很多麻烦 - 所有题目都在附件提供了环境描述
yaml,使用kubectl apply -f <xxx>.yaml创建pods,即可获得开发环境 - 通过
kubectl get pods来获取目前运行的pods - 运行
kubectl exec pod/<podname> -ti -- bash访问容器 - 使用
kubectl cp本地文件 容器名:路径以及kubectl cp容器名:路径 本地文件在本地与远端传递文件 - 使用
kubectl port-forward pod/{podname} local_port:remote_port进行端口转发 - 集群不保证pod的持久化,建议每位选手创建一个pvc,mount 到容器里,然后把内容存在对应的容器中
集群的使用¶
比赛集群是通过 kubernetes 管理的,我们提供了 kubeconfig 文件,可以通过 kubectl 访问集群。访问 https://hpcgame.pku.edu.cn/kube/_/ui/ ,可以可视化管理 kubeconfig 与集群资源。
kube ui¶
访问 https://hpcgame.pku.edu.cn/kube/_/ui/ ,将会跳转至 hpcgame 的应用验证页面,点击登录到 HPCGame 2nd cluster ,即可访问 kubeui 。
令牌 - 获取 kubeconfig¶
在左侧导航栏中,进入令牌管理页面,点击右上角“添加令牌”。点击“显示Kubeconfig”,即可获取 kubeconfig 文件,请复制文件内容并按下节中配置 kubeconfig 的步骤操作。
储存 - PVC¶
在 Kubernetes 中,PersistentVolumeClaim (PVC) 是一种用于请求存储资源的对象,你可以将其挂载到特定的Pod上,它使Pod能够动态地请求持久存储。
访问模式¶
在 Kubernetes 中,访问模式(Access Modes)定义了 Pod 可以如何访问存储卷。主要有三种访问模式:
| 访问模式 | 简介 | 使用场景 |
|---|---|---|
| ReadWriteOnce | 单节点上的多个 Pod 可读写访问 | 大多数应用场景,单实例访问存储卷 |
| ReadOnlyMany | 多节点上的多个 Pod 只读访问 | 需要多个实例读取同一数据,如静态数据或配置文件 |
| ReadWriteMany | 多节点上的多个 Pod 可读写访问 | 需要多个实例共享读写同一数据,如共享文件系统、分布式数据库 |
StorageClass¶
本次比赛我们使用了多种储存设备,可以通过 k8s 的 storage class 选择储存设备。请注意这些储存设备的地域关系。部分设备只能在特定地域使用,有时候需要跨地域传输数据。我们强烈推荐在 pod 对应的区域选择合适的储存设备,否则速度可能会相当糟糕。你可以用 kubectl get sc 查看所有的 storage class,我们在这里提供一些说明。
wm2-nfs:位于昌平校区,只有昌平校区机器都可以访问。储存介质为 SSD,每个机器的可用读写速度约 2GB/syanyuan-nfs:位于燕园校区,只有燕园校区机器都可以访问。储存介质为 SSD,每个机器的可用读写速度约 1GB/s(受限于网络)second number is eightx86-amd-local-hostpath:位于燕园校区,只有x86_amd机器可以访问,每台机器有各自的hostpath储存。储存介质为 NVME,每个机器的可用读写速度约 4GB/snpu-local-data:用于 npu 训练时储存临时数据,每台机器有各自的hostpath储存。储存介质为 NVME,每个机器的可用读写速度约 4GB/sjuicefs:位于燕园校区,所有机器都可以访问。储存介质为 HDD 集群,IOPS 特别低,请不要在上面放小文件,比如conda环境。昌平校区每个机器的可用读写速度约 500MB/s、燕园校区每个机器的可用读写速度约 1GB/s
需要注意的是,npu-local-data ,openebs-hostpath ,x86-amd-local-hostpath 只支持 ReadWriteOnce 的访问模式。
任务 - Job¶
Job 是一种控制器,用于一次性任务或批处理任务。它确保指定数量的 Pod 成功完成任务。一旦所有的 Pod 成功完成任务,Job 就会终止。在使用场景上,Job 通常适用于需要执行某个操作并期望在操作结束后关闭的任务。
注意,在 Kubernetes 中,当你创建一个 Job 时,它会根据 Job 的配置来生成相应的 Pod,它们会出现在 Pod 页面中。
容器 - Pod¶
Pod 是 Kubernetes 中最小的可调度单元,是一组一个或多个容器的集合,这些容器共享存储、网络资源以及一个 spec,它描述了这些容器应该如何运行。在使用场景上,Pod 通常用于长期运行的服务。
创建 Job / Pod:
- 输入 Job/Pod 名称
- 根据题目要求与下面的说明选择容器镜像与架构
- 如有需要,在挂载PVC中选择你已经创建的PVC,并指定其挂载路径。之后,你可以在Pod的对应路径访问PVC
- 设置CPU与内存。CPU的单位为m(milliCPU),1000m即一核;内存的单位为Gi
- 如无更多需求,其他配置可以保持默认,点击创建
- 等待状态变为 Running,注意,这一过程可能持续较长时间,请坐和放宽
可以直接使用题目提供的yaml文件,通过 kubectl apply -f <xxx>.yaml 来创建Pod。
如果在创建的过程中遇到问题,请点击操作栏的第一个图标,查看日志并反馈给我们。
硬件分区
昌平校区:同分区机器具有 100Gbps 网络互联
x86:处理器为 Intel Xeon Platinum 8358。label: hpc.lcpu.dev/partition=x86。gpu-a800:处理器为 Intel Xeon Platinum 8358,配备 A800 GPU。使用 MIG 技术,每位选手可使用约单张卡 2/7 的计算资源和 20G 显存。label:nvidia.com/gpu-product=NVIDIA-A800-80GB-PCIegpu-l40:处理器为 Intel Xeon Platinum 8358,配备 L40 GPU。fp64 计算能力较低,但每个任务可以使用所有算力。label:nvidia.com/gpu-product=NVIDIA-L40-40GB-PCIe
燕园校区:
x86_amd:处理器为 AMD Epyc 9654。配备V100 GPU,有高速 SSD,适合跑 vscodearm:处理器为 Kunpeng 920 7282C。单颗 CPU 80 核,每台机器 2 个 CPU socket。内存为DDR5 4800。由于工作失误,该机器内存通道只插满了一半,比较适合跑计算密集型任务npu:处理器为 Kunpeng 920 5250 * 4。单机配备 8 个 920B NPUnpu-inf:Kunpeng 920 5250 * 2,单机配备 4 张 Atlas 300I DUO NPU,共有 8 个 310P NPU 核心,适合跑推理任务
其中,arm ,npu ,npu-inf 通过 25G 网络互联。燕园校区所有机器之间是 10G 网络互联。
设置SSH key¶
在左侧导航栏中,进入配置管理-SSHAuthorizedKeys,点击创建SSHAuthorizedKeys,将你的ed25519或rsa公钥粘贴后即可,这个公钥会被自动应用于你后续创建的所有容器。
kubectl¶
kubectl 是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互和管理
安装 kubectl¶
注意,你的kubectl版本应不低于1.30,所以请不要使用vscode自动下载的kubectl
参见 https://kubernetes.io/zh-cn/docs/tasks/tools/#kubectl
除此之外,你还可以从下方我们提供的链接中直接下载系统对应的二进制文件,并将其加入系统PATH,其版本均为1.32.0。
https://disk.pku.edu.cn/link/AA832D1185BCA24642B252525E825488D2
配置 kubeconfig¶
注意,用于配置集群访问的文件称为 kubeconfig 文件。这是引用到配置文件的通用方法,并不意味着有一个名为 kubeconfig 的文件。
创建 ~/.kube/config 文件,并将你从 kubeui 令牌管理页面复制得到的 kubeconfig 文件内容粘贴进去保存。
请注意,从HPCGame网站获取的kubeconfig文件一定要保存到 ~/.kube/config 下。
用 vscode 连接到集群¶
使用kubernetes插件¶
请在vscode中安装kubernetes与Dev Containers插件,缺一不可。
配置vscode的kubernetes插件¶
按 Ctrl+Shift+P / Command+Shift+P(对于MacOS使用者) ,输入set kubeconfig并点击,选择 Add new kubeconfig,然后浏览并选择你之前配置的 Kubeconfig 文件。确认导入后,Kubernetes 插件将显示你的集群信息。
连接容器进行开发¶
在连接的集群中,找到Workloads,在其中找到Pods,选择你想要连接的容器名称,右键并点击Attach VSCode选项。
使用wsl的注意事项¶
对于wsl用户,你需要:
- wsl中安装kubectl并配置kubeconfig
- 在windows中安装kubectl并kubeconfig
- 注意,这两个kubeconfig文件的内容应该相同
而在wsl内attach vscode到容器的时候,需要注意,vscode会打开一个新窗口,校验Windows的kubeconfig配置
连接到容器¶
kubectl exec¶
可以使用 kubectl exec 命令来连接到容器。
kubectl exec pod/<podname> -ti -- bash
ssh连接(不推荐)¶
为了通过ssh连接到pod,你需要按照上节的步骤添加ssh key或进入容器后自行设置密码
你可以运行以下命令,将容器的22端口映射到本机的10022端口
kubectl port-forward pod/{podname} 10022:22
其中,{podname}为你想要连接的容器的名称
请保持该命令在后台运行,之后,你就可以使用vscode的remote-ssh连接localhost的10022端口进行开发
使用YAML文件创建Jobset / Pod¶
选手可以在HPCGame网站上使用可视化界面创建Job和Pod,也可以使用Yaml文件以及 kubectl 工具创建。
在随题目下发的yaml参考中,具有描述如何创建一个Job或者Pod的参考文件;在每个题目的handout中也附带了yaml文件描述组委会预设的、针对本题创建的Job / Pod配置。 注意此类配置仅为方便选手创建环境进行开发和调试,并不代表最终评测的环境,最终评测环境请以题面为准。
选手可以通过 kubectl apply -f <xxx>.yaml 来创建一个Job / Pod。
使用kubectl查看集群的资源使用情况和剩余资源情况¶
有两个queue可以查看。
lq: local queue。你自己的资源情况。 cq: cluster queue。集群的资源情况。
获取队列:¶
kubectl get lq
kubectl get cq
示例输出:
kubectl get lq
NAME CLUSTERQUEUE PENDING WORKLOADS ADMITTED WORKLOADS
default default-queue 1
kubectl get cq
NAME COHORT PENDING WORKLOADS
default-queue hpcgame 6
judge-queue hpcgame 0
查看队列资源情况¶
kubectl describe lq
kubectl describe cq
将会列出lq / cq中所有队列的资源情况。
如果需要单独查看,例如judge-queue,的资源情况,运行
kubectl describe cq judge-queue
将会单独列出judge-queue中的资源情况。
对于MPI程序,使用krun工具在Jobset中发现其他Pods¶
运行
krun init
以初始化环境
运行
krun host
以查看所有同jobset下pods。
在Jobset多Pods环境中使用MPI运行程序¶
MPI需要获取所有pods的host信息。采用上述 krun 工具,运行
krun host -n -I > hostfile
(-n 去除表头,-I只获取IP地址)
以获取本jobset中所有pods的host信息,保存到hostfile文件中。
在使用 mpirun 运行MPI程序时,添加 -hostfile 选项并指定上述hostfile文件。
mpirun -hostfile hostfile <your_program>
任务定义文件样例¶
单 Pod 任务:
apiVersion: v1
kind: Pod
metadata:
name: test
labels:
name: test
spec:
nodeSelector:
hpc.lcpu.dev/partition: __REPLACE_NODE__
containers:
- name: test
securityContext:
capabilities:
add: ["SYS_PTRACE", "IPC_LOCK"]
image: crmirror.lcpu.dev/hpcgame/intel:latest
resources:
limits:
memory: __REPLACE_LIMITS_MEMORY__
cpu: __REPLACE_LIMITS_CPU__
command:
- sleep
- inf
# 添加 volumeMounts 配置
volumeMounts:
- name: my-pvc-volume # 卷的名称,需要和下面volumes中的名称对应
mountPath: /mnt/data # 容器内的挂载路径
# 添加 volumes 配置
volumes:
- name: my-pvc-volume # 卷的名称
persistentVolumeClaim:
claimName: my-pvc # 已存在的PVC名称
对于 MPI 任务,使用 JobSet 的方法运行:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
resources:
requests:
storage: 64Gi
accessModes:
- ReadWriteMany
storageClassName: wm2-nfs
---
apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
name: testMPIJob # Replace with your jobname
spec:
network:
enableDNSHostnames: true
subdomain: testMPIJob
replicatedJobs:
- name: workers
replicas: 1
template:
spec:
backoffLimit: 0
# completions 和 parallelism 必须相等,为 Pod 数
completions: __REPLACE_POD_NUM__
parallelism: __REPLACE_POD_NUM__
template: # Describe a pod
metadata:
annotations:
ssh-operator.lcpu.dev/inject: enabled
lxcfs.lcpu.dev/inject: disabled
spec:
nodeSelector:
# 与单 Pod 的节点选择器功能相同
hpc.lcpu.dev/partition: __REPLACE_NODE__
# 将下方内容解除注释,即可指定任务调度到不同节点
# ------------ BEGIN ------------
# affinity:
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - topologyKey: "kubernetes.io/hostname"
# labelSelector:
# matchExpressions:
# - key: jobset.x-k8s.io/name
# operator: In
# values:
# - __REPLACE_JOBNAME__
# ------------ END ------------
containers: # Describe a container inside a pod
- name: worker
# Pre-defined images provided by HPCGame:
# crmirror.lcpu.dev/hpcgame/full:latest
# crmirror.lcpu.dev/hpcgame/llvm:latest
# crmirror.lcpu.dev/hpcgame/gcc:latest
# crmirror.lcpu.dev/hpcgame/nvhpc:latest
# crmirror.lcpu.dev/hpcgame/julia:latest
# crmirror.lcpu.dev/hpcgame/base:latest
# crmirror.lcpu.dev/hpcgame/intel:latest
# crmirror.lcpu.dev/hpcgame/cuda:latest
# crmirror.lcpu.dev/hpcgame/aocc:latest
# crmirror.lcpu.dev/hpcgame/hpckit:latest
# Or any other images that could be get via a URL.
image: __REPLACE_CONTAINER_IMAGE__
# Note: replace this with command that you want to use.
# ```
# command:
# - sleep
# - inf
# ```
# Or
# `command: ["sleep", "inf"]`
# This is the default command that would keep the container to run sliently
# for the convenience of login
command:
- sleep
- inf
resources:
# HPC场景中,limits和requests中所有值必须相同
limits:
cpu: __REPLACE_LIMITS_CPU__ # E.g. 4
memory: __REPLACE_LIMITS_MEMORY__ # E.g. 8Gi
rdma.hpc.lcpu.dev/hca_cx5: 1
requests:
cpu: __REPLACE_REQUESTS_CPU__ # E.g. 4
memory: __REPLACE_REQUESTS_MEMORY__ # E.g. 8Gi
rdma.hpc.lcpu.dev/hca_cx5: 1
volumeMounts:
- name: __REPLACE_VOLUME_NAME__ # The name of volume defined in `volumes` section, see below
mountPath: __REPLACE_VOLUME_MOUNT_PATH__
volumes:
- name: __REPLACE_VOLUME_NAME__
persistentVolumeClaim: # From which PVC does this volume come from?
claimName: __REPLACE_PVC_NAME__