
Amikor először dolgozunk a Kubernetes-szel, általában megfeledkezünk a konténerek erőforrásainak beállításáról. Ezen a ponton elég, ha megbizonyosodunk arról, hogy a Docker-kép működik, és telepíthető a Kubernetes klaszterben.
Később azonban az alkalmazást produktív klaszterben kell telepíteni más alkalmazásokkal együtt. Ehhez erőforrásokat kell allokálnunk a konténer számára, és meg kell győződnünk arról, hogy elegendő erőforrás áll rendelkezésre az alkalmazás elindításához és működéséhez, anélkül, hogy problémák merülnének fel más futó alkalmazásokban.
A parancs Átírtam a konténerek erőforrásairól (CPU és MEM), a kérésekről és erőforrás-korlátokról szóló cikket. Megtudhatja, milyen előnyöket nyújtanak ezek a beállítások, és mi történik, ha nem állítják be őket.
Számítási erőforrások
Kétféle erőforrásunk van, a következő mértékegységekkel:
- Központi feldolgozóegység (CPU) — magok;
- Memória (MEM) — bájtok.
Az erőforrásokat minden konténerhez meg kell határozni. A következő YAML-fájlban a Pod erőforrása jelöli a kért és a maximális erőforrásokat:
- A Pod kért erőforrásai = az összes konténer kért erőforrásainak összegét;
- A Pod maximális erőforrásai = az összes konténer maximális erőforrásainak összegét.
apiVersion: v1
kind: Pod
metadata:
name: backend-pod-name
labels:
application: backend
spec:
containers:
- name: main-container
image: my-backend
tag: v1
ports:
- containerPort: 8080
resources:
requests:
cpu: 0.2 # KÉRT CPU: 200m core
memory: "1Gi" # KÉRT MEM: 1Gi
limits:
cpu: 1 # MAX CPU HASZNÁLAT: 1 core
memory: "1Gi" # MAX MEM HASZNÁLAT: 1Gi
- name: other-container
image: other-app
tag: v1
ports:
- containerPort: 8000
resources:
requests:
cpu: "200m" # KÉRT CPU: 200m core
memory: "0.5Gi" # KÉRT MEM: 0.5Gi
limits:
cpu: 1 # MAX CPU HASZNÁLAT: 1 core
memory: "1Gi" # MAX MEM HASZNÁLAT: 1GiA kért és maximális erőforrások példája
Mező resources.requested a Pod specifikációjából — az egyik elem, amelyet a megfelelő node keresésére használnak. Már most ütemezhető a Pod telepítése. Hogyan találják meg a megfelelő node-ot?
A Kubernetes több összetevőből áll, beleértve egy fő node-ot vagy mester node-ot (Kubernetes Control Plane). A mester node-on több folyamat fut: kube-apiserver, kube-controller-manager és kube-scheduler.
A kube-scheduler feladata a frissen létrehozott modulok vagy podok megtekintése, és azokhoz lehetőséget keresni, amelyek megfelelnek az összes modul által megfogalmazott kérésnek, beleértve a kért erőforrások mennyiségét is. A kube-scheduler által talált node-ok rangsorolódnak. A Pod a legmagasabb pontszámú node-on kerül ütemezésre.
Hova kerül a lila Pod?
A képen látható, hogy a kube-scheduler új lila Podot kell ütemeznie. A Kubernetes klaszter két csomópontot tartalmaz: A és B. Ahogy látható, a kube-scheduler nem tudja ütemezni a Podot az A csomópontra — a rendelkezésre álló (nem lekért) erőforrások nem felelnek meg a lila Pod igényeinek. Így a lila Pod által kért 1 GB memória nem fér el az A csomóponton, mivel a rendelkezésre álló memória mennyisége 0,5 GB. Viszont a B csomópontnak elegendő erőforrása van. Végül a kube-scheduler úgy dönt, hogy a lila Pod célállomása a B csomópont.
Most már tudjuk, hogy a lekért erőforrások hogyan befolyásolják a csomópont kiválasztását a Pod futtatásához. De hogyan hatnak a határérték erőforrások?
A határérték erőforrások az a küszöb, amelyet a CPU/MEM nem léphet át. Mindazonáltal a CPU erőforrás rugalmas, így a CPU határértéket elérő konténerek nem okoznak a Pod leállítását. Ehelyett CPU korlátozás lép életbe. Ha azonban a MEM használati határértékét elérik, a konténert OOM-Killer miatt leállítják, és újraindítják, ha ezt a RestartPolicy beállítás engedélyezi.
Lekért és határérték erőforrások részletesen
Az erőforrások kapcsolata a Docker és a Kubernetes között
A legjobb módja annak, hogy elmagyarázzuk, hogyan működnek a lekért és határérték erőforrások, az a kapcsolatok bemutatása a Kubernetes és a Docker között. A fenti ábrán megnézheti, hogyan kapcsolódnak a Kubernetes mezők és a Docker indítóflagjei.
Memória: lekérés és korlátozás
containers:
...
resources:
requests:
memory: "0.5Gi"
limits:
memory: "1Gi"
Ahogy fent említettem, a memória byte-ban van mérve. Alapján , megadhatjuk a memóriát számként. Általában egész szám, például 2678 — ami 2678 byte-ot jelent. Szuffixumokat is használhatunk, G és Gi, fontos tudni, hogy ezek nem egyenlőek. Az első tizedes, a második pedig kettes alapú. Például, a k8s dokumentációjában említettek: 128974848, 129e6, 129M, 123Mi — ezek szinte egyenértékűek.
A Kubernetes paramétere limits.memory megfelel a flagnek --memory a Dockerben. A request.memory Docker esetében ez a nyíl hiányzik, mivel a Docker nem használja ezt a mezőt. Kérdezheti, hogy erre tényleg szükség van? Igen, szükség van. Ahogy már mondtam, a mező fontos a Kubernetes számára. Az információk alapján a kube-scheduler eldönti, hogy melyik csomóra ütemezze a Podot.
Mi történik, ha a lekéréshez nem elegendő memóriát állítunk be?
Ha a konténer elérte a kért memória határait, a Podot a memóriahiány miatt leállított Podok csoportjába helyezik.
Mi fog történni, ha túl alacsony memóriakorlátot állítunk be?
Ha a konténer túllépi a memóriakorlátot, az OOM-Killed miatt leáll. Újraindításra kerül, ha lehetséges a RestartPolicy alapján, amelynek alapértelmezett értéke — Mindig.
Mi történik, ha nem adunk meg kért memóriát?
A Kubernetes a korlátozott értéket fogja alapértelmezettként beállítani.
Mi történhet, ha nem adjuk meg a memóriakorlátot?
A konténernek nincsenek korlátai, annyi memóriát használhat, amennyit csak akar. Ha azonban elkezdi használni a node-on elérhető összes memóriát, az OOM leállítja. Ezután a kontény újraindul, ha lehetséges a RestartPolicy alapján.
Mi lesz, ha nem adunk meg memóriakorlátokat?
Ez a legrosszabb forgatókönyv: a scheduler nem tudja, mennyi erőforrásra van szüksége a konténernek, és ez súlyos problémákat okozhat a node-on. Ebben az esetben jó lenne, ha lennének alapértelmezett korlátok a névtérben (LimitRange beállításával). Nincsenek alapértelmezett korlátok - a Podnak nincsenek korlátai, annyit használhat, amennyit csak akar.
Ha a kért memória nagyobb, mint amit a node kínál, a Pod nem lesz ütemezve. Fontos megjegyezni, hogy Requests.memory — nem minimális érték. Ez a konténer folyamatos működéséhez elegendő memória mennyiségét írja le.
Általában ajánlott ugyanazt az értéket beállítani a következőhöz: request.memory és limit.memory. Ezzel a Kubernetes nem ütemez egy Podot egy olyan node-ra, ahol elegendő memória van a Pod futtatásához, de nem elegendő az működéséhez. Ne feledje: a Pod ütemezésénél a Kubernetes csak requests.memory, és limits.memory az nem számít.
CPU: kérés és korlátozás
containers:
...
resources:
requests:
cpu: 1
limits:
cpu: "1200m"
A CPU-val minden kicsit bonyolultabb. Visszatérve a Kubernetes és Docker közötti kapcsolatra, észrevehetjük, hogy request.cpu megfelel --cpu-shares, míg limit.cpu megfelel a flagnek cpus a Dockerben.
A Kubernetes által kért CPU-t 1024-gyel szorozzák — a CPU ciklusainak arányával. Ha egy teljes magot szeretne kérni, akkor hozzá kell adnia cpu: 1, ahogyan az fent látható.
A teljes magra vonatkozó kérés (arány = 1024) nem jelenti azt, hogy a konténered megkapja. Ha a host gépednek csak egy magja van, és több mint egy konténert használsz, akkor az összes konténernek közösen kell megosztania a rendelkezésre álló CPU-t. Hogyan történik ez? Nézzük meg a képet.

CPU kérés — egymagos rendszer
Képzeljük el, hogy van egy egymagos host rendszered, amelyen konténerek futnak. Az anyuka (Kubernetes) sült egy tortát (CPU), és meg akarja osztani a gyermekei (konténerek) között. Három gyermek egy egész tortát kér (arány = 1024), még egy gyermek fél tortát kér (512). Az anyuka fair szeretne lenni, ezért elvégzi a számítást.
# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%A számítások alapján a három gyermek 28%-ot kap a magból, nem pedig egy egész magot. A negyedik gyermek 14%-ot kap a teljes magból, nem pedig a felét. De minden másképp alakul, ha többmagos rendszered van.

CPU kérés — többmagos (4) rendszer
A fent látható képen látható, hogy a három gyermek egy egész tortát akar, míg az egyik fél tortát. Mivel az anyuka négy tortát sütött, minden gyermek annyit kap, amennyit szeretne. Többmagos rendszerben a processzora rendelkezésre álló magja közötti erőforrások elosztása történik. Ha a konténer kevesebb, mint egy teljes CPU magra van korlátozva, akkor is 100%-ban kihasználhatja azt.
A fenti számítások leegyszerűsítettek, hogy megértsük, hogyan oszlik el a CPU a konténerek között. Természetesen a konténereken kívül más folyamatok is használják a CPU erőforrásait. Amikor a konténer egyik folyamata tétlen, mások felhasználhatják az erőforrást. CPU: "200m" megfelel CPU: 0,2, ami körülbelül 20%-át jelenti egy magnak.
Most beszéljünk a limit.cpu. A Kubernetes által korlátozott CPU-t 100-zal szorozzuk. Az eredmény — az az idő, amely alatt a konténer felhasználhatja az erőforrást 100 μs-ig (cpu-period).
limit.cpu ez megfelel a Docker zászlónak --cpus. Ez egy új kombináció a régi --cpu-period és --cpu-quota. E beállításokkal megmondjuk, hogy mennyi CPU erőforrást használhat maximum a konténer, mielőtt kezdődne a throttling:
- cpus — kombináció
cpu-periodéscpu-quota. cpus = 1.5ez egyenlő a beállítássalcpu-period = 100000éscpu-quota = 150000; - cpu-period — a CFS CPU ütemező periódusával cpu-quota
- — a mikrosegundák száma, amelyen belül a konténer korlátozva van.
cpu-period, amellyel a tartály korlátozott.
Mi történik, ha nem elég CPU-t állítunk be?
Ha a konténernek több CPU-ra van szüksége, mint amennyit beállítottunk, akkor ellopja a CPU-t más folyamatoktól.
Mi történik, ha nem elegendő CPU-korlátozást állítunk be?
Mivel a CPU-számla szabályozott, a CPU-lassítás aktiválódik.
Mi történik, ha nem adunk meg CPU-t kérésként?
Ahogy a memóriánál, a kérési érték egyenlő a korlátozással.
Mi történik, ha nem adunk meg CPU-korlátozást?
A konténer annyi CPU-t használ, amennyire szüksége van. Ha a névtérben alapértelmezett CPU-politika van megadva (LimitRange), akkor ezt a korlátozást a konténer is használja.
Mi történik, ha sem kérést, sem korlátozást nem adunk meg CPU-nál?
Ahogyan a memóriánál, ez a legrosszabb forgatókönyv. A ütemező nem tudja, mennyi erőforrásra van szüksége a konténerének, és ez súlyos problémákat okozhat a csomóponton. Ennek elkerülése érdekében alapértelmezett korlátozásokat kell beállítani a névterekhez (LimitRange).
Ne felejtsd el: ha több CPU-t kérsz, mint amit a csomópontok tudnak biztosítani, akkor a Pod nem lesz ütemezve. Requests.cpu — nem minimális érték, hanem elegendő ahhoz, hogy a Pod elinduljon és zökkenőmentesen működjön. Ha az alkalmazás nem igényel bonyolult számításokat, a legjobb megoldás — beállítani request.cpu <= 1 és annyi replikát indítani, amennyire szükség van.
Az ideális erőforrás-kérelmek vagy korlátozások száma
Megtanultuk a számítási erőforrások korlátozását. Most itt az idő, hogy megválaszoljunk egy kérdést: «Mennyi erőforrásra van szüksége a Pod-nak az alkalmazás zökkenőmentes működéséhez? Mi az ideális mennyiség?»
Sajnos ezekre a kérdésekre nincsenek egyértelmű válaszok. Ha nem tudod, hogyan működik az alkalmazásod, mennyi CPU-ra vagy memóriára van szüksége, a legjobb megoldás — sok memóriát és CPU-t adni az alkalmazásnak, majd futtatni a teljesítményteszteket.
A teljesítménytesztek mellett egy héten keresztül figyeld az alkalmazás viselkedését a monitorozásban. Ha a grafikonok azt mutatják, hogy az alkalmazásod kevesebb erőforrást fogyaszt, mint amennyit kértél, akkor csökkentheted a kért CPU vagy memória mennyiségét.
Példaként nézd meg ezt a . Ez megjeleníti a kért erőforrások vagy korlátozások és a jelenlegi erőforrás-fogyasztás közötti különbséget.
Zárás
A kért és korlátozott erőforrások segítenek fenntartani a Kubernetes klaszter működését. A megfelelő limitek konfigurációja minimalizálja a költségeket és folyamatosan fenntartja az alkalmazásokat működésben.
Röviden szólva, figyelembe kell venni néhány tényezőt:
- A kért erőforrások - olyan konfiguráció, amely figyelembe lesz véve a beindítás során (amikor a Kubernetes a program elhelyezését tervezi). Ezzel szemben a erőforrások korlátozása fontos a működés közben - amikor az alkalmazás már fut a csomópontnál.
- A memória-val összehasonlítva a CPU - szabályozott erőforrás. CPU hiánya esetén a Pod nem áll le, belép a throttling mechanizmusa.
- A kért erőforrások és az erőforrás korlátok nem minimális és maximális értékek! A kért erőforrások meghatározásával biztosítja, hogy az alkalmazás problémák nélkül működjön.
- Jó gyakorlat, ha a memória-kérés egyenlő a memória-korláttal.
- Jó beállítani a kért
CPU <=1, ha az alkalmazás nem végez bonyolult számításokat. - Ha több erőforrást kér, mint ami a csomóponton van, akkor a Pod soha nem lesz ütemezve erre a csomópontra.
- A megfelelően szükséges erőforrások/korlátok meghatározásához használjon terheléses tesztelést és megfigyelést.
Remélem, hogy ez a cikk segít megérteni az erőforrás-korlátozás alapvető fogalmát. És képes lesz ezt a tudást alkalmazni a munkájában.
Sok sikert!
Mit érdemes még olvasni:
- .
- .
- .
Forrás: habr.com
