במאמר הזה מוסבר איך להגדיר אשכולות ומכונות וירטואליות כדי לתמוך בעומסי עבודה עם ביצועים גבוהים וזמן אחזור נמוך, באמצעות יעילות החישוב של גישה לזיכרון לא אחיד (NUMA). יש הוראות להתאמת הגדרות Kubernetes לצמתים באשכול. במסמך הזה יש גם הוראות להגדרת מכונות וירטואליות (VM) עם זיקה ל-NUMA, כדי שהן יתוזמנו בצמתי NUMA וינצלו אותם.
במכונה וירטואלית עם מודעות ל-NUMA, כל התקשורת בתוך המכונה הווירטואלית היא מקומית לצומת ה-NUMA. המכונה הווירטואלית עם מודעות ל-NUMA נמנעת מעסקאות נתונים אל משאבים מרוחקים וממשאבים מרוחקים, שיכולות לפגוע בביצועים של המכונה הווירטואלית.
הגדרת צמתים לשימוש ב-NUMA
בקטעים הבאים מוסבר איך להגדיר את רכיבי Kubernetes הקריטיים כדי לכוונן את הצומת ולוודא שאפשר לתזמן קונטיינרים שמודעים ל-NUMA. צמתי ה-NUMA האלה מכווננים כדי לבצע אופטימיזציה של הביצועים של ה-CPU והזיכרון. צריך לפעול לפי ההוראות לכל צומת שרוצים להריץ בו מכונות וירטואליות שמודעות ל-NUMA.
עדכון ההגדרה של kubelet
כחלק מהגדרת הצומת לתמיכה בהצמדה של צומת NUMA, צריך לבצע את השינויים הבאים בהגדרת kubelet:
- הפעלת CPU Manager עם מדיניות
static - הפעלת מנהל הזיכרון באמצעות מדיניות
Static - הפעלת הכלי לניהול טופולוגיה עם טופולוגיה
restricted
כדי להגדיר את kubelet בצומת העובד:
מאתרים את קובץ
kubeletבצומת העובד ופותחים אותו לעריכה:edit /etc/default/kubeletאם הקובץ
kubeletלא מופיע, יוצרים אותו באמצעות הפקודה הבאה:echo "KUBELET_EXTRA_ARGS=\"\"" >> /etc/default/kubeletהפקודה הזו יוצרת את הקובץ
kubeletעם קטעKUBELET_EXTRA_ARGS=""ריק.כדי להפעיל את CPU Manager עם מדיניות
static, מוסיפים את הדגל--cpu-manager-policy=staticלקטעKUBELET_EXTRA_ARGS=""בקובץ:KUBELET_EXTRA_ARGS="--cpu-manager-policy=static"
כדי להפעיל את הכלי לניהול זיכרון באמצעות מדיניות
Static, מוסיפים את הדגל--memory-manager-policy=StaticלקטעKUBELET_EXTRA_ARGS=""בקובץ:KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static"
כדי להפעיל את Topology Manager באמצעות מדיניות
restricted, מוסיפים את הדגל--topology-manager-policy=restrictedלקטעKUBELET_EXTRA_ARGS=""בקובץ:KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted"
בודקים את כמות הזיכרון הנוכחית ששמורה ל-Google Distributed Cloud:
cat /var/lib/kubelet/kubeadm-flags.envהפלט אמור להיראות כך:
KUBELET_KUBEADM_ARGS="--anonymous-auth=false --authentication-token-webhook=true --authorization-mode=Webhook --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --feature-gates=SeccompDefault=true --kube-reserved=cpu=100m,memory=3470Mi --max-pods=110 --node-ip=192.168.1.190 --node-labels=baremetal.cluster.gke.io/k8s-ip=192.168.1.190,baremetal.cluster.gke.io/namespace=cluster-user001,baremetal.cluster.gke.io/node-pool=node-pool-1,cloud.google.com/gke-nodepool=node-pool-1 --pod-infra-container-image=gcr.io/anthos-baremetal-release/pause-amd64:3.1-gke.5 --provider-id=baremetal://192.168.1.190 --read-only-port=10255 --rotate-server-certificates=true --seccomp-default=true"
ההגדרה
--kube-reserved=cpu=100m,memory=3470Miמציינת ש-Google Distributed Cloud שמר 3,470 מביבייט של זיכרון בצומת.מגדירים את הדגל
--reserved-memoryבקטעKUBELET_EXTRA_ARGSשל הקובץkubeletל-100 מביבייט יותר מהזיכרון השמור הנוכחי, כדי להתחשב בסף הפינוי. אם אין זיכרון שמור, אפשר לדלג על השלב הזה.לדוגמה, אם הזיכרון השמור הוא
3470Miכמו בדוגמה בשלב הקודם, שומרים3570Miזיכרון בקובץkubelet:KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted --reserved-memory=0:memory=3570Mi"
מסירים את קובצי המצב של ה-CPU והזיכרון מהספרייה
/var/lib:rm /var/lib/cpu_manager_state rm /var/lib/memory_manager_stateמפעילים מחדש את kubelet:
systemctl start kubelet
מידע נוסף על הגדרות המדיניות האלה זמין במסמכי Kubernetes הבאים:
הגדרת הצומת לשימוש ב-hugepages
אחרי שמפעילים את Memory Manager עם מדיניות Static, אפשר להוסיף hugepages כדי לשפר עוד יותר את הביצועים של עומסי העבודה של הקונטיינרים בצמתי ה-NUMA.
כמו שאפשר להבין מהשם, hugepages מאפשרות לכם לציין דפי זיכרון גדולים יותר מהגודל הרגיל של 4 קיביבייט (KiB). VM Runtime ב-GDC תומך בדפי ענק של 2 מביבייט (MiB) ו-1 גיביבייט (GiB). אפשר להגדיר hugepages לצומת בזמן הריצה או בזמן האתחול של מכונת הצומת. מומלץ להגדיר hugepages בכל צומת שרוצים להפעיל בו מכונות וירטואליות עם מודעות ל-NUMA.
כדי להגדיר את מספר דפי הזיכרון הגדולים בגודל מסוים בצומת NUMA בזמן הריצה, משתמשים בפקודה הבאה:
echo HUGEPAGE_QTY > \ /sys/devices/system/node/NUMA_NODE/hugepages/hugepages-HUGEPAGE_SIZEkB/nr_hugepagesמחליפים את מה שכתוב בשדות הבאים:
HUGEPAGE_QTY: מספר דפי הזיכרון הגדולים להקצאה בגודל שצוין.
NUMA_NODE: צומת ה-NUMA, כמוnode0, שאליו מקצים את דפי הזיכרון הגדולים.
HUGEPAGE_SIZE: גודל דפי הזיכרון הגדולים ב-kibibytes,2048(2 MiB) או1048576(1 GiB).
הגדרת מכונה וירטואלית לשימוש בצומת NUMA
אחרי שמכווננים את צמתי האשכול ל-NUMA, אפשר ליצור מכונות וירטואליות עם תמיכה ב-NUMA. מכונות וירטואליות עם מודעות ל-NUMA מתוזמנות בצמתי NUMA.
כדי ליצור מכונה וירטואלית עם מודעות ל-NUMA:
פועלים לפי ההוראות ליצירת מכונה וירטואלית ממניפסט.
כדי להגדיר את מכונת ה-VM כך שתהיה מודעת ל-NUMA, משתמשים בהגדרות הבאות של
compute:
spec.compute.guaranteed: מגדירים אתguaranteedל-true. בהגדרה הזו, ה-Podvirt-launcherמוגדר להצבה ב-Kubernetes Guaranteed Quality of Service (QoS) class.spec.compute.advancedCompute:-
dedicatedCPUPlacement: מגדירים אתdedicatedCPUPlacementל-true. ההגדרה הזו מצמידה מעבדים וירטואליים למעבדים הפיזיים של הצומת. -
hugePageSize: מגדירים אתhugePageSizeל-2Miאו ל-1Giכדי לציין את הגודל של דפי הזיכרון הגדולים שבהם ה-VM ישתמש: 2 מביבייט או 1 גיביבייט. numaGuestMappingPassthrough: כוללים מבנה ריק ({}) להגדרה הזו. ההגדרה הזו קובעת זיקה ל-NUMA, כך שהמכונה הווירטואלית מתוזמנת רק בצמתי NUMA.
-
בדוגמה הבאה של מניפסט VirtualMachine אפשר לראות איך יכולה להיראות הגדרה של מכונה וירטואלית עם מודעות ל-NUMA:
apiVersion: vm.cluster.gke.io/v1 kind: VirtualMachine metadata: name: vm1 spec: compute: cpu: vcpus: 2 guaranteed: true advancedCompute: dedicatedCPUPlacement: true hugePageSize: 2Mi numaGuestMappingPassthrough: {} memory: capacity: 256Mi interfaces: - name: eth0 networkName: pod-network default: true disks: - virtualMachineDiskName: disk-from-gcs boot: true readOnly: true