SPDX-License-Identifier: Apache-2.0
Copyright (c) 2019-2020 Intel Corporation
Dedicated CPU core for workload support in Smart Edge Open
Overview
Multi-core, commercial, off-the-shelf platforms are typical in any cloud or cloud-native deployment. Running processes in parallel on multiple cores helps achieve a better density of processes per platform. On a multi-core platform, one challenge for applications and network functions that are latency and throughput dependent is deterministic compute. It is important to achieve deterministic compute that can allocate dedicated resources. Dedicated resource allocation avoids interference with other applications (noisy neighbor). When deploying on a cloud-native platform, applications are deployed as PODs. And providing required information to the container orchestrator on dedicated CPU cores is key. CPU manager allows provisioning of a POD to dedicated cores.
Smart Edge Open release 21.03 deprecated Intel CMK in favour of Kubernetes native CPU Management.
The following are typical usages of this feature.
- Consider an edge application that uses an AI library such as OpenVINO™ for inference. This library uses a special instruction set on the CPU to get a higher performance for the AI algorithm. To achieve a deterministic inference rate, the application thread executing the algorithm needs a dedicated CPU core so that there is no interference from other threads or other application pods (noisy neighbor).
What is Kubernetes Native CPU management?
- If the workload already uses a threading library (e.g., pthread) and uses set affinity like APIs, Kbernetes CPU Management may not be needed. For such workloads, to provide cores to use for deployment, Kubernetes ConfigMaps are the recommended methodology. ConfigMaps can be used to pass the CPU core mask to the application for use. However, Kubernetes CPU Management offers transparent and out of the box support for cpu management which does not need any additional configuration. The only issue is threading aware software can interfere with Kubernetes when Kubernetes is configured to use CPU Manager.
- The workload is a medium to long-lived process with interarrival times on the order of ones to tens of seconds or greater.
- After a workload has started executing, there is no need to dynamically update its CPU assignments.
- Kubernetes CPU management does not need to perform additional tuning to IRQ affinity, CFS settings, or process scheduling classes.
- The preferred mode of deploying additional infrastructure components is to run them in containers on top of Kubernetes.
Default kubelet configuration uses CFS quota to manage PODs execution times and enforce imposed CPU limits. For such a solution it is possible that individual PODs are moved between different CPU because of changing circumistances on Kubernetes node. When cetrains PODs end its lifespan or CPU throttling comes in place then a POD can be moved to another CPU.
Another, default for Smart Edge Open, solution supported by Kubernetes is CPU manager. CPU manager uses Linux CPUSET mechanism to schedule PODS to invividual CPUs. Kubernetes defines shared pool of CPUs which initially contains all the system CPUs without CPUs reverved for system and kubelet itself. CPU selection is configurable with kubelet options. Kubernetes uses shared CPU pool to schedule PODs with three QoS classes BestEffort
, Burstable
and Guaranteed
.
When POD is qualified as Guaranteed
QoS class then kubelet removes requested CPUs amount from shared pool and assigns the POD exclusively to the CPUs.
Details - CPU Manager support in Smart Edge Open
Setup
Deployment setup
- Kubernetes CPU Management needs CPU Manager Policy to be set to
static
which is a default option in Smart Edge Open. This can be examined ininventory/default/group_vars/all/10-open.yml
file. ```yamlCPU policy - possible values: none (disabled), static (default)
policy: “static” ```
- Amount of CPUs reserved for Kubernetes and operating system is defined in
inventory/default/group_vars/all/10-open.yml
file.# Reserved CPUs for K8s and OS daemons - list of reserved CPUs reserved_cpus: "0,1"
- Deploy the node with
deploy.py
.NOTE: for more details about deployment and defining inventory please refer to CEEK getting started page.
Edge Controller / Kubernetes control plane
No setup needed.
Edge Node / Kubernetes node
No setup needed.
CPU Manager QoS classes
Kubernetes CPU Manager defines three quality of service classes for PODs.
- Best effort
BestEffort
QoS class is assigned to PODs which do not define any memory and CPU limits and requests. PODs from this QoC class run in the shared pool - Burstable
Bustrable
QoS class is assigned to PODS which define memory or CPU limits and requests which do not match. PODs fromBustrable
QoS class run in the shared pool. - Guaranteed
Guaranteed
QoS class is assigned to PODs which define memory and CPU limits and requests and those two values are equal. The values set to CPU limits and request have to be integral, factional CPU specified caused the POD to be run on the shared pool.
POD definitions
POD defined without any constraints. This will ne assigned BestEffort
QoS class and will run on shared poll.
spec:
containers:
- name: nginx
image: nginx
POD defined with some constraints. This will be assigned Bustrable
QoS class and will run on shared poll.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "100Mi"
cpu: "1"
POD defined with constraints, limits are equal to requests and CPU is integral bigger than or equal to one. This will be assigned Guaranteed
QoS classs and will run exclusively on CPUs assigned by Kubernetes.
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"
POD defined with constraints even when limits are equal to request but CPU is specified as a fractional number will not get exclusive CPUs but will be run on the shared pool. Still, QoS class for such a pod is Guaranteed
.
Examples
Example POD using CPU Manager feature.
apiVersion: v1
kind: Pod
metadata:
labels:
app: test-pod
name: test-pod
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: "IfNotPresent"
resources:
limits:
cpu: 1
memory: "200Mi"
requests:
cpu: 1
memory: "200Mi"
restartPolicy: Never
Scheduled POD is assigned Guaranteed
quality of service class, this can be examined by issuing kubectl describe pod/test-pod
.
Part of sample ouput is:
QoS Class: Guaranteed
Invidual processes/threads processor affinity can be checked on the node where the pod was scheduled with taskset
command.
Process started by a container with Guaranteed
POD QoS class has set CPU affinity according to the POD definition. It runs exclusively on CPUs removed from shared pool. All processes spawned from POD assigned to Guaranteed
QoS class are scheduled to run on the same exclusive CPU. Processes from Burstable
and BestEffort
QoS classes PODs are scheduled to run on shared pool CPUs. This can be examined with example nginx container.
[root@vm ~]# for p in `top -n 1 -b|grep nginx|gawk '{print $1}'`; do taskset -c -p $p; done
pid 5194's current affinity list: 0,1,3-7
pid 5294's current affinity list: 0,1,3-7
pid 7187's current affinity list: 0,1,3-7
pid 7232's current affinity list: 0,1,3-7
pid 17715's current affinity list: 2
pid 17757's current affinity list: 2