6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Sulod sa mga katuigan sa paggamit sa Kubernetes sa produksiyon, natigom namo ang daghang makaiikag nga mga istorya kon sa unsang paagi ang mga bug sa lain-laing mga sangkap sa sistema misangpot ngadto sa dili maayo ug/o dili masabtan nga mga sangputanan nga nakaapekto sa operasyon sa mga sudlanan ug mga pod. Niini nga artikulo naghimo kami og usa ka pagpili sa pipila sa labing komon o makapaikag nga mga. Bisan kung dili ka swerte nga makasugat sa ingon nga mga sitwasyon, ang pagbasa bahin sa mga mubu nga istorya sa detektib - labi na ang "first-hand" - kanunay nga makapaikag, dili ba?

Istorya 1. Supercronic ug Docker nga nagbitay

Sa usa sa mga kumpol, nakadawat kami matag karon ug unya usa ka nagyelo nga Docker, nga nakabalda sa normal nga paglihok sa cluster. Sa samang higayon, ang mosunod naobserbahan sa Docker logs:

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

…

Ang labing nakapainteres kanamo bahin sa kini nga sayup mao ang mensahe: pthread_create failed: No space left on device. Dali nga Pagtuon dokumentasyon gipasabut nga ang Docker dili maka-fork sa usa ka proseso, mao nga kini kanunay nga nagyelo.

Sa pagmonitor, ang mosunod nga hulagway katumbas sa unsay nahitabo:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Ang susama nga sitwasyon makita sa ubang mga node:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Sa parehas nga mga node atong makita:

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>

Kini nahimo nga kini nga kinaiya mao ang usa ka sangputanan sa pod nagtrabaho uban supercronic (usa ka Go utility nga among gigamit sa pagpadagan sa mga trabaho sa cron sa 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>
…

Ang problema mao kini: kung ang usa ka buluhaton gipadagan sa supercronic, ang proseso gipatungha niini dili ma-terminate sa saktong paagi, milingi ngadto sa zombie.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Aron mahimong mas tukma, ang mga proseso gipatungha sa mga buluhaton sa cron, apan ang supercronic dili init nga sistema ug dili "makasagop" sa mga proseso nga gipatungha sa mga anak niini. Kung ang mga signal sa SIGHUP o SIGTERM gipataas, dili kini ipasa sa mga proseso sa bata, nga moresulta sa mga proseso sa bata nga dili matapos ug magpabilin sa kahimtang sa zombie. Mahimo nimong basahon ang dugang mahitungod niining tanan, pananglitan, sa ingon niana nga artikulo.

Adunay duha ka paagi sa pagsulbad sa mga problema:

  1. Ingon usa ka temporaryo nga solusyon - dugangi ang gidaghanon sa mga PID sa sistema sa usa ka punto sa oras:
           /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. O paglansad sa mga buluhaton sa supercronic dili direkta, apan gamit ang parehas tini, nga makahimo sa pagtapos sa mga proseso sa husto nga paagi ug dili magpatunghag mga zombie.

Istorya 2. "Mga Zombie" sa dihang nagtangtang sa cgroup

Ang Kubelet nagsugod sa pagkonsumo sa daghang CPU:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Walay usa nga ganahan niini, mao nga kami nag-armas sa among kaugalingon perf ug nagsugod sa pag-atubang sa problema. Ang resulta sa imbestigasyon mao ang mosunod:

  • Ang Kubelet migugol ug labaw sa ikatulo nga bahin sa oras sa CPU niini sa pagbira sa datos sa panumduman gikan sa tanang cgroup:

    6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

  • Sa kernel developers' mailing list imong makit-an paghisgot sa problema. Sa laktud, ang punto moabut niini: lain-laing mga tmpfs file ug uban pang susama nga mga butang dili hingpit nga gikuha gikan sa sistema sa pag delete ug cgroup, ang gitawag memcg Zombie. Sa madugay o sa madali sila mapapas gikan sa cache sa panid, apan adunay daghang memorya sa server ug ang kernel dili makakita sa punto sa pag-usik sa panahon sa pagtangtang niini. Mao nga nagsige silag tambak. Nganong nahitabo man kini? Kini usa ka server nga adunay mga trabaho sa cron nga kanunay nga nagmugna og mga bag-ong trabaho, ug kauban nila ang mga bag-ong pod. Sa ingon, ang mga bag-ong cgroup gihimo alang sa mga sulud niini, nga sa dili madugay matangtang.
  • Ngano nga ang cAdvisor sa kubelet nag-usik ug daghang oras? Kini dali nga makita sa pinakasimple nga pagpatuman time cat /sys/fs/cgroup/memory/memory.stat. Kung sa usa ka himsog nga makina ang operasyon nagkinahanglan og 0,01 segundos, unya sa problema nga cron02 nagkinahanglan kini og 1,2 segundos. Ang butang mao nga ang cAdvisor, nga nagbasa sa mga datos gikan sa sysfs hinay kaayo, naningkamot nga tagdon ang panumduman nga gigamit sa mga zombie cgroup.
  • Aron kusog nga matangtang ang mga zombie, gisulayan namon ang paghawan sa mga cache ingon girekomenda sa LKML: sync; echo 3 > /proc/sys/vm/drop_caches, - apan ang kernel nahimong mas komplikado ug nahagsa ang sakyanan.

Unsay buhaton? Ang problema giayo (pasalig, ug alang sa usa ka paghulagway tan-awa ipagawas ang mensahe) pag-update sa Linux kernel ngadto sa bersyon 4.16.

Kasaysayan 3. Systemd ug ang bukid niini

Sa makausa pa, ang kubelet nag-usik sa daghang mga kahinguhaan sa pipila ka mga node, apan niining higayona kini nag-usik sa sobra nga memorya:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Nahibal-an nga adunay problema sa systemd nga gigamit sa Ubuntu 16.04, ug kini mahitabo kung nagdumala sa mga mount nga gihimo alang sa koneksyon subPath gikan sa ConfigMap o sa sekreto. Human pod nahuman ang trabaho niini ang systemd service ug ang service mount niini nagpabilin sa sistema. Sa paglabay sa panahon, ang usa ka dako nga gidaghanon kanila natipon. Adunay bisan mga isyu bahin niini nga hilisgutan:

  1. #5916;
  2. kubernetes #57345.

... ang katapusan niini nagtumong sa PR sa systemd: #7811 (isyu sa systemd - #7798).

Ang problema wala na sa Ubuntu 18.04, apan kung gusto nimo magpadayon sa paggamit sa Ubuntu 16.04, mahimo nimong makit-an ang among solusyon sa kini nga hilisgutan nga mapuslanon.

Busa gihimo namo ang mosunod nga DaemonSet:

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

... ug kini naggamit sa mosunod nga script:

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

... ug kini nagdagan matag 5 minuto gamit ang nahisgotan na nga supercronic. Ang Dockerfile niini ingon niini:

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

Istorya 4. Kakompetensya kung mag-iskedyul pod

Namatikdan nga: kung kami adunay usa ka pod nga gibutang sa usa ka node ug ang imahe niini gibomba sa dugay nga panahon, unya ang lain nga pod nga "naigo" sa parehas nga node yano ra. wala magsugod sa pagbitad sa imahe sa bag-ong pod. Hinuon, maghulat kini hangtod mabira ang imahe sa miaging pod. Ingon usa ka sangputanan, ang usa ka pod nga naka-iskedyul na ug kansang imahe mahimo’g ma-download sa usa lang ka minuto maabut sa kahimtang sa containerCreating.

Ang mga panghitabo sama niini:

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

Nahitabo kana Ang usa ka imahe gikan sa usa ka hinay nga rehistro mahimong makapugong sa pag-deploy kada node.

Ikasubo, wala'y daghang mga paagi gikan sa sitwasyon:

  1. Sulayi nga gamiton ang imong Docker Registry direkta sa cluster o direkta sa cluster (pananglitan, GitLab Registry, Nexus, ug uban pa);
  2. Gamita ang mga utilities sama sa kraken.

Istorya 5. Ang mga buko nagbitay tungod sa kakulang sa memorya

Atol sa operasyon sa lain-laing mga aplikasyon, nasugatan usab namo ang usa ka sitwasyon diin ang usa ka node hingpit nga mihunong nga ma-access: SSH dili motubag, ang tanan nga monitoring daemon mahulog, ug unya walay bisan unsa (o halos walay bisan unsa) anomalous sa mga troso.

Isulti ko kanimo sa mga litrato gamit ang panig-ingnan sa usa ka node diin naglihok ang MongoDB.

Kini ang hitsura sa ibabaw sa mga aksidente:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Ug ingon niini - human sa mga aksidente:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Sa pag-monitor, adunay usab usa ka mahait nga paglukso, diin ang node dili na magamit:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

Busa, gikan sa mga screenshot klaro nga:

  1. Ang RAM sa makina hapit sa katapusan;
  2. Adunay usa ka mahait nga paglukso sa pagkonsumo sa RAM, pagkahuman ang pag-access sa tibuuk nga makina kalit nga na-disable;
  3. Usa ka dako nga buluhaton moabut sa Mongo, nga nagpugos sa proseso sa DBMS sa paggamit sa dugang nga memorya ug aktibong pagbasa gikan sa disk.

Kini nahimo nga kung ang Linux nahutdan sa libre nga memorya (gibutang ang presyur sa memorya) ug wala’y swap, nan sa Sa diha nga ang OOM killer moabut, ang usa ka pagbalanse nga buhat mahimong motumaw tali sa paglabay sa mga panid ngadto sa panid cache ug pagsulat niini balik sa disk. Gihimo kini sa kswapd, nga maisugon nga nagpagawas sa daghang mga panid sa memorya kutob sa mahimo alang sa sunod nga pag-apod-apod.

Ikasubo, sa usa ka dako nga I/O load inubanan sa gamay nga kantidad sa libre nga memorya, Ang kswapd nahimong bottleneck sa tibuok sistema, tungod kay sila nahigot niini sa tanan nga mga mga alokasyon (mga sayup sa panid) sa mga panid sa memorya sa sistema. Mahimo kini nga magpadayon sa dugay nga panahon kung ang mga proseso dili na gusto nga mogamit pa sa panumduman, apan gitakda sa mismong ngilit sa OOM-killer abyss.

Ang natural nga pangutana mao: nganong ulahi na kaayo ang nagpatay sa OOM? Sa kasamtangan nga pag-uli niini, ang OOM killer hilabihan ka hungog: kini mopatay sa proseso lamang kung ang pagsulay sa paggahin sa usa ka panumduman nga panid mapakyas, i.e. kung mapakyas ang page fault. Dili kini mahitabo sa dugay nga panahon, tungod kay ang kswapd maisugon nga nagpagawas sa mga panid sa panumduman, nga gilabay ang cache sa panid (ang tibuuk nga disk I / O sa sistema, sa tinuud) balik sa disk. Sa dugang nga detalye, nga adunay usa ka paghulagway sa mga lakang nga gikinahanglan aron mapapas ang ingon nga mga problema sa kernel, mahimo nimong basahon dinhi.

Kini nga pamatasan kinahanglan nga molambo uban sa Linux kernel 4.6+.

Istorya 6. Ang mga pod na-stuck sa Pending state

Sa pipila ka mga pungpong, diin adunay daghang mga pod nga nag-operate, nahibal-an namon nga kadaghanan sa kanila "nagbitay" sa dugay nga panahon sa estado. Pending, bisan kung ang mga sudlanan sa Docker mismo nagdagan na sa mga node ug mahimong magamit nga mano-mano.

Dugang pa, sa describe walay sayop:

  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

Pagkahuman sa pipila nga pagkalot, among gihimo ang pangagpas nga ang kubelet wala’y oras aron ipadala ang tanan nga kasayuran bahin sa kahimtang sa mga pods ug liveness/readiness nga mga pagsulay sa API server.

Ug pagkahuman sa pagtuon sa tabang, nakit-an namon ang mosunod nga mga parameter:

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

Ingon sa nakita, ang mga default nga kantidad gamay ra, ug sa 90% ilang gisakup ang tanan nga mga panginahanglan... Apan, sa among kaso kini dili igo. Busa, among gibutang ang mosunod nga mga bili:

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

... ug gi-restart ang mga kubelets, pagkahuman nakita namon ang mosunod nga litrato sa mga graph sa mga tawag sa API server:

6 makapaikag nga mga bug sa sistema kung gigamit ang Kubernetes [ug ilang mga solusyon]

... ug oo, ang tanan nagsugod sa paglupad!

PS

Alang sa ilang tabang sa pagkolekta sa mga bug ug pag-andam niini nga artikulo, akong gipahayag ang akong dakong pasalamat sa daghang mga inhenyero sa among kompanya, ug labi na sa akong kauban gikan sa among R&D team nga si Andrey Klimentyev (mga zuzza).

PPS

Basaha usab sa among blog:

Source: www.habr.com

Idugang sa usa ka comment