Chapitre 4. Utilisation du gestionnaire de CPU et du gestionnaire de topologie
Le gestionnaire de CPU gère des groupes de CPU et limite les charges de travail à des CPU spécifiques.
CPU Manager est utile pour les charges de travail qui présentent certaines de ces caractéristiques :
- Exiger le plus de temps possible de l'unité centrale.
- Sont sensibles aux défaillances de la mémoire cache du processeur.
- Sont des applications réseau à faible latence.
- Coordonnez-vous avec d'autres processus et profitez du partage de la mémoire cache d'un seul processeur.
Le gestionnaire de topologie recueille des indices auprès du gestionnaire de CPU, du gestionnaire de périphériques et d'autres fournisseurs d'indices afin d'aligner les ressources de pods, telles que les CPU, les VF SR-IOV et d'autres ressources de périphériques, pour toutes les classes de qualité de service (QoS) sur le même nœud d'accès à la mémoire non uniforme (NUMA).
Le gestionnaire de topologie utilise les informations topologiques provenant des indices collectés pour décider si un module peut être accepté ou rejeté sur un nœud, en fonction de la politique configurée du gestionnaire de topologie et des ressources de module demandées.
Topology Manager est utile pour les charges de travail qui utilisent des accélérateurs matériels pour prendre en charge l'exécution critique en termes de latence et le calcul parallèle à haut débit.
Pour utiliser le gestionnaire de topologie, vous devez configurer le gestionnaire de CPU avec la politique static
.
4.1. Configuration du gestionnaire de CPU
Procédure
Facultatif : Étiqueter un nœud :
# oc label node perf-node.example.com cpumanager=true
Modifiez le site
MachineConfigPool
des nœuds pour lesquels le gestionnaire de CPU doit être activé. Dans cet exemple, tous les travailleurs ont activé le gestionnaire de CPU :# oc edit machineconfigpool worker
Ajouter une étiquette au pool de configuration de la machine de travail :
metadata: creationTimestamp: 2020-xx-xxx generation: 3 labels: custom-kubelet: cpumanager-enabled
Créez une ressource personnalisée (CR)
KubeletConfig
,cpumanager-kubeletconfig.yaml
. Référez-vous à l'étiquette créée à l'étape précédente pour que les nœuds corrects soient mis à jour avec la nouvelle configuration du kubelet. Voir la sectionmachineConfigPoolSelector
:apiVersion: machineconfiguration.openshift.io/v1 kind: KubeletConfig metadata: name: cpumanager-enabled spec: machineConfigPoolSelector: matchLabels: custom-kubelet: cpumanager-enabled kubeletConfig: cpuManagerPolicy: static 1 cpuManagerReconcilePeriod: 5s 2
- 1
- Spécifier une politique :
-
none
. Cette politique active explicitement le schéma d'affinité CPU par défaut existant, ne fournissant aucune affinité au-delà de ce que le planificateur fait automatiquement. Il s'agit de la stratégie par défaut. -
static
. Cette politique autorise les conteneurs dans les pods garantis avec des demandes de CPU entières. Elle limite également l'accès aux CPU exclusifs sur le nœud. Sistatic
, vous devez utiliser une minuscules
.
-
- 2
- Facultatif. Indiquez la fréquence de rapprochement du gestionnaire de CPU. La valeur par défaut est
5s
.
Créer la configuration dynamique du kubelet :
# oc create -f cpumanager-kubeletconfig.yaml
Cela ajoute la fonction CPU Manager à la configuration du kubelet et, si nécessaire, le Machine Config Operator (MCO) redémarre le nœud. Pour activer le gestionnaire de CPU, un redémarrage n'est pas nécessaire.
Vérifier la configuration du kubelet fusionné :
# oc get machineconfig 99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet -o json | grep ownerReference -A7
Exemple de sortie
"ownerReferences": [ { "apiVersion": "machineconfiguration.openshift.io/v1", "kind": "KubeletConfig", "name": "cpumanager-enabled", "uid": "7ed5616d-6b72-11e9-aae1-021e1ce18878" } ]
Consultez le travailleur pour obtenir la mise à jour de
kubelet.conf
:# oc debug node/perf-node.example.com sh-4.2# cat /host/etc/kubernetes/kubelet.conf | grep cpuManager
Exemple de sortie
cpuManagerPolicy: static 1 cpuManagerReconcilePeriod: 5s 2
Créer un pod qui demande un ou plusieurs cœurs. Les limites et les demandes doivent avoir une valeur CPU égale à un entier. Il s'agit du nombre de cœurs qui seront dédiés à ce module :
# cat cpumanager-pod.yaml
Exemple de sortie
apiVersion: v1 kind: Pod metadata: generateName: cpumanager- spec: containers: - name: cpumanager image: gcr.io/google_containers/pause-amd64:3.0 resources: requests: cpu: 1 memory: "1G" limits: cpu: 1 memory: "1G" nodeSelector: cpumanager: "true"
Créer la capsule :
# oc create -f cpumanager-pod.yaml
Vérifiez que le pod est planifié sur le nœud que vous avez étiqueté :
# oc describe pod cpumanager
Exemple de sortie
Name: cpumanager-6cqz7 Namespace: default Priority: 0 PriorityClassName: <none> Node: perf-node.example.com/xxx.xx.xx.xxx ... Limits: cpu: 1 memory: 1G Requests: cpu: 1 memory: 1G ... QoS Class: Guaranteed Node-Selectors: cpumanager=true
Vérifiez que l'adresse
cgroups
est correctement configurée. Obtenir l'ID du processus (PID) du processuspause
:# ├─init.scope │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17 └─kubepods.slice ├─kubepods-pod69c01f8e_6b74_11e9_ac0f_0a2b62178a22.slice │ ├─crio-b5437308f1a574c542bdf08563b865c0345c8f8c0b0a655612c.scope │ └─32706 /pause
Les pods du niveau de qualité de service (QoS)
Guaranteed
sont placés à l'intérieur du sitekubepods.slice
. Les pods des autres niveaux de QoS se retrouvent dans les enfantscgroups
dekubepods
:# cd /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-pod69c01f8e_6b74_11e9_ac0f_0a2b62178a22.slice/crio-b5437308f1ad1a7db0574c542bdf08563b865c0345c86e9585f8c0b0a655612c.scope # for i in `ls cpuset.cpus tasks` ; do echo -n "$i "; cat $i ; done
Exemple de sortie
cpuset.cpus 1 tasks 32706
Vérifiez la liste des unités centrales autorisées pour la tâche :
# grep ^Cpus_allowed_list /proc/32706/status
Exemple de sortie
Cpus_allowed_list: 1
Vérifiez qu'un autre pod (dans ce cas, le pod du niveau de qualité de service
burstable
) sur le système ne peut pas fonctionner sur le cœur alloué au podGuaranteed
:# cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podc494a073_6b77_11e9_98c0_06bba5c387ea.slice/crio-c56982f57b75a2420947f0afc6cafe7534c5734efc34157525fa9abbf99e3849.scope/cpuset.cpus 0 # oc describe node perf-node.example.com
Exemple de sortie
... Capacity: attachable-volumes-aws-ebs: 39 cpu: 2 ephemeral-storage: 124768236Ki hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 8162900Ki pods: 250 Allocatable: attachable-volumes-aws-ebs: 39 cpu: 1500m ephemeral-storage: 124768236Ki hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 7548500Ki pods: 250 ------- ---- ------------ ---------- --------------- ------------- --- default cpumanager-6cqz7 1 (66%) 1 (66%) 1G (12%) 1G (12%) 29m Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1440m (96%) 1 (66%)
Cette VM dispose de deux cœurs de processeur. Le paramètre
system-reserved
réserve 500 millicores, ce qui signifie que la moitié d'un cœur est soustraite de la capacité totale du nœud pour obtenir la quantitéNode Allocatable
. Vous pouvez voir queAllocatable CPU
est de 1500 millicores. Cela signifie que vous pouvez exécuter l'un des pods du gestionnaire de CPU, puisque chacun d'entre eux prendra un cœur entier. Un cœur entier est équivalent à 1000 millicores. Si vous essayez de planifier un deuxième module, le système acceptera le module, mais il ne sera jamais planifié :NAME READY STATUS RESTARTS AGE cpumanager-6cqz7 1/1 Running 0 33m cpumanager-7qc2t 0/1 Pending 0 11s