![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/bed059552ed86580939aa18fbdf1553e.jpg)
Bi salên bikaranîna Kubernetes di hilberînê de, me gelek çîrokên balkêş berhev kirine ka çawa xeletiyên di hêmanên pergalê yên cihêreng de bûne sedema encamên ne xweş û/an nefêmkirî ku bandorê li xebata konteyneran û potan dikin. Di vê gotarê de me hilbijarkek ji yên herî gelemperî an balkêş çêkiriye. Her çend hûn qet ne bextewar bin ku hûn bi rewşên weha re rû bi rû nebin jî, xwendina li ser çîrokên detektîf ên weha - nemaze "destê yekem" - her gav balkêş e, ne wusa?..
Çîrok 1. Supercronic û Docker daleqandî
Li ser yek ji koman, me bi awayekî periyodîk Dockerek cemidî wergirt, ku destwerdana xebata normal a komê dike. Di heman demê de, jêrîn di têketinên Docker de hate dîtin:
level=error msg="containerd: start init process" error="exit status 2: "runtime/cgo: pthread_create failed: No space left on device
SIGABRT: abort
PC=0x7f31b811a428 m=0
goroutine 0 [idle]:
goroutine 1 [running]:
runtime.systemstack_switch() /usr/local/go/src/runtime/asm_amd64.s:252 fp=0xc420026768 sp=0xc420026760
runtime.main() /usr/local/go/src/runtime/proc.go:127 +0x6c fp=0xc4200267c0 sp=0xc420026768
runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc4200267c8 sp=0xc4200267c0
goroutine 17 [syscall, locked to thread]:
runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1
… Ya ku herî zêde me di derbarê vê xeletiyê de eleqedar dike ev peyam e: pthread_create failed: No space left on device. Lêkolîna Zû diyar kir ku Docker nekare pêvajoyek bişopîne, ji ber vê yekê ew dem bi dem cemidand.
Di çavdêriyê de, wêneya jêrîn bi tiştê ku diqewime re têkildar e:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/bd778052c87b338493bae54b26830ef3.jpg)
Rewşek wusa li ser girêkên din jî tê dîtin:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/ef512532a95ca982e4342071115dbe9f.jpg)
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/43c32ebca78755dde348ed5e7ac75c79.jpg)
Di heman girêkan de em dibînin:
root@kube-node-1 ~ # ps auxfww | grep curl -c
19782
root@kube-node-1 ~ # ps auxfww | grep curl | head
root 16688 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 17398 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 16852 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 9473 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 4664 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 30571 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 24113 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 16475 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 7176 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>
root 1090 0.0 0.0 0 0 ? Z Feb06 0:00 | _ [curl] <defunct>Derket holê ku ev tevger encama xebata podê ye (karsazek Go-ya ku em bikar tînin da ku karên kronan di pods de bimeşînin):
_ docker-containerd-shim 833b60bb9ff4c669bb413b898a5fd142a57a21695e5dc42684235df907825567 /var/run/docker/libcontainerd/833b60bb9ff4c669bb413b898a5fd142a57a21695e5dc42684235df907825567 docker-runc
| _ /usr/local/bin/supercronic -json /crontabs/cron
| _ /usr/bin/newrelic-daemon --agent --pidfile /var/run/newrelic-daemon.pid --logfile /dev/stderr --port /run/newrelic.sock --tls --define utilization.detect_aws=true --define utilization.detect_azure=true --define utilization.detect_gcp=true --define utilization.detect_pcf=true --define utilization.detect_docker=true
| | _ /usr/bin/newrelic-daemon --agent --pidfile /var/run/newrelic-daemon.pid --logfile /dev/stderr --port /run/newrelic.sock --tls --define utilization.detect_aws=true --define utilization.detect_azure=true --define utilization.detect_gcp=true --define utilization.detect_pcf=true --define utilization.detect_docker=true -no-pidfile
| _ [newrelic-daemon] <defunct>
| _ [curl] <defunct>
| _ [curl] <defunct>
| _ [curl] <defunct>
…Pirsgirêk ev e: dema ku peywirek di superkronîk de tê meşandin, pêvajo ji hêla wê ve hatî çêkirin nikare rast biqede, zivirî nav .
bingotin: Ji bo ku rasttir be, pêvajo ji hêla peywirên cron ve têne çêkirin, lê supercronic ne pergalek destpêkê ye û nikare pêvajoyên ku zarokên wê çêdibin "qebûl bike". Dema ku sînyalên SIGHUP an SIGTERM têne bilind kirin, ew ji pêvajoyên zarokan re nayên derbas kirin, di encamê de pêvajoyên zarokan bi dawî nabin û di rewşa zombî de dimînin. Hûn dikarin li ser van hemîyan bêtir bixwînin, mînakî, li .
Ji bo çareserkirina pirsgirêkan du rê hene:
- Wekî çareseriyek demkî - di yek xala demê de hejmara PID-an di pergalê de zêde bikin:
/proc/sys/kernel/pid_max (since Linux 2.5.34) This file specifies the value at which PIDs wrap around (i.e., the value in this file is one greater than the maximum PID). PIDs greater than this value are not allo‐ cated; thus, the value in this file also acts as a system-wide limit on the total number of processes and threads. The default value for this file, 32768, results in the same range of PIDs as on earlier kernels - An jî peywiran di supercronic de ne rasterast, lê heman bikar tînin dest pê bikin , ku karibe pêvajoyan rast biqedîne û zozanan neke.
Çîrok 2. "Zombî" dema ku cgroup jêbirin
Kubelet dest bi vexwarina gelek CPU kir:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/6140058330faaa3785b089dcba857056.jpg)
Kes ji vê hez nake, lewma me xwe çekdar kir û dest bi çareserkirina pirsgirêkê kir. Encamên lêkolînê wiha bûn:
- Kubelet ji sêyeka dema xwe ya CPU-yê bêtir ji hemî cgroupan daneyên bîranînê dikişîne:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20241'%3E%3C/svg%3E)
- Di navnîşa nameya pêşdebirên kernel de hûn dikarin bibînin . Bi kurtî, xal bi vê yekê tê: pelên cûrbecûr tmpfs û tiştên din ên mîna wan bi tevahî ji pergalê nayê derxistin dema ku cgroup jêbirin, tê gotin zombie. Zû yan dereng ew ê ji cacheya rûpelê werin jêbirin, lê li ser serverê pir bîranîn heye û kernel fêdeya windakirina demê li ser jêbirina wan nabîne. Ji ber vê yekê ew berdewam dikin. Çima ev yek jî dibe? Ev serverek bi karên kron e ku bi domdarî karên nû diafirîne, û bi wan re jî podên nû. Bi vî rengî, cgroupên nû ji bo konteynerên di wan de têne afirandin, ku di demek nêzîk de têne jêbirin.
- Çima cAdvisor di kubelet de ew qas wext winda dike? Ev bi darvekirina herî hêsan tê dîtin
time cat /sys/fs/cgroup/memory/memory.stat. Ger li ser makîneyek saxlem operasyon 0,01 çirkeyan digire, wê hingê li ser cron02 pirsgirêk 1,2 çirkeyan digire. Tişt ev e ku cAdvisor, ku daneyên ji sysfs pir hêdî dixwîne, hewl dide ku bîranîna ku di cgroupên zombî de tê bikar anîn hesab bike. - Ji bo ku bi zorê zozanan rakin, me hewl da ku wekî ku di LKML-ê de tê pêşniyar kirin paqij bikin:
sync; echo 3 > /proc/sys/vm/drop_caches, - lê kernel tevlihevtir derket û erebe qelibî.
Çi bikim? Pirsgirêk tê çareser kirin (, û ji bo ravekirinê binêre ) nûvekirina kernelê Linux heta guhertoya 4.16.
Dîrok 3. Sîstem û çiyayê wê
Dîsa, kubelet li ser hin girêkan gelek çavkaniyan dixwe, lê vê carê ew pir bîranîn dixwe:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/044c4e23a772c61a6206b9b20aa67c1d.jpg)
Derket holê ku pirsgirêkek bi sîstema ku tê de tê bikar anîn re hebû. Ubuntu 16.04, û ew dema birêvebirina montajên ku ji bo girêdanê hatine afirandin çêdibe. subPath ji ConfigMap an veşartî. Piştî ku pod karê xwe qedand karûbarê systemd û çiyayê karûbarê wê dimîne di sîstemê de. Bi demê re, hejmareke mezin ji wan kom dibin. Di vê mijarê de jî pirsgirêk hene:
- ;
- .
... ya paşîn ya ku di pergalê de PR-yê vedibêje: (mijar di sîstemê de - ).
Pirsgirêk êdî nemaye Ubuntu 18.04, lê heke hûn dixwazin berdewam bikin bi karanîna Ubuntu 16.04, dibe ku hûn çareseriya me ya li ser vê mijarê kêrhatî bibînin.
Ji ber vê yekê me DaemonSet-a jêrîn çêkir:
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
app: systemd-slices-cleaner
name: systemd-slices-cleaner
namespace: kube-system
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: systemd-slices-cleaner
template:
metadata:
labels:
app: systemd-slices-cleaner
spec:
containers:
- command:
- /usr/local/bin/supercronic
- -json
- /app/crontab
Image: private-registry.org/systemd-slices-cleaner/systemd-slices-cleaner:v0.1.0
imagePullPolicy: Always
name: systemd-slices-cleaner
resources: {}
securityContext:
privileged: true
volumeMounts:
- name: systemd
mountPath: /run/systemd/private
- name: docker
mountPath: /run/docker.sock
- name: systemd-etc
mountPath: /etc/systemd
- name: systemd-run
mountPath: /run/systemd/system/
- name: lsb-release
mountPath: /etc/lsb-release-host
imagePullSecrets:
- name: antiopa-registry
priorityClassName: cluster-low
tolerations:
- operator: Exists
volumes:
- name: systemd
hostPath:
path: /run/systemd/private
- name: docker
hostPath:
path: /run/docker.sock
- name: systemd-etc
hostPath:
path: /etc/systemd
- name: systemd-run
hostPath:
path: /run/systemd/system/
- name: lsb-release
hostPath:
path: /etc/lsb-release... û ew skrîpta jêrîn bikar tîne:
#!/bin/bash
# we will work only on xenial
hostrelease="/etc/lsb-release-host"
test -f ${hostrelease} && grep xenial ${hostrelease} > /dev/null || exit 0
# sleeping max 30 minutes to dispense load on kube-nodes
sleep $((RANDOM % 1800))
stoppedCount=0
# counting actual subpath units in systemd
countBefore=$(systemctl list-units | grep subpath | grep "run-" | wc -l)
# let's go check each unit
for unit in $(systemctl list-units | grep subpath | grep "run-" | awk '{print $1}'); do
# finding description file for unit (to find out docker container, who born this unit)
DropFile=$(systemctl status ${unit} | grep Drop | awk -F': ' '{print $2}')
# reading uuid for docker container from description file
DockerContainerId=$(cat ${DropFile}/50-Description.conf | awk '{print $5}' | cut -d/ -f6)
# checking container status (running or not)
checkFlag=$(docker ps | grep -c ${DockerContainerId})
# if container not running, we will stop unit
if [[ ${checkFlag} -eq 0 ]]; then
echo "Stopping unit ${unit}"
# stoping unit in action
systemctl stop $unit
# just counter for logs
((stoppedCount++))
# logging current progress
echo "Stopped ${stoppedCount} systemd units out of ${countBefore}"
fi
done... û ew her 5 hûrdeman bi karanîna superkronîk a ku berê hatî destnîşan kirin dimeşîne. Dockerfile wê bi vî rengî xuya dike:
FROM ubuntu:16.04
COPY rootfs /
WORKDIR /app
RUN apt-get update &&
apt-get upgrade -y &&
apt-get install -y gnupg curl apt-transport-https software-properties-common wget
RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable" &&
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - &&
apt-get update &&
apt-get install -y docker-ce=17.03.0*
RUN wget https://github.com/aptible/supercronic/releases/download/v0.1.6/supercronic-linux-amd64 -O
/usr/local/bin/supercronic && chmod +x /usr/local/bin/supercronic
ENTRYPOINT ["/bin/bash", "-c", "/usr/local/bin/supercronic -json /app/crontab"]Çîrok 4. Pêşbaziya dema plansazkirina pods
Hate dîtin ku: heke me podek li ser girêkekê were danîn û wêneya wê ji bo demek pir dirêj were kişandin, wê gavê potek din ku heman girêkê "lêdixe" dê bi hêsanî. dest bi kişandina wêneya podê nû nake. Di şûna wê de, ew li bendê dimîne heya ku wêneya podê berê were kişandin. Wekî encamek, podek ku jixwe hatî plansaz kirin û wêneya wê dikaribû tenê di deqeyekê de were dakêşandin dê di rewşa containerCreating.
Bûyer dê bi vî rengî xuya bikin:
Normal Pulling 8m kubelet, ip-10-241-44-128.ap-northeast-1.compute.internal pulling image "registry.example.com/infra/openvpn/openvpn:master"Ew dizane ku wêneyek yek ji qeydek hêdî dikare sazkirinê asteng bike per node.
Mixabin, gelek rêyên ji rewşê tune ne:
- Biceribînin ku hûn Registry Docker-a xwe rasterast di nav komê de an rasterast bi komê re bikar bînin (mînak, GitLab Registry, Nexus, hwd.);
- Karûbarên wekî wekî .
Çîrok 5. Ji ber kêmbûna bîrê girêk daliqandî ne
Di dema xebitandina sepanên cihêreng de, me di heman demê de rastî rewşek jî hat ku girêkek bi tevahî dev ji gihîştina xwe berdide: SSH bersivê nade, hemî şeytanên çavdêriyê dikevin, û dûv re di têketin de tiştek (an hema hema tiştek) anormal tune.
Ez ê di wêneyan de ji we re bi mînaka yek girêkek ku MongoDB lê dixebitî vebêjim.
Tiştê ku li jor xuya dike ev e ber qeza:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/5de916d270a862cbcbb5ed23c31f698e.jpg)
Û bi vî awayî - после qeza:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/0f32bf1113204cf19f4639a297e40348.jpg)
Di çavdêriyê de, di heman demê de bazdanek tûj jî heye, ku tê de girêk namîne:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/31e770cac5be32bb7f95cfbbc6b9f1ae.jpg)
Bi vî rengî, ji dîmenan diyar dibe ku:
- RAM li ser makîneyê nêzîkî dawiyê ye;
- Di xerckirina RAM-ê de bazdanek tûj heye, piştî ku gihîştina tevahiya makîneyê ji nişkê ve tê asteng kirin;
- Erkek mezin digihîje Mongo, ku pêvajoya DBMS neçar dike ku bêtir bîranîn bikar bîne û bi çalak ji dîskê bixwîne.
Derdikeve holê ku eger di Linux bîra vala diqede (fişara bîrê çêdibe) û guhertin çênabe, wê hingê ber Dema ku kujerê OOM digihîje, dibe ku di navbera avêtina rûpelan li cacheya rûpelê û nivîsandina wan li dîskê de çalakiyek hevseng çêbibe. Ev ji hêla kswapd-ê ve tête kirin, ku bi cesaret ji bo belavkirina paşîn bi qasî ku pêkan dibe gelek rûpelên bîranînê azad dike.
Mixabin, bi bargiraniyek I/O ya mezin re digel hejmarek piçûk bîranîna belaş, kswapd dibe stûna tevahiya pergalê, ji ber ku ew pê ve girêdayî ne hemî veqetandinên (xeletiyên rûpelê) rûpelên bîranînê yên di pergalê de. Ev dikare ji bo demek pir dirêj bidome heke pêvajo êdî nexwazin bîranînê bikar bînin, lê li qeraxa çoltera OOM-kujer sabît bibin.
Pirsa xwezayî ev e: çima kujer OOM ew qas dereng tê? Di dubarekirina xwe ya heyî de, kujerê OOM zehf bêaqil e: ew ê pêvajoyê bikuje tenê gava ku hewildana veqetandina rûpelek bîranînê têk biçe, ango. heke xeletiya rûpelê têk bibe. Ev ji bo demek dirêj çênabe, ji ber ku kswapd bi cesaret rûpelên bîranînê azad dike, cache rûpelê (tevahiya dîska I/O di pergalê de, bi rastî) vedigere dîskê. Bi hûrgulî, bi ravekirina gavên ku ji bo rakirina pirsgirêkên weha di kernelê de hewce ne, hûn dikarin bixwînin .
Ev tevger bi bingehek Linux 4.6 +.
Çîrok 6. Pod di dewleta Li bendê de asê dibin
Di hin koman de, ku tê de bi rastî gelek zozan dixebitin, me dest pê kir ku piraniya wan ji bo demek pir dirêj li dewletê "daleqandî" ne. Pending, her çend konteynerên Docker bixwe berê li ser girêkan dimeşin û dikarin bi destan bi wan re bixebitin.
Wekî din, di describe tiştek xelet tune:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1m default-scheduler Successfully assigned sphinx-0 to ss-dev-kub07
Normal SuccessfulAttachVolume 1m attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-6aaad34f-ad10-11e8-a44c-52540035a73b"
Normal SuccessfulMountVolume 1m kubelet, ss-dev-kub07 MountVolume.SetUp succeeded for volume "sphinx-config"
Normal SuccessfulMountVolume 1m kubelet, ss-dev-kub07 MountVolume.SetUp succeeded for volume "default-token-fzcsf"
Normal SuccessfulMountVolume 49s (x2 over 51s) kubelet, ss-dev-kub07 MountVolume.SetUp succeeded for volume "pvc-6aaad34f-ad10-11e8-a44c-52540035a73b"
Normal Pulled 43s kubelet, ss-dev-kub07 Container image "registry.example.com/infra/sphinx-exporter/sphinx-indexer:v1" already present on machine
Normal Created 43s kubelet, ss-dev-kub07 Created container
Normal Started 43s kubelet, ss-dev-kub07 Started container
Normal Pulled 43s kubelet, ss-dev-kub07 Container image "registry.example.com/infra/sphinx/sphinx:v1" already present on machine
Normal Created 42s kubelet, ss-dev-kub07 Created container
Normal Started 42s kubelet, ss-dev-kub07 Started containerPiştî hin kolandinê, me texmîn kir ku kubelet bi hêsanî wext tune ku hemî agahdariya li ser rewşa pod û ceribandinên zindîtî / amadebûnê ji servera API re bişîne.
Û piştî xwendina alîkariyê, me pîvanên jêrîn dîtin:
--kube-api-qps - QPS to use while talking with kubernetes apiserver (default 5)
--kube-api-burst - Burst to use while talking with kubernetes apiserver (default 10)
--event-qps - If > 0, limit event creations per second to this value. If 0, unlimited. (default 5)
--event-burst - Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. Only used if --event-qps > 0 (default 10)
--registry-qps - If > 0, limit registry pull QPS to this value.
--registry-burst - Maximum size of bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry-qps. Only used if --registry-qps > 0 (default 10)Wek tê dîtin, nirxên xwerû pir piçûk in, û di %90 de ew hemû hewcedariyên xwe pêk tînin... Lê li cem me ev têr nekir. Ji ber vê yekê, em nirxên jêrîn destnîşan dikin:
--event-qps=30 --event-burst=40 --kube-api-burst=40 --kube-api-qps=30 --registry-qps=30 --registry-burst=40... û kubelets ji nû ve dest pê kir, piştî ku me di grafikên bangên servera API-ê de wêneya jêrîn dît:
![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/b2ae099729e55a686f6bec3012b96195.jpg)
... û erê, her tiştî dest pê kir!
PS
Ji bo alîkariya wan di berhevkirina xeletiyan û amadekirina vê gotarê de, ez spasiya xwe ya kûr ji gelek endezyarên pargîdaniya me re, û nemaze ji hevkarê xwe yê tîmê me yê R&D Andrey Klimentyev re radigihînim ().
PPS
Li ser bloga me jî bixwînin:
- «".
- Serişteyên Kubernetes û fêlbazan
- «»;
- «»;
- «»;
- «".
Source: www.habr.com

![Di xebata Kubernetes de 6 xeletiyên pergalê yên balkêş [û çareseriya wan]](/wp-content/uploads/2019/03/0d15d1de17cd6838fc1cad19615af218.jpg)