6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Thar nam bliadhnaichean de bhith a’ cleachdadh Kubernetes ann an cinneasachadh, tha sinn air mòran sgeulachdan inntinneach a chruinneachadh mu mar a dh’ adhbhraich bugaichean ann an grunn phàirtean den t-siostam builean mì-thlachdmhor agus/no do-thuigsinn a’ toirt buaidh air obrachadh shoithichean is pods. San artaigil seo tha sinn air taghadh a dhèanamh de chuid den fheadhainn as cumanta no as inntinniche. Fiù mura h-eil thu fortanach gu leòr a bhith a’ tighinn tarsainn air suidheachaidhean mar sin, tha leughadh mu dheidhinn sgeulachdan goirid lorg-phoileas - gu sònraichte “ciad làmh” - an-còmhnaidh inntinneach, nach eil?..

Sgeulachd 1. Supercronic agus Docker a 'crochadh

Air aon de na cruinneachaidhean, fhuair sinn bho àm gu àm Docker reòta, a chuir bacadh air gnìomhachd àbhaisteach a’ bhraisle. Aig an aon àm, chaidh na leanas a choimhead ann an logaichean Docker:

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

…

Is e an rud as inntinniche dhuinn mun mhearachd seo an teachdaireachd: pthread_create failed: No space left on device. Sgrùdadh Luath sgrìobhainnean mhìnich e nach b’ urrainn do Docker pròiseas a chuir air bhog, agus is e sin as coireach gun do reothadh e bho àm gu àm.

Ann an sgrùdadh, tha an dealbh a leanas a 'freagairt ris na tha a' tachairt:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Tha suidheachadh coltach ris air fhaicinn ann an nodan eile:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Aig na h-aon nodan chì sinn:

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>

Thionndaidh e a-mach gu bheil an giùlan seo mar thoradh air a’ pod a bhith ag obair leis supercronic (goireas Go a bhios sinn a’ cleachdadh gus obraichean cron a ruith ann am pods):

 _ 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>
…

Is e an duilgheadas a tha seo: nuair a thèid gnìomh a ruith ann an supercronic, bidh am pròiseas air a shìolachadh leis chan urrainn dha a chrìochnachadh gu ceart, a' tionndadh a steach zombie.

thuirt: Gus a bhith nas mionaidiche, tha pròiseasan air an sìolachadh le gnìomhan cron, ach chan e siostam init a th’ ann an supercronic agus chan urrainn dhaibh “gabhail ri” pròiseasan a bhios a chlann a’ sìolachadh. Nuair a thèid comharran SIGHUP no SITERM a thogail, chan eil iad air an toirt seachad do phròiseasan an leanaibh, agus mar thoradh air sin chan eil pròiseasan cloinne a 'tighinn gu crìch agus a' fuireach ann an inbhe zombie. Faodaidh tu barrachd a leughadh mu dheidhinn seo uile, mar eisimpleir, ann an artaigil mar sin.

Tha dà dhòigh air fuasgladh fhaighinn air duilgheadasan:

  1. Mar fhuasgladh sealach - àrdaich an àireamh de PIDn san t-siostam aig aon àm:
           /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
  2. No cuir air bhog gnìomhan ann an supercronic chan ann gu dìreach, ach a’ cleachdadh an aon rud tini, a tha comasach air pròiseasan a thoirt gu crìch gu ceart agus gun a bhith a’ sìolachadh zombies.

Sgeul 2. “Zombies” nuair a sguabas tu às cgroup

Thòisich Kubelet ag ithe tòrr CPU:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Cha toil le duine seo, agus mar sin dh'armachd sinn sinn fhìn perf agus thòisich e air dèiligeadh ris an duilgheadas. Bha toraidhean an sgrùdaidh mar a leanas:

  • Bidh Kubelet a’ caitheamh còrr air trian den ùine CPU aige a’ tarraing dàta cuimhne bho gach cgroup:

    6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

  • Ann an liosta puist luchd-leasachaidh kernel a lorgas tu deasbad mun duilgheadas. Ann an ùine ghoirid, tha am puing a’ tighinn sìos gu seo: chan eil diofar fhaidhlichean tmpfs agus rudan eile coltach ris air an toirt air falbh bhon t-siostam gu tur nuair a sguabas tu às cgroup, ris an canar memcg zombie. Ann an ùine ghoirid no nas fhaide air adhart thèid an toirt às tasgadan na duilleige, ach tha tòrr cuimhne air an fhrithealaiche agus chan eil an kernel a’ faicinn a’ phuing ann a bhith a’ caitheamh ùine air an cuir às. Sin as coireach gu bheil iad a 'cumail a' càrnadh. Carson a tha seo eadhon a’ tachairt? Is e seo frithealaiche le obraichean cron a bhios an-còmhnaidh a’ cruthachadh obraichean ùra, agus còmhla riutha pods ùra. Mar sin, thèid cgroups ùra a chruthachadh airson soithichean annta, a thèid a dhubhadh às a dh’ aithghearr.
  • Carson a tha cAdvisor ann an kubelet a’ caitheamh uimhir de ùine? Tha seo furasta fhaicinn leis an coileanadh as sìmplidh time cat /sys/fs/cgroup/memory/memory.stat. Ma bheir an obrachadh air inneal fallain 0,01 diogan, an uairsin air an duilgheadas cron02 bheir e 1,2 diogan. Is e an rud gu bheil cAdvisor, a bhios a’ leughadh dàta bho sysfs gu math slaodach, a’ feuchainn ri aire a thoirt don chuimhne a thathas a’ cleachdadh ann an cgroups zombie.
  • Gus zombies a thoirt air falbh gu làidir, dh’ fheuch sinn ri caches a ghlanadh mar a chaidh a mholadh ann an LKML: sync; echo 3 > /proc/sys/vm/drop_caches, - ach thionndaidh an kernel gu bhith na bu toinnte agus bhuail e an càr.

Dè a nì thu? Tha an duilgheadas air a rèiteachadh (tiomnadh, agus airson tuairisgeul faic teachdaireachd a leigeil ma sgaoil) ag ùrachadh an kernel Linux gu dreach 4.16.

Eachdraidh 3. Systemd and its mount

A-rithist, tha an kubelet ag ithe cus ghoireasan air cuid de nodan, ach an turas seo tha e a’ caitheamh cus cuimhne:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Thionndaidh e a-mach gu bheil duilgheadas ann an systemd air a chleachdadh ann an Ubuntu 16.04, agus bidh e a ’tachairt nuair a bhios tu a’ riaghladh sreapan a thèid a chruthachadh airson ceangal subPath bho ConfigMap no dìomhaireachdan. Às deidh don pod a h-obair a chrìochnachadh tha an t-seirbheis systemd agus an t-seirbheis seirbheis aige fhathast anns an t-siostam. Thar ùine, bidh àireamh mhòr dhiubh a 'cruinneachadh. Tha eadhon cùisean air a’ chuspair seo:

  1. #5916;
  2. àireamh #57345.

...tha am fear mu dheireadh a’ toirt iomradh air PR ann an systemd: #7811 (cùis ann an systemd - #7798).

Chan eil an duilgheadas ann tuilleadh ann an Ubuntu 18.04, ach ma tha thu airson leantainn air adhart a’ cleachdadh Ubuntu 16.04, is dòcha gum bi an dòigh-obrach againn air a’ chuspair seo feumail dhut.

Mar sin rinn sinn an DaemonSet a leanas:

---
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

... agus bidh e a’ cleachdadh an sgriobt a leanas:

#!/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

agus bidh e a’ ruith a h-uile 5 mionaid a’ cleachdadh an supercronic a chaidh ainmeachadh roimhe. Tha an Dockerfile a’ coimhead mar seo:

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"]

Sgeul 4. Co-fharpaiseachd nuair a thathar a' clàradh pods

Chaidh mothachadh: ma tha pod againn air a chuir air nód agus gu bheil an ìomhaigh aige air a phumpadh a-mach airson ùine mhòr, an uairsin bidh pod eile a bhios “a’ bualadh ”an aon nód gu sìmplidh. nach tòisich a’ tarraing ìomhaigh a’ phoit ùr. An àite sin, bidh e a 'feitheamh gus an tèid ìomhaigh a' phoit a bh 'ann roimhe a tharraing. Mar thoradh air an sin, thig pod a bha clàraichte mar-thà agus a dh’ fhaodadh a bhith air a luchdachadh sìos ann am mionaid ann an inbhe containerCreating.

Bidh na tachartasan a’ coimhead rudeigin mar seo:

Normal  Pulling    8m    kubelet, ip-10-241-44-128.ap-northeast-1.compute.internal  pulling image "registry.example.com/infra/openvpn/openvpn:master"

A rèir coltais, tha sin faodaidh aon ìomhaigh bho chlàr slaodach bacadh a chuir air cleachdadh gach nód.

Gu mì-fhortanach, chan eil mòran dhòighean a-mach às an t-suidheachadh:

  1. Feuch ris a’ Chlàr Docker agad a chleachdadh gu dìreach anns a’ bhuidheann no gu dìreach leis a’ bhuidheann (mar eisimpleir, GitLab Registry, Nexus, msaa);
  2. Cleachd goireasan mar kraken.

Sgeulachd 5. Bidh nodan a 'crochadh air sgàth cion cuimhne

Rè obrachadh diofar thagraidhean, thachair sinn cuideachd ri suidheachadh far nach eil nòta gu tur ruigsinneach: chan eil SSH a ’freagairt, bidh a h-uile deamhan sgrùdaidh a’ tuiteam dheth, agus an uairsin chan eil dad (no cha mhòr dad) neo-riaghailteach anns na logaichean.

Innsidh mi dhut ann an dealbhan a’ cleachdadh an eisimpleir de aon nód far an robh MongoDB ag obair.

Seo cò ris a tha e coltach gu h-àrd gu tubaistean:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Agus mar seo - после tubaistean:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Ann an sgrùdadh, tha leum geur ann cuideachd, far nach bi an nód ri fhaighinn:

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

Mar sin, bho na seallaidhean-sgrìn tha e soilleir:

  1. Tha an RAM air an inneal faisg air an deireadh;
  2. Tha leum geur ann an caitheamh RAM, agus às deidh sin tha ruigsinneachd don inneal gu lèir ciorramach gu h-obann;
  3. Bidh gnìomh mòr a’ ruighinn Mongo, a bheir air pròiseas DBMS barrachd cuimhne a chleachdadh agus leughadh gu gnìomhach bhon diosc.

Tha e a 'tionndadh a-mach ma tha Linux a' ruith a-mach à cuimhne an-asgaidh (cuideam cuimhne a 'suidheachadh) agus nach eil suaip ann, an uairsin gu Nuair a ruigeas an neach-marbhadh OOM, faodaidh gnìomh cothromachaidh èirigh eadar a bhith a’ tilgeil dhuilleagan a-steach don tasgadan duilleag agus gan sgrìobhadh air ais gu diosc. Tha seo air a dhèanamh le kswapd, a bhios gu gaisgeil a’ saoradh nas urrainn de dhuilleagan cuimhne airson an sgaoileadh às deidh sin.

Gu mì-fhortanach, le luchd mòr I/O còmhla ri beagan cuimhne an-asgaidh, kswapd gu bhith na bhotal den t-siostam gu lèir, oir tha iad ceangailte ris uile riarachadh (sgàinidhean duilleag) de dhuilleagan cuimhne san t-siostam. Faodaidh seo a dhol air adhart airson ùine mhòr mura h-eil na pròiseasan ag iarraidh cuimhne a chleachdadh tuilleadh, ach gu bheil iad stèidhichte aig fìor oir an àibheis OOM-killer.

Is e a’ cheist nàdarra: carson a tha am marbhadh OOM a ’tighinn cho fadalach? Anns an tionndadh a th’ aige an-dràsta, tha am marbhadh OOM gu math gòrach: marbhaidh e am pròiseas dìreach nuair a dh’ fhailicheas an oidhirp air duilleag cuimhne a riarachadh, i.e. ma dh'fhailicheas mearachd na duilleige. Chan eil seo a’ tachairt airson ùine mhòr, oir bidh kswapd gu gaisgeil a’ saoradh duilleagan cuimhne, a’ dumpadh tasgadan na duilleige (an diosc gu lèir I/O san t-siostam, gu dearbh) air ais chun diosc. Ann am barrachd mionaideachd, le tuairisgeul air na ceumannan a dh'fheumar gus cur às do leithid de dhuilgheadasan ann an kernel, faodaidh tu leughadh an seo.

An giùlan seo bu chòir leasachadh le Linux kernel 4.6+.

Sgeul 6. Podan a' dol an sàs ann an staid ri feitheamh

Ann an cuid de chruinneachaidhean, anns a bheil dha-rìribh mòran pods ag obair, thòisich sinn a 'mothachadh gu bheil a' mhòr-chuid dhiubh "crochadh" airson ùine fhada anns an stàit. Pending, ged a tha na soithichean Docker iad fhèin a’ ruith air na nodan mu thràth agus faodar obrachadh leotha le làimh.

Aig an aon àm, ann an describe chan eil dad ceàrr:

  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 container

Às deidh beagan cladhach, rinn sinn a’ bharail nach eil ùine aig an kubelet am fiosrachadh gu lèir mu staid nan pods agus deuchainnean beòthalachd / ullachaidh a chuir chun t-seirbheisiche API.

Agus às deidh dhuinn cuideachadh a sgrùdadh, lorg sinn na paramadairean a leanas:

--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)

Mar a chithear, tha luachan bunaiteach gu math beag, agus ann an 90% tha iad a' còmhdach a h-uile feum... Ach, anns a' chùis againn cha robh seo gu leòr. Mar sin, shuidhich sinn na luachan a leanas:

--event-qps=30 --event-burst=40 --kube-api-burst=40 --kube-api-qps=30 --registry-qps=30 --registry-burst=40

...

6 bugaichean siostam aoigheachd ann an obrachadh Kubernetes [agus am fuasgladh]

... agus tha, thòisich a h-uile càil ag itealaich!

PS

Airson an cuideachadh ann a bhith a’ cruinneachadh bhiteagan agus ag ullachadh an artaigil seo, tha mi a’ cur mo thaing mhòr do na h-iomadh innleadairean sa chompanaidh againn, agus gu sònraichte dha mo cho-obraiche bhon sgioba R&D againn Andrey Klimentyev (sgios).

Pps

Leugh cuideachd air ar blog:

Source: www.habr.com

Cuir beachd ann