2. 版本申明

版本

修改内容

修改时间

v1.0

初始化

5/12/2022

v1.1

新增二次开发说明

5/22/2023

v1.2

更新组件文档说明

6/25/2023

v1.3

更新组件说明

7/3/2023

v1.4

更新一些词语

12/12/2023

v1.5

更新一些格式以及内容

4/8/2024

v1.6

更新异构平台部分

5/20/2024

v1.7

更新格式部分

6/24/2024

v1.8

更新前置依赖

7/9/2024

v1.9

增加containerd配置说明

11/28/2024

v1.10

更新一些内容

12/3/2024

v1.11

更新arm以及containerd使用说明

12/5/2024

3. 简介

TopsCloud 是基于GCU的云原生解决方案包,其包括enflame-container-toolkit,k8s-device-plugin,gcu-exporter,gcu-operator等重要组件用于支持GCU K8S集群。

4. 专有名词解释

名词

描述

TopsCloud

燧原基于GCU的K8S集群化解决方案

enflame-container-toolkit

燧原基于GCU的容器化插件

k8s-device-plugin

燧原基于GCU的k8s插件,向k8s集群注册GCU资源

gcu-exporter

燧原GCU的数据采集组件,提供gcu设备运行相关指标的时序数据

gcu-feature-discovery

用于给GCU设备打上标签

node-feature-discovery

用于给服务器设备打上标签

gcu-operator

自定义资源GcuResource用于自动化管理gcu软件

go-eflib

golang 二次开发库

5. 前置依赖

  • 已安装docker, containerd(k8s version >=1.24)

  • Kubernetes版本高于1.9

  • GCU Driver

6. 平台以及OS支持说明

  • X86 平台支持OS:ubuntu, tencentos, openeuler;

  • ARM 平台支持OS:ubuntu,openeuler。

7. 文档使用说明

7.1. k8s-device-plugin使用说明

见《K8S Plugin用户使用手册》。

7.2. enflame-container-toolkit使用说明

见《Container Toolkit用户使用手册》。

7.3. gcu-operater使用说明

见《GCU Operator用户使用手册》。

7.4. gcu-exporter使用说明

见《GCU Exporter用户使用手册》。

7.5. gcushare使用说明

见《GCUSHARE用户使用手册》。

7.6. gcu-feature-discovery使用说明

见《GCU Feature Discovery用户使用手册》。

7.7. node-feature-discovery使用说明

见《Node Feature Discovery用户使用手册》。

7.8. node-problem-detector使用说明

见《Node Problem Detector用户使用手册》。

7.9. 其他组件

其他独立组件见相应的组件文档,确认依赖组件已就绪后,依照用户手册进行安装使用。

8. 二次开发使用说明

首先参考相应的独立组件用户使用手册,另外除了参考相应的独立组件用户使用手册之外, 安装包的Yaml配置文件里涉及容器镜像填写的地方需要用户自我定义以及根据实际使用情况来修改, 可以通过命令:find . -name "*.yaml" | xargs grep "artifact.enflame.cn/enflame_docker_images/enflame" 找到相关文件, 例如:

# cd topscloud_<VERSION>
# find . -name "*.yaml" | xargs grep "artifact.enflame.cn/enflame_docker_images/enflame"
./k8s-device-plugin_2.0.0.beta1/yaml/enflame-device-plugin.yaml:     \
- image: artifact.enflame.cn/enflame_docker_images/enflame/k8s-device-plugin:v2.0.0 \
./k8s-device-plugin_2.0.0.beta1/yaml/enflame-device-plugin-pcie-switch-affinity.yaml:   \
- image: artifact.enflame.cn/enflame_docker_images/enflame/k8s-device-plugin:v2.0.0 \
./k8s-device-plugin_2.0.0.beta1/yaml/enflame-device-plugin-compat-with-cpumanager.yaml:  \
- image: artifact.enflame.cn/enflame_docker_images/enflame/k8s-device-plugin:v2.0.0     \
./gcu-feature-discovery_1.2.10/yaml/gcu-feature-discovery-daemonset.yaml:        \
- image: artifact.enflame.cn/enflame_docker_images/enflame/gcu-feature-discovery:latest  \
./gcu-feature-discovery_1.2.10/all-in-one/yaml/all-in-one.yaml:        \
image: artifact.enflame.cn/enflame_docker_images/enflame/enflame-device-plugin:latest \
............................................
./gcu-operator_2.2.22/enflame-resources/k8s-device-plugin/pcie-switch/daemonset.yaml:      \
- image: artifact.enflame.cn/enflame_docker_images/enflame/k8s-device-plugin:latest    \
./gcu-exporter_1.4.20/yaml/gcu-exporter-non-privileged.yaml:          \
image: artifact.enflame.cn/enflame_docker_images/enflame/gcu-exporter:latest      \
./gcu-exporter_1.4.20/yaml/gcu-exporter.yaml:          \
image: artifact.enflame.cn/enflame_docker_images/enflame/gcu-exporter:latest       \
./gcu-exporter_1.4.20/yaml/gcu-exporter-for-arm.yaml:          \
image: artifact.enflame.cn/enflame_docker_images/enflame/gcu-exporter:latest
..............................................

注:除了以上文件,也需要二次开发用户根据自己的实际使用情况梳理且修改相应的镜像,避免遗漏。

9. containerd配置使用说明

9.1. cgroup driver配置

cgroup driver有两种配置,分别为cgroupfs和systemd,其中cgroupfs为直接通过cgroup文件系统管理cgroup,而systemd则是通过systemd去管理cgroup相对cgroup fs,使用systemd管理cgroup主要有以下优势:

1)简化操作

Cgroupfs 直接操作 /sys/fs/cgroup 文件系统,需手动创建、调整和清理 Cgroup,这在管理多个服务或容器时非常繁琐。Systemd 提供了 API 和服务管理工具,自动完成 Cgroup 的创建和清理,降低了运维复杂性。

2)避免冲突

在使用 cgroupfs 时,多个进程可能尝试操作相同的 Cgroup 层次结构,导致路径冲突。使用 systemd,服务的 Cgroup 是以 system.slice 为根的独立层次结构,避免冲突。

3)资源隔离更全面

systemd 提供更细粒度的资源隔离功能,例如:仅限制服务某些特定子进程的资源使用; 配置服务的 IO 权重(IOWeight)或网络优先级; Cgroupfs 仅提供基础的资源限制功能。

4)集成现代系统的其他功能

Systemd 的优势在于与现代 Linux 系统深度集成,支持 slice 和 scope 的高级分组概念,结合 dbus 或其他监控工具,实现全方位的资源管理和自动化。

其中,当使用较复杂的软件系统,比如kubernetes,使用cgroupfs作为cgroup driver发生冲突的概率会大大提升,所以一般建议在containerd配置中将cgroup driver配置成systemd。

这里以containerd v1.7.24 为例,/etc/containerd/config.toml enflame options内设置 “SystemdCgroup = true” , 如下:

.........................
>           [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.enflame.options]
>             BinaryName = "/usr/bin/enflame-container-runtime"
>             CriuImagePath = ""
>             CriuPath = ""
>             CriuWorkPath = ""
>             IoGid = 0
>             IoUid = 0
>             NoNewKeyring = false
>             NoPivotRoot = false
>             Root = ""
>             ShimCgroup = ""
>             SystemdCgroup = true

9.2. cgroup driver配置的一致性

containerd的cgroup driver配置必须与kubelet保持一致,k8s下kubelet配置的cgroup driver是否与containerd保持一致,如果不一致,会造成冲突运行失败。

k8s version >=1.22 已默认启用systemd作为cgroup driver,可以使用以下命令确认kubelet有没有自定义配置cgroup driver:

ps aux | grep kubelet

9.3. cgroup v1 和cgroup v2

cgroup有v1 和 v2两个版本,

可以使用以下命令查看cgroup版本

mount | grep cgroup

如果存在type为cgroup2的输出,则是cgroup v2:

cgroup2 on /sys/fs/cgroup type cgroup2

如果存在type为cgroup的输出,则是cgroup v1:

cgroup on /sys/fs/cgroup type cgroup

如果同时存在,则同时开启了v1和v2

tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
none on /run/calico/cgroup type cgroup2 (rw,relatime)

这里有三种情况:

用户使用cgroup v1

由于cgroup v1设计简单,用systemd或者cgroupfs 管理区别不大,当然还是建议systemd。

用户使用cgroup v2

cgroup v2较复杂,对于复杂的软件系统如k8s,一定要使用systemd作为cgroup driver。

用户同时使用cgroup v1 和 v2

在ubuntu20.04上,默认同时开启了cgroup v1和v2,此时可以使用cgroupfs,但systemd无法正常工作,需要用户重新配置cgroup,明确只使用v1或者v2。

通过修改/etc/default/grub,可以明确需要使用的cgroup version:

systemd.unified_cgroup_hierarchy=1

其中1代表v2,0代表v1。

9.4. 其他不支持systemd的情况

使用了低版本的container toolkit

对于container toolkit 2.0, 会根据上级容器运行时的配置配置cgroup driver,但是对于container toolkit1.0,并没有支持systemd,所以此时k8s,containerd以及所有其他相关组件必须配置为cgroupfs。

不支持systemd的操作系统

部分操作系统不支持systemd,此时只能使用cgroupfs。

9.5. containerd镜像构建

containerd 自带的命令ctr不带镜像构建功能,需要借助于buildkit:“https://github.com/moby/buildkit” 镜像镜像构建, ctr也不兼容docker命令,使用不是很方便,因此这里推荐采用nerdctl: “https://github.com/containerd/nerdctl” 构建containerd镜像, 示例如下:

## 示例用的nerdctl全量版,根据需要也可以下载精简版, 但是需要额外下载buildkit进行配置。
# wget -c https://github.com/containerd/nerdctl/releases/download/v2.0.0/nerdctl-2.0.0-linux-amd64.tar.gz

wget -c https://github.com/containerd/nerdctl/releases/download/v2.0.0/nerdctl-full-2.0.0-linux-amd64.tar.gz
tar -zxvf nerdctl-full-2.0.0-linux-amd64.tar.gz -C /usr/local/

systemctl enable buildkit containerd --now
systemctl restart buildkit containerd
systemctl status buildkit containerd

安装以及配置好nerdctl后,可以采用topscloud里基础组件包里的 “build-image.sh” 脚本进行containerd镜像构建,如下:

./build-image.sh --cli nerdctl --os ubuntu

对于k8s version >=1.24,推荐采用 nerdctl 或 ctr构建:

./build-image.sh --cli nerdctl
或
./build-image.sh --cli ctr

10. GCU标签自动生成使用说明

10.1. 基础组件

  • enflame-container-toolkit

  • k8s-device-plugin

  • node-feature-discovery

  • gcu-feature-discovery

10.2. 基于NFD与GFD的使用方案

方案 1 - 同GPU方案

该方案部署方式同GPU,基本使用过程示例如下,该方案方便与用户已有的GPU方案保持一致,便于后续升级维护。

1)用户先安装 enflame-container-toolkit以及k8s-device-plugin

2)安装node-feature-discovery,步骤如下:

cd node-feature-discovery_<VERSION>

# 构建node-feature-discovery镜像
./build-image.sh

# apply namespace 为 enflame.com 的nfd yaml,这里也可以修改deploy.sh 执行
kubectl apply -f yaml/nfd.yaml
或
# tke cloud用户 apply namespace 为 tke.cloud.tencent.com 的nfd yaml,这里也可以修改deploy.sh 执行
kubectl apply -f yaml/tke-cloud-nfd.yaml

3)安装gcu-feature-discovery

cd gcu-feature-discovery_<VERSION>

# 构建gcu-feature-discovery镜像
./build-image.sh

# apply gfd daemonset, 这里也可以修改deploy.sh 执行
kubectl apply -f yaml/gcu-feature-discovery-daemonset.yaml

方案 2 - 镜像与DaemonSet合一方案

k8s-device-plugin + node-feature-discovery + gcu-feature-discovery 镜像与daemonset合一方案,基本使用过程示例如下:

1)用户先安装 enflame-container-toolkit;

2)安装k8s-device-plugin + node-feature-discovery + gcu-feature-discovery:

# 构建k8s-device-plugin + node-feature-discovery + gcu-feature-discovery镜像
执行./build-image.sh

# apply k8s-device-plugin + node-feature-discovery +
# gcu-feature-discovery三个文件合一的 yaml文件,这里也可以修改deploy.sh 执行
kubectl apply -f yaml/k8s-device-plugin-with-nfd-gfd.yaml

方案 3 - 自定义或自我开发

用户也可以基于api或提供的二进制文件,自我二次开发:

1)topscloud除了提供最基本的container-toolkit + k8s-device-plugin 之外 也提供 node-feature-discovery + gcu-feature-discovery二进制以及基本的编程示例以及使用手册, 由用户根据自己的实际使用场景进行DIY编程,达成内部最佳适用;

2)topscloud也提供go-zxlib api 库,用户可以基于这些API结合自有的k8s plugin manager 进行二次开发从而满足本身原有的使用案例的支持;

方案1结果如下(方案2类似)

GCU标签信息查看:

# kubectl get pod -A
NAMESPACE     NAME                                       \
                              READY   STATUS    RESTARTS      AGE
..............................
kube-system   etcd-sse-lg-112-32                         \
                              1/1     Running   2 (58d ago)   64d
kube-system   gcu-feature-discovery-cnm4h                \
                              1/1     Running   0             19s
kube-system   kube-apiserver-sse-lg-112-32               \
                              1/1     Running   2 (58d ago)   64d
kube-system   kube-controller-manager-sse-lg-112-32      \
                              1/1     Running   2 (58d ago)   64d
kube-system   kube-proxy-j2gbj                           \
                              1/1     Running   2 (58d ago)   64d
kube-system   kube-scheduler-sse-lg-112-32               \
                              1/1     Running   2 (58d ago)   63d
kube-system   nfd-fblrn                                  \
                              2/2     Running   0             7m13s
..........................

# kubectl get nodes -o yaml
.................
    creationTimestamp: "2024-03-13T10:16:16Z"
    labels:
      beta.kubernetes.io/arch: amd64
      beta.kubernetes.io/os: linux
      enflame.com/gcu.count: "8"
      enflame.com/gcu.driverVer: 1.0.1.2
      enflame.com/gcu.family: AAAA
      enflame.com/gcu.machine: NF5468M5
      enflame.com/gcu.memory: "32768"
      enflame.com/gcu.model: TXTX
      enflame.com/gcu.product: AAAA
      enflame.com/gfd.latestLabeledTimestamp: 2024-05-20-06-40-27
      enflame.com/gfd.timestamp: 2024-05-20-06-40-27
........................

标签使用编程示例

nodeSelector编程示例

spec:
  nodeSelector:
    enflame.com/gpu.product:  AAAA  # 假设我们想要的 GCU 产品型号

nodeAffinity编程示例

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "enflame.com/gpu.product"
            operator: "In"
            values:
            - "AAAA"  # 假设我们想要的 GCU 产品型号

11. GCU标签手工生成使用说明

11.1. 如何给节点打上标签

命令行添加Labels示例

kubectl label nodes k8s-node1 enflame.com/gcu.product=AAAA               # 为node加上标签
kubectl label --overwrite nodes k8s-node1 enflame.com/gcu.product=BBBB   # 改写node标签
kubectl label nodes --all enflame.com/gcu.product=AAAA                   # 为所有node加上标签
kubectl label nodes k8s-node1 enflame.com/gcu.product-                   # 为node去除标签

yaml文件添加Labels示例

kind: Node
apiVersion: v1
metadata:
  name: k8s-node1
  labels:
    enflame.com/gcu.product: AAAA

执行kubectl apply -f node.yaml即可进行标签的添加和覆盖

11.2. 为pod配置节点亲和性示例

将pod调度到具有特定标签的节点,有nodeSelector和nodeAffinity两种方式可以做到,这里使用节点亲和性(node affinity)作为示例。 这一过程需要在pod对象下的规约(spec)下添加亲和性描述,下面是一个描述pod对象的yaml文件,可以看到我们我们在pod的spec下增加了亲和性描述。

apiVersion: v1
kind: Pod
metadata:
name: pod-gcu-example
namespace: enflame
spec:
#  restartPolicy: OnFailure
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
  - matchExpressions:
  # 下面四行为匹配表达式的详细内容,支持
  # In,Not In,Exist,Not Exist,Gt,Lt六种操作符
  - key: enflame.com/gcu.product  # GFD生成的标签
operator: In
values:
  - AAAA
hostNetwork: true
containers:
  - name: pod-gcu-example
    image: ubuntu:18.04
    imagePullPolicy: IfNotPresent
    command: [ "sleep" ]
    args: [ "100000" ]
...............................

11.3. 应用示例

利用一个两节点单master集群进行实验:

假设AAAA的卡所在node 1,按照以上步骤打上标签enflame.com/gcu.product=AAAA

假设BBBB的卡所在node 2,按照以上步骤打上标签enflame.com/gcu.product=BBBB

当values为BBBB时,通过kubectl get po -A -o wide可以看到,pod准确落在node2。

当values为AAAA时,通过kubectl get po -A -o wide可以看到,pod准确落在node1。

12. 常见问题

1)如何获取更多的文档?

可以联系客户支持相关部门获取。