پرو هوسٽر > بلاگ > انتظاميه > 6 دلچسپ سسٽم بگ جڏهن ڪبرنيٽس استعمال ڪندي [۽ انهن جو حل]
6 دلچسپ سسٽم بگ جڏهن ڪبرنيٽس استعمال ڪندي [۽ انهن جو حل]
پيداوار ۾ ڪبرنيٽس کي استعمال ڪرڻ جي سالن کان، اسان ڪيتريون ئي دلچسپ ڳالهيون گڏ ڪيون آهن ته ڪيئن مختلف سسٽم جي اجزاء ۾ ڪيڙا ناپسنديده ۽/يا سمجھ ۾ نه اچڻ جا نتيجا ڪنٽينر ۽ پوڊ جي آپريشن کي متاثر ڪن ٿا. هن مقالي ۾ اسان ڪجھ سڀ کان عام يا دلچسپ جي چونڊ ڪئي آهي. جيتوڻيڪ توهان ڪڏهن به خوش قسمت نه آهيو ته اهڙين حالتن کي منهن ڏيڻ لاء، اهڙين مختصر جاسوسي ڪهاڻيون بابت پڙهڻ - خاص طور تي "فرسٽ هٿ" - هميشه دلچسپ آهي، ڇا اهو ناهي؟
ڪهاڻي 1. سپر ڪرونڪ ۽ ڊاڪر پھانسي
ھڪڙي ھڪڙي ڪلستر تي، اسان کي وقتي طور تي ھڪڙو منجمد ڊاکر ملي ٿو، جيڪو ڪلستر جي عام ڪم سان مداخلت ڪري ٿو. ساڳئي وقت، هيٺيان ڏٺو ويو 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
…
هن غلطي بابت اسان کي ڪهڙي دلچسپي آهي پيغام آهي: pthread_create failed: No space left on device. تڪڙو مطالعو دستاويز وضاحت ڪئي ته ڊڪر هڪ عمل کي ڇڪي نه سگهيو، ڇو ته اهو وقتي طور تي منجمد ٿي ويو.
نگراني ۾، هيٺ ڏنل تصوير سان ملندڙ جلندڙ آهي ڇا ٿي رهيو آهي:
مسئلو اهو آهي: جڏهن ڪو ڪم سپر ڪرونڪ ۾ هلندو آهي، اهو عمل ان جي ذريعي پيدا ڪيو ويندو آهي صحيح طور تي ختم نه ٿو ڪري سگھجي، ۾ تبديل ٿيڻ زومبي.
ويچاري: وڌيڪ صحيح هجڻ لاءِ، عملن کي ڪرن جي ڪمن جي ذريعي پيدا ڪيو ويندو آهي، پر سپر ڪرونڪ هڪ شروعاتي سسٽم نه آهي ۽ "اپنائڻ" نه ٿو ڪري سگهي پروسيس جيڪي هن جي ٻارن پيدا ڪيا آهن. جڏهن SIGHUP يا SIGTERM سگنل اٿاريا ويندا آهن، اهي ٻار جي عملن تي منتقل نه ڪيا ويندا آهن، جنهن جي نتيجي ۾ ٻار جي عمل ختم نه ٿيندي ۽ زومبي جي حيثيت ۾ رهي ٿي. توھان ھن بابت وڌيڪ پڙھي سگھو ٿا، مثال طور، ۾ اهڙو مضمون.
مسئلا حل ڪرڻ جا ٻه طريقا آهن:
هڪ عارضي ڪم جي طور تي - سسٽم ۾ PIDs جو تعداد وڌايو وقت ۾ هڪ نقطي تي:
/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. ”زومبي“ جڏهن هڪ سي گروپ کي حذف ڪيو وڃي
ڪوبيليٽ تمام گهڻو سي پي يو استعمال ڪرڻ شروع ڪيو:
ڪو به اهو پسند نه ڪندو، تنهنڪري اسان پاڻ کي هٿياربند ڪيو عجيب ۽ مسئلو سان ڊيل ڪرڻ شروع ڪيو. تحقيق جا نتيجا هن ريت هئا:
ڪوبيليٽ پنهنجي سي پي يو وقت جو ٽيون حصو خرچ ڪري ٿو سڀني سي گروپن مان ميموري ڊيٽا ڪڍڻ ۾:
ڪرنل ڊولپرز جي ميلنگ لسٽ ۾ توھان ڳولي سگھو ٿا مسئلي جي بحث. مختصر ۾، نقطي ھيٺ اچي ٿو: مختلف tmpfs فائلون ۽ ٻيون ساڳيون شيون مڪمل طور تي سسٽم مان ختم نه ڪيون ويون آهن جڏهن هڪ cgroup کي حذف ڪري، جنهن کي سڏيو ويندو آهي memcg زومبي. جلد يا بعد ۾ اهي صفحي جي ڪيش مان حذف ٿي ويندا، پر سرور تي تمام گهڻي ميموري آهي ۽ ڪنيل انهن کي حذف ڪرڻ ۾ وقت ضايع ڪرڻ جو نقطو نظر نٿو اچي. ان ڪري اهي ڍير لڳندا رهن ٿا. آخر ائين ڇو ٿي رهيو آهي؟ هي هڪ سرور آهي ڪرون نوڪريون جيڪو مسلسل نئين نوڪريون ٺاهي ٿو، ۽ انهن سان گڏ نوان پوڊ. اهڙيءَ طرح، انهن ۾ ڪنٽينرز لاءِ نوان سي گروپ ٺاهيا ويندا آهن، جيڪي جلد ئي ڊهي ويندا آهن.
ڪبيليٽ ۾ سي ايڊوائزر ايترو وقت ڇو ضايع ڪري ٿو؟ اهو آسان ترين عمل سان ڏسڻ لاء آسان آهي time cat /sys/fs/cgroup/memory/memory.stat. جيڪڏهن هڪ صحتمند مشين تي آپريشن 0,01 سيڪنڊن ۾ لڳندي آهي، ته پوء مشڪلاتي cron02 تي اهو 1,2 سيڪنڊ وٺندو آهي. شيء اها آهي ته cAdvisor، جيڪو sysfs کان ڊيٽا کي تمام سستي طور تي پڙهي ٿو، ڪوشش ڪري ٿو حساب ۾ رکڻ جي يادگيري کي زومبي سي گروپن ۾ استعمال ڪيو وڃي.
زور سان زومبي کي هٽائڻ لاءِ، اسان ڪوشش ڪئي ڪيچ صاف ڪرڻ جي جيئن LKML ۾ تجويز ڪيل آهي: sync; echo 3 > /proc/sys/vm/drop_caches, - پر دانا وڌيڪ پيچيده ٿي ويو ۽ ڪار کي تباهه ڪيو.
#!/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
... ۽ اھو ھلندو آھي ھر 5 منٽ اڳ ذڪر ڪيل سپر ڪرونڪ استعمال ڪندي. ان جو Dockerfile هن طرح ڏسڻ ۾ اچي ٿو:
اهو نوٽ ڪيو ويو آهي ته: جيڪڏهن اسان وٽ هڪ پوڊ هڪ نوڊ تي رکيل آهي ۽ ان جي تصوير تمام گهڻي وقت تائين پمپ ڪئي وئي آهي، ته پوء هڪ ٻيو پوڊ جيڪو "ماري" ساڳيو نوڊ آسان ٿي ويندو. نئين پوڊ جي تصوير کي ڇڪڻ شروع نٿو ڪري. ان جي بدران، اهو انتظار ڪري ٿو جيستائين پوئين پوڊ جي تصوير کي ڇڪيو وڃي. نتيجي طور، هڪ پوڊ جيڪو اڳ ۾ ئي شيڊول ڪيو ويو هو ۽ جنهن جي تصوير صرف هڪ منٽ ۾ ڊائون لوڊ ٿي سگهي ٿي ان جي حيثيت ۾ ختم ٿي ويندي. containerCreating.
واقعا ڪجهه هن طرح نظر ايندا:
Normal Pulling 8m kubelet, ip-10-241-44-128.ap-northeast-1.compute.internal pulling image "registry.example.com/infra/openvpn/openvpn:master"
اهو ظاهر ٿي ويو آهي سست رجسٽري مان هڪ واحد تصوير ڊبليشن کي بلاڪ ڪري سگهي ٿي في نوڊ.
بدقسمتي سان، صورتحال مان نڪرڻ جا ڪيترائي طريقا نه آهن:
ڪوشش ڪريو پنھنجي Docker رجسٽري کي سڌو سنئون ڪلستر ۾ يا سڌو سنئون ڪلستر سان (مثال طور، GitLab رجسٽري، Nexus، وغيره)؛
مختلف ايپليڪيشنن جي آپريشن دوران، اسان هڪ اهڙي صورتحال سان پڻ منهن ڪيو جتي هڪ نوڊ مڪمل طور تي رسائي حاصل ڪرڻ کان روڪي ٿو: SSH جواب نه ڏيندو آهي، سڀ نگراني ڊيمون بند ٿي ويندا آهن، ۽ پوء لاگ ان ۾ ڪجھ به (يا تقريبا ڪجھ به) غير معمولي ناهي.
مان توهان کي هڪ نوڊ جو مثال استعمال ڪندي تصويرن ۾ ٻڌائيندس جتي مونگو ڊي بي ڪم ڪيو.
رام جي استعمال ۾ تيز جمپ آهي، جنهن کان پوء سڄي مشين تائين رسائي اوچتو بند ٿي وئي آهي؛
مونگو تي ھڪڙو وڏو ڪم اچي ٿو، جيڪو DBMS عمل کي وڌيڪ ميموري استعمال ڪرڻ ۽ ڊسڪ مان فعال طور تي پڙھڻ تي مجبور ڪري ٿو.
اهو ظاهر ٿئي ٿو ته جيڪڏهن لينڪس مفت ميموري مان نڪرندي آهي (ميموري پريشر سيٽ ان ۾) ۽ ڪو به ادل نه آهي، پوء ڪرڻ جڏهن OOM قاتل اچي ٿو، هڪ توازن وارو عمل پيدا ٿي سگھي ٿو صفحن کي صفحي جي ڪيش ۾ اڇلڻ ۽ انهن کي ڊسڪ ڏانهن واپس لکڻ جي وچ ۾. اهو ڪيو ويو آهي kswapd، جيڪو بهادريءَ سان ڪيترن ئي ميموري صفحن کي آزاد ڪري ٿو جيترو ممڪن طور تي ايندڙ ورڇ لاءِ.
بدقسمتي سان، هڪ وڏي I / O لوڊ سان گڏ ٿوري مقدار ۾ مفت ياداشت سان گڏ، kswapd سڄي سسٽم جي رڪاوٽ بڻجي وڃي ٿي، ڇاڪاڻ ته اهي ان سان ڳنڍيل آهن سڀ ڪجهه سسٽم ۾ ميموري صفحن جي مختص (صفحي جي غلطي). اهو تمام ڊگهو وقت تائين هلي سگهي ٿو جيڪڏهن پروسيس ميموري کي وڌيڪ استعمال ڪرڻ نٿا چاهين، پر OOM-قاتل ابياس جي بلڪل ڪنڊ تي مقرر ٿيل آهن.
قدرتي سوال آهي: او او ايم قاتل ايتري دير سان ڇو اچي ٿو؟ ان جي موجوده ورهاڱي ۾، OOM قاتل انتهائي بيوقوف آهي: اهو صرف ان عمل کي ماريندو جڏهن ميموري صفحي کي مختص ڪرڻ جي ڪوشش ناڪام ٿيندي، يعني. جيڪڏهن صفحي جي غلطي ناڪام ٿئي ٿي. اهو گهڻو وقت تائين نه ٿو ٿئي، ڇاڪاڻ ته kswapd بهادري سان ميموري صفحن کي آزاد ڪري ٿو، صفحي جي ڪيش کي ڊمپ ڪري ٿو (سسٽم ۾ سڄي ڊسڪ I/O، حقيقت ۾) واپس ڊسڪ ڏانهن. وڌيڪ تفصيل سان، ڪتن ۾ اهڙن مسئلن کي ختم ڪرڻ لاء گهربل قدمن جي وضاحت سان، توهان پڙهي سگهو ٿا هتي.
ڪجھ ڪلسٽرن ۾، جن ۾ واقعي ڪيترائي پوڊ ڪم ڪري رھيا آھن، اسان نوٽ ڪرڻ شروع ڪيو ته انھن مان گھڻا رياست ۾ تمام گھڻي وقت تائين ”پٽ“ آھن. Pending، جيتوڻيڪ ڊاکر ڪنٽينر پاڻ اڳ ۾ ئي نوڊس تي هلندڙ آهن ۽ دستي طور تي ڪم ڪري سگھجن ٿا.
ان کان علاوه، ۾ describe ڪجھ به غلط ناهي:
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
ڪجهه کوٽائي ڪرڻ کان پوءِ، اسان اهو فرض ڪيو ته ڪوبلٽ وٽ صرف ايترو وقت نه هوندو آهي ته هو پوڊ جي حالت بابت سموري معلومات موڪلي سگهي ۽ زندهه/ تياري جا امتحان API سرور ڏانهن.
--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)
جيئن ڏٺو ويو، ڊفالٽ قدر ڪافي ننڍا آهن، ۽ 90٪ ۾ اهي سڀئي ضرورتون ڍڪيندا آهن ... جڏهن ته، اسان جي صورت ۾ اهو ڪافي نه هو. تنهن ڪري، اسان هيٺ ڏنل قدر مقرر ڪريون ٿا: