鲲鹏云原生项目集合,包含多个针对鲲鹏处理器优化的云原生组件。
表 1 版本说明
|
||
硬件要求如表1所示。
表 1 硬件要求
软件要求如表2所示。
表 2 软件要求
编译Kunpeng TAP源代码并生成插件可执行文件。
-
获取Kunpeng TAP源代码,在标签中获取最新发布的release-0.2版本。
git clone --branch release-0.2 https://gitee.com/kunpeng_compute/topo-affinity-plugin.git -
进入“topo-affinity-plugin“目录,并执行构建插件的脚本。
cd /path/to/topo-affinity-plugin go mod tidy make build其中“/path/to/topo-affinity-plugin“为插件源码的实际路径,请根据实际情况修改。
构建完成后,请确认在“bin“目录下生成kunpeng-tap二进制文件。
- Go 1.23.6或更高版本
- Linux环境(推荐openEuler 22.03)
- 支持MPAM的硬件平台(推荐鲲鹏处理器)
make mpam-docker
如果K8s集群使用的是containerd作为容器运行时,需要把镜像手动导入到containerd的镜像仓库。
docker save k8s-mpam-controller:0.1.0 -o k8s-mpam-controller.tar
ctr -n k8s.io images import k8s-mpam-controller.tar
在目标计算节点部署Kunpeng TAP,并且验证插件的运行状态。
Kunpeng TAP的运行依赖于K8s集群,当前支持使用Dockershim通信方式的Docker和Containerd。在部署该插件之前,需确保K8s集群已完成正确的网络配置,并且能够顺利部署和运行容器实例。
-
在目标计算节点导入Kunpeng TAP的可执行文件。
-
启动方式一:systemd启动。可直接进入源代码目录下,通过make命令安装和启动。
-
进入源代码目录。
cd /path/to/topology-affinity-plugin其中“/path/to/topology-affinity-plugin“为Kunpeng TAP源码的实际路径,请根据实际情况修改。
-
安装插件,默认以Docker模式启动。
make install-service -
指定运行时为Docker,运行如下安装命令。
make install-service-docker如果需要修改启动参数,则在源代码目录下的“hack/kunpeng-tap.service.docker“文件的“ExecStart=“下进行修改:
[Unit] Description=Kunpeng Topology-Affinity Plugin Service After=network.target [Service] ExecStart=/usr/local/bin/kunpeng-tap --runtime-proxy-endpoint="/var/run/kunpeng/tap-runtime-proxy.sock" \ --container-runtime-service-endpoint="/var/run/docker.sock" --container-runtime-mode="Docker" \ --resource-policy="numa-aware" Restart=always RestartSec=5 [Install] WantedBy=multi-user.target说明: 指定运行时为Containerd,运行如下安装命令,参数配置可在源代码目录下的“hack/kunpeng-tap.service.containerd“文件中修改。
make install-service-containerd -
安装完毕后,借助如下命令启动插件,并且自动查看启动后的服务状态。
make start-service -
查看日志信息。
journalctl -u kunpeng-tap
**启动方式二:**直接启动。
-
Docker运行时下的启动命令,示例如下:
kunpeng-tap --runtime-proxy-endpoint="/var/run/kunpeng/tap-runtime-proxy.sock" \ --container-runtime-service-endpoint="/var/run/docker.sock" --container-runtime-mode="Docker" \ --resource-policy="numa-aware" -
Containerd运行时下的启动命令,示例如下:
kunpeng-tap --runtime-proxy-endpoint="/var/run/kunpeng/tap-runtime-proxy.sock" \ --container-runtime-service-endpoint="/var/run/containerd/containerd.sock" --container-runtime-mode="Containerd" \ --resource-policy="numa-aware"
说明: 用户可根据需求修改相关参数后启动。参数说明见表1。
表 1 参数说明
-
-
在计算节点配置Kubelet参数。
为了让Kunpeng TAP成功代理Kubelet的请求,需要在Kubelet的命令行配置中增加如下参数。
-
在Docker场景下,在Kubelet启动参数中添加或修改对应参数项如下所示。
--docker-endpoint=unix:///var/run/kunpeng/tap-runtime-proxy.sock以使用kubeadm安装集群为例,可以在“/var/lib/kubelet/kubeadm-flags.env“添加参数。
KUBELET_KUBEADM_ARGS="--network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.6 --docker-endpoint=unix:///var/run/kunpeng/tap-runtime-proxy.sock"注意,修改Kubelet参数后,须运行如下命令重新启动Kubelet。
systemctl daemon-reload systemctl restart kubelet -
在Containerd场景下,修改Kubelet的启动参数。
--container-runtime=remote --container-runtime-endpoint=unix:///var/run/kunpeng/tap-runtime-proxy.sock此时,“/var/lib/kubelet/kubeadm-flags.env“的参数示例可能是:
KUBELET_KUBEADM_ARGS="--network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.6 --container-runtime=remote --container-runtime-endpoint=unix:///var/run/kunpeng/tap-runtime-proxy.sock"注意,修改Kubelet参数后,须运行如下命令重新启动Kubelet。
systemctl daemon-reload systemctl restart kubelet
-
Kunpeng TAP允许在部署Pod时指定CPU资源需求,系统将自动按NUMA亲和性分配资源。通过编写YAML文件并指定节点选择器,可以将Pod部署到特定节点上。成功部署插件后,只需在部署其他Pod时指定CPU资源的request和limit值,系统将自动按照NUMA亲和性原则进行资源分配。
以下为部署一个单容器Pod的YAML文件示例,供用户参考。该Pod请求的CPU资源最小值为4核,最大值为8核,内存固定为4Gi,容器使用busybox作为镜像。
-
创建YAML文件,例如example.yaml,并在YAML文件中写入以下配置。
apiVersion: v1 kind: Pod metadata: name: tap-test annotations: spec: containers: - name: tap-example image: busybox:latest imagePullPolicy: IfNotPresent command: ["/bin/sh"] args: ["-c", "while true; do echo `date`; sleep 5; done"] resources: requests: cpu: "4" memory: "4Gi" limits: cpu: "8" memory: "4Gi" -
以指定Pod在compute01节点上运行为例,需要在YAML文件中的spec部分加入以下内容。
说明: 在多个工作节点的K8s集群中,Pod可能会被调度到不同节点的NUMA内。如果希望Pod在指定的节点上运行,只需在YAML文件的spec部分加入nodeSelector字段,并指定kubernetes.io/hostname为目标节点的名称。
nodeSelector: kubernetes.io/hostname: compute01 -
在管理节点应用YAML文件,完成Pod部署。
kubectl apply -f example.yaml -
判断Kunpeng TAP是否生效。
-
以Docker运行时为例,进入步骤2中nodeSelector所指定的集群节点_compute01_后,通过docker命令查询容器的CpusetCpus参数,判断容器是否与NUMA成功亲和。
-
通过docker ps查询集群节点运行的容器任务,在NAMES列中找到步骤一中“spec.containers.name“指定的_nri-1_容器。
# docker ps | grep nri-1 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -
依据_CONTAINER ID_查询目标容器的部署参数_CpusetCpus_,该参数表示容器的可调度CPU范围。
# docker inspect bf32de0d09fe | grep "CpusetCpus" "CpusetCpus": "0-23",如果启用了内存绑定功能,可以通过如下命令查看,注意其取值表示节点的编号。
# docker inspect bf32de0d09fe | grep "CpusetMems" "CpusetMems": "0",说明: 在不同的机器上查看时,绑定的NUMA节点不固定,_CpusetCpus_数字可能不一致。
Containerd运行时可以运行如下命令查看容器的可调度CPU范围。
# crictl inspect bf32de0d09fe | grep "cpuset_cpus" "cpuset_cpus": "0-23",如果NUMA节点亲和失败,则可能无法查找到cpuset_cpus输出。
-
查询系统的NUMA信息,与上述的容器可调度CPU范围进行对比,一致则表示亲和于对应NUMA节点。
# lscpu ... NUMA node0 CPU(s): 0-23 NUMA node1 CPU(s): 24-47 NUMA node2 CPU(s): 48-71 NUMA node3 CPU(s): 72-95 ...“node0“表示编号为“0“的NUMA节点,“0-23“表示NUMA节点内的CPU编号。
-
-
此外,对于系统中GPU的NUMA分布,可以运行如下命令查看,其中“0200“为网卡设备号。
lspci -vvv -d :0200 | grep NUMA回显如下所示:
NUMA node: 0 NUMA node: 0 NUMA node: 0 NUMA node: 0 NUMA node: 0 NUMA node: 2 NUMA node: 2 NUMA node: 2 NUMA node: 2 NUMA node: 2
-
在部署插件之前要先确保MPAM的resctrl文件系统已经挂载,在worker节点使用如下命令可以挂载。
mount -t resctrl resctrl /sys/fs/resctrl -
在master节点上执行如下命令部署插件。
cd config/k8s-mpam-controller-config/samples kubectl apply -f k8s-mpam-controller.yaml -
查看MPAM插件对应的Pod是否正常运行。
kubectl get pods正常运行可能的回显如下。
NAME READY STATUS RESTARTS AGE mpam-controller-daemonset-agent-bj2gv 1/1 Running 0 143m
当需要对Pod进行资源限制时,需要创建MPAM资源组。
-
进入“samples“目录,修改MPAM资源组的配置文件(.yaml格式),以example-config.yaml为例。
在example-config.yaml文件中,Node资源组包括如表1所示3种不同级别的配置,用户可以通过ConfigMap为Node节点或一组节点创建配置。创建配置后,MPAM插件将管理Kubernetes集群中的ConfigMap,并在添加或更新ConfigMap后将配置自动应用到相应的节点。
表 1 配置类型及其说明
-
打开文件。
cd samples vi example-config.yaml -
按“i“进入编辑模式,在文件中修改name字段指定为表1中的实际配置名称,将mpam字段下添加对应的资源组信息。
apiVersion: v1 kind: ConfigMap metadata: name: ${CONFIG_NAME} namespace: rc-config data: rc.conf: | mpam: group1: llc: <schemata> mb: <schemata> group2: llc: <schemata> mb: <schemata> group3: llc: <schemata> mb: <schemata>说明:
- 最多可以设置32个资源组(根分组默认占一个资源组,根分组下最多实际只能创建出31个资源组),每条<schemata>必须要满足语法规则。
- 如果某个资源组中没有对某一项进行配置或者已配置的配置项不满足语法规则,该资源组将使用该配置项的默认配置。L3 cache的默认配置为**"L3:0=fffffff;1=fffffff;2=fffffff;3=fffffff";带宽的默认配置为"MB:0=100;1=100;2=100;3=100"**
-
按“Esc“键退出编辑模式,输入**:wq!**,按“Enter“键保存并退出文件。
-
-
在“samples“目录下,应用example-config.yaml文件以创建ConfigMap。
kubectl apply -f example-config.yaml -
在Node节点上,进入“/sys/fs/resctrl“目录,查看资源组是否已创建,以及对应的资源组配置是否和example-config.yaml中的一致。
cd /sys/fs/resctrl ls说明: 例如,可以通过以下命令查看资源组group1的配置。
cat group1/schemata
当需要将某个Pod加入到某个资源组中时,需要在创建Pod时指定资源组。
-
修改Pod的配置文件(.yaml格式),以example-pod.yaml为例。
-
进入“samples“目录,打开example-pod.yaml文件。
cd samples vi example-pod.yaml -
按“i“进入编辑模式,在配置文件中分别添加如下信息。
labels: rcgroup: group2nodeSelector: MPAM: enabled说明:
- 在labels字段中通过rcgroup字段指定对应的资源组,例如将Pod加到group2中。
- 在nodeSelector字段中增加MPAM:enabled,用于调度器将该Pod调度到支持MPAM特性的节点上去。
修改后的example-pod.yaml文件如下所示。
apiVersion: v1 kind: Pod metadata: name: nginx labels: rcgroup: group2 spec: containers: - name: nginx image: nginx:1.16.1 ports: - containerPort: 80 hostPort: 8088 nodeSelector: MPAM: enabled -
按“Esc“键退出编辑模式,输入**:wq!**,按“Enter“键保存并退出文件。
-
-
创建Pod。
kubectl apply -f example-pod.yaml -
在Node节点上,进入“/sys/fs/resctrl“目录,再进入Pod所属的资源组中(例如Pod属于资源组group1),可以在资源组中查看对应的配置以及监控数据,还可以查看当前资源组下被限制应用的pid。
cd /sys/fs/resctrl/group1-
通过以下命令查看资源组的配置。
cat schemata -
通过以下命令查看该资源组下的pid。
cat tasks -
通过以下命令查看资源组下的监控数据。
grep . mon_data/*
-
当需要动态调整某些离线业务的资源使用量时可以使用动态MPAM隔离功能。
插件提供了默认配置,如果不配置configMap同样可以使用动态MPAM隔离功能。MPAM动态隔离参数通过json文件配置,参数含义请参见表2。如果需要手动更改配置参考下面内容进行配置。
{
"mpamConfig":{
"adjustInterval": 5000,
"perfDuration": 3000,
"l3Percent": {
"low": 20,
"high": 50
},
"memBandPercent": {
"low": 10,
"high": 50
},
"cacheMiss": {
"minMiss": 10,
"maxMiss": 50
}
}
}
表 2 MPAM动态隔离参数说明
json文件通过configMap的形式进行配置,在k8s-mpam-controller.yaml文件中配置,完整的yaml文件如下。
apiVersion: v1
kind: ServiceAccount
metadata:
name: mpam-controller-agent
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: mpam-controller-agent
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: mpam-controller-agent
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: mpam-controller-agent
subjects:
- kind: ServiceAccount
name: mpam-controller-agent
namespace: default
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mpam-config
data:
config.json: |
{
"mpamConfig":{
"adjustInterval": 10000,
"perfDuration": 3000,
"l3Percent": {
"low": 20,
"high": 50
},
"memBandPercent": {
"low": 10,
"high": 50
},
"cacheMiss": {
"minMiss": 10,
"maxMiss": 30
}
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: mpam-controller-daemonset-agent
spec:
selector:
matchLabels:
app: k8s-mpam-controller-agent
template:
metadata:
labels:
app: k8s-mpam-controller-agent
spec:
serviceAccountName: mpam-controller-agent
hostPID: true
hostIPC: true
containers:
- name: k8s-mpam-controller-agent
image: k8s-mpam-controller:0.1
securityContext:
privileged: true
command: ["/usr/bin/agent"]
args: ["-direct"]
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
volumeMounts:
- name: resctrl
mountPath: /sys/fs/resctrl/
- name: hostname
mountPath: /etc/hostname
- name: sysfs
mountPath: /sys/fs/cgroup/
- name: config-volume
mountPath: /var/lib/mpam-config
volumes:
- name: resctrl
hostPath:
path: /sys/fs/resctrl/
- name: hostname
hostPath:
path: /etc/hostname
- name: sysfs
hostPath:
path: /sys/fs/cgroup/
- name: config-volume
configMap:
name: mpam-config
items:
- key: config.json
path: config.json
使用动态MPAM隔离功能后插件会在“/sys/fs/resctrl“目录下创建mpam-controller_dynamic目录,如下图所示。
-
在Pod的yaml文件中添加注解kunpeng.com/offline: "true",标记该Pod为离线业务,方便插件对其进行限制,示例bw-mem.yaml文件如下。
apiVersion: v1 kind: Pod metadata: name: bw-mem annotations: kunpeng.com/offline: "true" spec: containers: - name: bw-mem image: bw-mem:latest imagePullPolicy: IfNotPresent command: [ "/bin/sh", "-c", "--" ] args: [ "while true; do sleep 300000; done;" ] securityContext: capabilities: add: ["ALL"] resources: requests: cpu: "9.6" limits: cpu: "9.6" -
部署要进行限制的离线业务。
kubectl apply -f bw-mem.yaml部署成功后离线业务的pid会被加入到mpam-controller_dynamic控制组中的tasks。
-
通过以下命令查看被限制的离线业务的pid。
cd /sys/fs/resctrl/mpam-controller_dynamic cat tasks
欢迎提交Issue和Pull Request来改进项目。请确保:
- 代码符合项目规范。
- 包含适当的测试。
- 更新相关文档。
本项目不含任何明示或暗示的担保,包括但不限于适销性、特定用途适用性及不侵权保证;在任何情况下,版权所有者或贡献者均不对因使用本软件而产生的任何直接、间接、特殊、附带或后果性损害负责。使用即视为同意上述条款。
本项目采用Apache License 2.0许可证。详见LICENSE文件。
