Jak získat přístup k prostředkům Kubernetes Pod

Jak získat přístup k prostředkům Kubernetes PodOdměna od Tohad

Na začátku práce s Kubernetes obvykle zapomínají na nastavení prostředků kontejnerů. V této fázi stačí ověřit, že obraz Docker funguje a že ho lze nasadit v klastru Kubernetes.

Později je potřeba aplikaci nasadit do produkčního klastru spolu s dalšími aplikacemi. K tomu je nutné vyčlenit prostředky pro kontejner a ujistit se, že jich je dostatek pro spuštění a fungování aplikace, aniž by to způsobilo problémy v ostatních spuštěných aplikacích.

Tým Kubernetes aaS od Mail.ru přeložila jsem článek o prostředcích kontejnerů (CPU & MEM), dotazech a limitech prostředků. Zjistíte, jaké výhody tyto nastavení poskytují a co se stane, pokud nejsou nastavena.

Výpočetní prostředky

Máme dva typy prostředků s následujícími jednotkami:

  • Centrální procesor (CPU) — jádra;
  • Paměť (MEM) — bajty.

Prostředky jsou specifikovány pro každý kontejner. V následujícím YAML souboru Pod uvidíte sekci prostředků, která obsahuje požadované a limitované prostředky:

  • Požadované prostředky Podu = součet požadovaných prostředků všech kontejnerů;
  • Limitované prostředky Podu = součet limitovaných prostředků všech kontejnerů.

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 # POŽADOVANÝ CPU: 200m jader
          memory: "1Gi" # POŽADOVANÁ MEM: 1Gi
        limits:
          cpu: 1 # MAX VYUŽITÍ CPU: 1 jádro
          memory: "1Gi" # MAX VYUŽITÍ MEM:  1Gi
    - name: other-container
      image: other-app
      tag: v1
      ports:
      - containerPort: 8000
      resources:
        requests:
          cpu: "200m" # POŽADOVANÝ CPU: 200m jader
          memory: "0.5Gi" # POŽADOVANÁ MEM: 0.5Gi
        limits:
          cpu: 1 # MAX VYUŽITÍ CPU: 1 jádro
          memory: "1Gi" # MAX VYUŽITÍ MEM:  1Gi

Příklad požadovaných a limitovaných prostředků

Pole resources.requested ze specifikace Pod — jeden z prvků, který se používá k vyhledání požadovaného uzlu. Na něj lze již naplánovat nasazení Pod. Jak se však hledá vhodný uzel?

Kubernetes se skládá z několika komponentů a zahrnuje hlavní uzel nebo master uzel (Kubernetes Control Plane). Na master uzlu běží několik procesů: kube-apiserver, kube-controller-manager a kube-scheduler.

Proces kube-scheduler je zodpovědný za prohlížení nově vytvořených modulů a hledání možných pracovních uzlů, které splňují všechny požadavky modulů, včetně požadovaného množství prostředků. Seznam uzlů, který kube-scheduler najde, je seřazen. Pod je plánován na uzlu s nejvyššími skóre.

Jak získat přístup k prostředkům Kubernetes PodKam bude umístěn fialový Pod?

Na obrázku je vidět, že kube-scheduler musí naplánovat nový fialový Pod. Kluster Kubernetes obsahuje dva uzly: A a B. Jak si můžete všimnout, kube-scheduler nemůže naplánovat Pod na uzel A — dostupné (nepožadované) zdroje neodpovídají požadavkům fialového Podu. Takže, požadovaných 1 GB paměti pro fialový Pod se na uzlu A nevejde, protože dostupná paměť je 0,5 GB. Na uzlu B však jsou dostatečné zdroje. Nakonec kube-scheduler rozhoduje, že cílovým místem fialového Podu je uzel B.

Nyní víme, jak požadované zdroje ovlivňují výběr uzlu pro spuštění Podu. Ale jak ovlivňují limity zdrojů?

Limity zdrojů jsou hranice, které CPU/MEM nemohou překročit. Nicméně zdroj CPU je flexibilní, takže kontejnery, které dosáhnou limitních hodnot CPU, nezpůsobí ukončení Podu. Místo toho dojde k throttlingu CPU. Pokud však dojde k dosažení limitu využití MEM, kontejner bude zastaven z důvodu OOM-Killer a pokud je to povoleno nastavením RestartPolicy, bude restartován.

Požadované a limitní zdroje v detailech

Jak získat přístup k prostředkům Kubernetes PodSouvislost zdrojů mezi Dockerem a Kubernetes

Nejlepším způsobem, jak vysvětlit, jak požadované a limitní zdroje fungují, je představit si souvislost mezi Kubernetes a Doctorem. Na obrázku výše můžete vidět, jak jsou propojená pole Kubernetes a spouštěcí příznaky Dockeru.

Paměť: požadavek a limit

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

Jak bylo zmíněno výše, paměť se měří v bytech. Na základě dokumentace Kubernetes, můžeme využít paměť jako číslo. Obvykle je to celé číslo, například 2678 — tedy 2678 bytů. Lze také použít suffixy G a Gi, hlavní je si pamatovat, že nejsou ekvivalentní. První je desítkový, druhý je binární. Jako příklad, uvedený v dokumentaci k8s: 128974848, 129e6, 129M, 123Mi — jsou prakticky ekvivalentní.

Parametr Kubernetes limits.memory odpovídá příznaku --memory v Dockeru. V případě request.memory neexistuje žádný ekvivalent v Dockeru, protože Docker toto pole nepoužívá. Můžete se ptát, jestli je to vůbec potřeba? Ano, potřebné je. Jak jsem již řekl, pole má význam pro Kubernetes. Na základě informací z něj kube-scheduler rozhoduje, na který uzel naplánovat Pod.

Co se stane, když nastavíte nedostatečnou paměť pro požadavek?

Pokud kontejner dosáhne limitu požadované paměti, Pod je umístěn do skupiny Podů, které se zastaví při nedostatku paměti na uzlu.

Co se stane, pokud nastavíte příliš nízký limit paměti?

Pokud kontejner překročí limit paměti, bude ukončen z důvodu OOM-Killed. A bude restartován, pokud to bude možné na základě RestartPolicy, kde výchozí hodnota je Vždy.

Co se stane, pokud nezadáte požadovanou paměť?

Kubernetes vezme limit a nastaví ho jako výchozí hodnotu.

Co se může stát, pokud nezadáte limit paměti?

Kontejner nemá žádná omezení, může používat tolik paměti, kolik chce. Pokud začne používat veškerou dostupnou paměť uzlu, bude ukončen OOM. Poté bude kontejner restartován, pokud to bude možné na základě RestartPolicy.

Co se stane, pokud nezadáte limity paměti?

To je nejhorší scénář: plánovač neví, kolik zdrojů kontejner potřebuje, a to může způsobit vážné problémy na uzlu. V tomto případě by bylo dobré mít výchozí omezení v prostoru jmen (nastavené LimitRange). Žádná výchozí omezení nejsou - Pod nemá žádná omezení, může používat tolik paměti, kolik chce.

Pokud je požadovaná paměť větší, než může uzel nabídnout - Pod nebude naplánován. Je důležité si pamatovat, že Requests.memory není minimální hodnota. Je to popis objemu paměti, který je dostatečný pro neustálý provoz kontejneru.

Obvykle se doporučuje nastavit stejnou hodnotu pro request.memory a limit.memory. Díky tomu Kubernetes nenaplánuje Pod na uzlu, který má dostatek paměti pro spuštění Pod, ale nedostatek pro provoz. Mějte na paměti: při plánování Pod Kubernetes zohledňuje pouze requests.memory, a limits.memory a to nezohledňuje.

CPU: požadavek a limit

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

S CPU je to o něco složitější. Když se vrátíme k obrázku vzájemného vztahu mezi Kubernetes a Docker, můžeme si všimnout, že request.cpu odpovídá --cpu-shares, zatímco limit.cpu odpovídá příznaku cpus v Dockeru.

CPU, který Kubernetes žádá, se násobí 1024 - poměr cyklů CPU. Pokud chcete požádat o jedno plné jádro, musíte přidat cpu: 1, jak je uvedeno výše.

Žádost o plné jádro (poměr = 1024) neznamená, že váš kontejner toto jádro dostane. Pokud má váš hostitelský počítač pouze jedno jádro a používáte více než jeden kontejner, všechny kontejnery si musí dostupný CPU sdílet. Jak to funguje? Pojďme se podívat na obrázek.

Jak získat přístup k prostředkům Kubernetes Pod
Žádost o CPU — systém s jedním jádrem

Představme si, že máte hostitelský systém s jedním jádrem, na kterém běží kontejnery. Maminka (Kubernetes) upekla koláč (CPU) a chce ho rozdělit mezi děti (kontejnery). Tři děti chtějí celý koláč (poměr = 1024), jedno dítě chce polovinu koláče (512). Maminka chce být spravedlivá a provede jednoduchý výpočet.

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

Na základě výpočtu obdrží tři děti přibližně 28 % jádra, a ne celé jádro. Čtvrté dítě dostane 14 % z plného jádra, a ne polovinu. Ale vše bude jinak, pokud máte vícejádrový systém.

Jak získat přístup k prostředkům Kubernetes Pod
Žádost o CPU — vícejádrový (4) systém

Na obrázku výše je vidět, že tři děti chtějí celý koláč a jedno chce polovinu. Protože maminka upekla čtyři koláče, každé dítě dostane tolik, kolik chce. V vícejádrovém systému jsou procesorové zdroje rozděleny mezi všechna dostupná jádra procesoru. Pokud je kontejner omezen na méně než jedno plné jádro CPU, může ho přesto využít na 100 %.

Výše uvedené výpočty byly zjednodušeny pro pochopení, jak se CPU dělí mezi kontejnery. Samozřejmě, že kromě samotných kontejnerů existují i další procesy, které také využívají CPU. Když procesy v jednom kontejneru nepracují, mohou ostatní procesy využít jeho zdroje. CPU: "200m" odpovídá CPU: 0,2, což odpovídá přibližně 20 % jednoho jádra.

Nyní si promluvme o limit.cpu. CPU, který omezuje Kubernetes, se násobí 100. Výsledek je množství času, které může kontejner využít každých 100 μs (cpu-period).

limit.cpu odpovídá flagu Docker --cpus. To je nová kombinace starých --cpu-period a --cpu-quota. Nastavením toho uvádíme, kolik dostupných zdrojů CPU může kontejner maximálně využít, než dojde k omezení:

  • cpus — kombinace cpu-period a cpu-quota. cpus = 1.5 odpovídá nastavení cpu-period = 100000 a cpu-quota = 150000;
  • cpu-period — období plánovače CPU CFS, ve výchozím nastavení 100 mikrosekund;
  • cpu-quota — množství mikrosekund uvnitř cpu-period, kterým je kontejner omezen.

Co se stane, pokud nastavíte nedostatečný požadavek na CPU?

Pokud kontejner potřebuje více, než je nastaveno, ukradne CPU od ostatních procesů.

Co se stane, pokud nastavíte nedostatečný limit CPU?

Jelikož je zdroj CPU regulovaný, dojde k throttlingu.

Co se stane, pokud neuvedete požadavek na CPU?

Stejně jako u paměti, požadavek se rovná limitu.

Co se stane, pokud neuvedete limit CPU?

Kontejner použije tolik CPU, kolik potřebuje. Pokud je v prostoru jmen určena výchozí politika CPU (LimitRange), pak tento limit se používá i pro kontejner.

Co se stane, pokud neuvedete ani požadavek, ani limit CPU?

Stejně jako u paměti, to je nejhorší scénář. Plánovač neví, kolik zdrojů váš kontejner potřebuje, a to může způsobit vážné problémy na uzlu. Abychom tomu předešli, musíte nastavit výchozí omezení pro prostory jmen (LimitRange).

Pamatujte: pokud požádáte o více CPU, než mohou poskytnout uzly, Pod nebude naplánován. Requests.cpu — není to minimální hodnota, ale hodnota dostatečná pro spuštění Podu a provoz bez selhání. Pokud aplikace neprovádí složité výpočty, nejlepší volba je nastavit request.cpu <= 1 a spustit tolik replik, kolik je potřeba.

Ideální množství požadovaných nebo limitovaných zdrojů

Zjistili jsme o omezení výpočetních zdrojů. Teď je čas odpovědět na otázku: „Kolik zdrojů potřebuje můj Pod pro bezproblémový provoz aplikace? Jaké množství je ideální?“.

Bohužel na tyto otázky neexistují jednoznačné odpovědi. Pokud nevíte, jak funguje vaše aplikace, kolik CPU nebo paměti potřebuje, nejlepší volba je dát aplikaci hodně paměti a CPU a poté spustit testy výkonnosti.

Kromě testů výkonu sledujte chování aplikace během týdne prostřednictvím monitorování. Pokud z grafů vyplývá, že vaše aplikace spotřebovává méně zdrojů, než jste požadovali, můžete snížit množství požadovaného CPU nebo paměti.

Jako příklad se podívejte na tento dashboard Grafana. Zobrazuje rozdíl mezi požadovanými nebo limitovanými zdroji a aktuálním využitím zdrojů.

Závěr

Žádosti a omezení zdrojů pomáhají udržovat funkčnost Kubernetes clusteru. Správná konfigurace limitů minimalizuje náklady a neustále udržuje aplikace v chodu.

Pokud to shrneme, je dobré mít na paměti několik aspektů:

  1. Žádané zdroje jsou konfigurace, která se zohledňuje během spuštění (kdy Kubernetes plánuje umístění aplikace). Naopak omezení zdrojů je důležité během provozu — když je aplikace již spuštěna na uzlu.
  2. Na rozdíl od paměti je CPU regulovaný zdroj. V případě nedostatku CPU váš Pod nebude ukončen, ale aktivuje se mechanismus throttlingu.
  3. Žádané zdroje a limit zdrojů nejsou minimální a maximální hodnoty! Stanovením žádaných zdrojů zaručujete, že aplikace bude fungovat bez problémů.
  4. Dobrým postupem je nastavit žádost o paměť rovnou limitu paměti.
  5. Je také dobré nastavit žádost o CPU <=1, pokud aplikace neprovádí složité výpočty.
  6. Pokud požádáte o více zdrojů, než jaké jsou na uzlu, Pod nikdy nebude naplánován na tento uzel.
  7. Chcete-li určit správné množství žádostí o zdroje / limitů zdrojů, použijte zátěžové testování a monitoring.

Doufám, že tento článek vám pomůže pochopit základní koncept omezení zdrojů. A budete moci tyto znalosti využít ve své práci.

Hodně štěstí!

Co dalšího si přečíst:

  1. Sledovatelnost SRE: prostory názvů a struktura metrik.
  2. 90+ užitečných nástrojů pro Kubernetes: nasazení, správa, monitoring, bezpečnost a další.
  3. Náš kanál Kolem Kubernetes na Telegramu.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster