Kubernetes-dan foydalanishda 10 ta keng tarqalgan xato

Eslatma. tarjima.: Ushbu maqola mualliflari kichik Chexiya kompaniyasining muhandislari, pipetail. Ular Kubernetes klasterlarining ishlashi bilan bog'liq [ba'zan banal, ammo baribir] juda dolzarb muammolar va noto'g'ri tushunchalarning ajoyib ro'yxatini tuzishga muvaffaq bo'lishdi.

Kubernetes-dan foydalanishda 10 ta keng tarqalgan xato

Kubernetes-dan foydalangan yillar davomida biz ko'p sonli klasterlar bilan ishladik (boshqariladigan va boshqarilmaydigan - GCP, AWS va Azure-da). Vaqt o'tishi bilan biz ba'zi xatolar doimiy ravishda takrorlanayotganini seza boshladik. Biroq, bu erda uyat yo'q: biz ularning ko'pini o'zimiz qildik!

Maqola eng keng tarqalgan xatolarni o'z ichiga oladi, shuningdek ularni qanday tuzatish haqida gapiradi.

1. Resurslar: so'rovlar va cheklovlar

Ushbu element, albatta, eng yaqin e'tibor va ro'yxatdagi birinchi o'ringa loyiqdir.

Odatda CPU so'rovi yoki umuman ko'rsatilmagan yoki juda past qiymatga ega (har bir tugunga iloji boricha ko'proq podlarni joylashtirish uchun). Shunday qilib, tugunlar ortiqcha yuklanadi. Yuqori yuklanish davrida tugunning qayta ishlash quvvati to'liq ishlatiladi va ma'lum bir ish yuki faqat "so'ragan" narsani oladi. CPU sekinlashishi. Bu ilovaning kechikishi, kutish vaqti va boshqa noxush oqibatlarga olib keladi. (Bu haqda boshqa so'nggi tarjimamizda o'qing: "Kubernetesda protsessor cheklovlari va tajovuzkor tejamkorlik" - taxminan. tarjima.)

BestEffort (juda yo'q tavsiya etiladi):

resources: {}

Juda past CPU so'rovi (o'ta yo'q tavsiya etiladi):

   resources:
      Requests:
        cpu: "1m"

Boshqa tomondan, protsessor chegarasining mavjudligi, hatto tugun protsessori to'liq yuklanmagan bo'lsa ham, podlar tomonidan soat tsikllarini asossiz ravishda o'tkazib yuborishga olib kelishi mumkin. Shunga qaramay, bu kechikishlarning kuchayishiga olib kelishi mumkin. Parametr atrofida bahslar davom etmoqda CPU CFS kvotasi Linux yadrosida va protsessorning o'rnatilgan chegaralarga qarab tormozlanishi, shuningdek, CFS kvotasi o'chirilishi... Afsuski, protsessor chegaralari hal qilishdan ko'ra ko'proq muammolarni keltirib chiqarishi mumkin. Bu haqda batafsil ma'lumotni quyidagi havolada topishingiz mumkin.

Haddan tashqari tanlov (ortiqcha majburiyat) xotira muammolari kattaroq muammolarga olib kelishi mumkin. CPU chegarasiga erishish soat sikllarini o'tkazib yuborishni, xotira chegarasiga erishish esa podani o'ldirishni talab qiladi. Hech kuzatganmisiz OOMkill? Ha, biz aynan shu narsa haqida gapiramiz.

Bu sodir bo'lish ehtimolini minimallashtirishni xohlaysizmi? Xotirani haddan tashqari ajratmang va xotira so'rovini chegaraga o'rnatish orqali Kafolatlangan QoS (Xizmat sifati) dan foydalanmang (quyidagi misolda bo'lgani kabi). Bu haqda ko'proq ma'lumotni o'qing Henning Jacobs taqdimoti (Zalando bosh muhandisi).

Burstable (OOMkilled olish ehtimoli yuqori):

   resources:
      requests:
        memory: "128Mi"
        cpu: "500m"
      limits:
        memory: "256Mi"
        cpu: 2

Kafolatlangan:

   resources:
      requests:
        memory: "128Mi"
        cpu: 2
      limits:
        memory: "128Mi"
        cpu: 2

Resurslarni o'rnatishda nima yordam beradi?

Yordamida ko'rsatkichlar-server protsessor resurslarining joriy iste'moli va xotiradan foydalanishni podlar (va ularning ichidagi konteynerlar) bo'yicha ko'rishingiz mumkin. Katta ehtimol bilan siz allaqachon foydalanasiz. Faqat quyidagi buyruqlarni bajaring:

kubectl top pods
kubectl top pods --containers
kubectl top nodes

Biroq, ular faqat joriy foydalanishni ko'rsatadi. Bu sizga kattalik tartibi haqida taxminiy tasavvur berishi mumkin, ammo oxir-oqibat sizga kerak bo'ladi vaqt davomida ko'rsatkichlarning o'zgarishi tarixi (masalan, savollarga javob berish uchun: "Protsessorning eng yuqori yuki nima edi?", "Kecha ertalab yuk nima edi?" va hokazo). Buning uchun siz foydalanishingiz mumkin Prometheus, DataDog va boshqa vositalar. Ular shunchaki o'lchovlar-serverdan o'lchovlarni oladi va ularni saqlaydi va foydalanuvchi ularni so'rashi va shunga mos ravishda tuzishi mumkin.

VerticalPodAutoscaler Bu beradi avtomatlashtirish bu jarayon. U protsessor va xotiradan foydalanish tarixini kuzatib boradi va ushbu ma'lumotlar asosida yangi so'rovlar va cheklovlarni o'rnatadi.

Hisoblash quvvatidan samarali foydalanish oson ish emas. Bu har doim Tetris o'ynashga o'xshaydi. Agar siz oʻrtacha isteʼmoli past boʻlgan hisoblash quvvati uchun juda koʻp pul toʻlayotgan boʻlsangiz (aytaylik, ~10%), AWS Fargate yoki Virtual Kubelet asosidagi mahsulotlarni koʻrib chiqishni tavsiya qilamiz. Ular serversiz/foydalanish uchun to'lov modelida qurilgan bo'lib, bunday sharoitlarda arzonroq bo'lishi mumkin.

2. Jonlilik va tayyorgarlik zondlari

Odatiy bo'lib, Kubernetesda jonlilik va tayyorlikni tekshirish yoqilmagan. Va ba'zida ular ularni yoqishni unutishadi ...

Ammo halokatli xatolik yuz berganda xizmatni qayta ishga tushirishni qanday boshlash mumkin? Va yuk balanslagichi podning trafikni qabul qilishga tayyorligini qanday biladi? Yoki u ko'proq trafikni boshqarishi mumkinmi?

Ushbu testlar ko'pincha bir-biri bilan aralashtiriladi:

  • Tiriklik - "omon qolish" tekshiruvi, agar u muvaffaqiyatsiz bo'lsa, podni qayta ishga tushiradi;
  • Tayyorlik — tayyorlikni tekshirish, agar u muvaffaqiyatsiz bo'lsa, u podni Kubernetes xizmatidan uzib qo'yadi (buni yordamida tekshirish mumkin kubectl get endpoints) va keyingi tekshirish muvaffaqiyatli yakunlanmaguncha unga trafik kelmaydi.

Bu ikkala tekshiruv PODNING BARCHA HAYOT TIKLIDA IJRO ETILGAN. Bu juda muhim.

Umumiy noto'g'ri tushuncha shundan iboratki, tayyorlik problari faqat ishga tushirilganda ishga tushiriladi, shunda balanslashtiruvchi podning tayyorligini bilishi mumkin (Ready) va trafikni qayta ishlashni boshlashi mumkin. Biroq, bu ulardan foydalanish variantlaridan biri.

Yana bir narsa - podkastdagi trafikning haddan tashqari ko'p ekanligini aniqlash imkoniyati ortiqcha yuklaydi (yoki pod resurs talab qiladigan hisob-kitoblarni amalga oshiradi). Bunday holda, tayyorlikni tekshirish yordam beradi podkadagi yukni kamaytiring va uni "sovuting". Kelajakda tayyorlikni tekshirishni muvaffaqiyatli yakunlash imkonini beradi podkastdagi yukni yana oshiring. Bunday holatda (tayyorlik testi muvaffaqiyatsiz bo'lsa), jonlilik testining muvaffaqiyatsizligi juda teskari bo'ladi. Nega sog'lom va qattiq ishlaydigan podni qayta ishga tushiring?

Shuning uchun, ba'zi hollarda, ularni noto'g'ri sozlangan parametrlar bilan yoqishdan ko'ra, hech qanday tekshiruv o'tkazilmaydi. Yuqorida aytib o'tilganidek, agar jonlilikni tekshirish nusxalari tayyorlikni tekshirish, keyin siz katta muammoga duch kelasiz. Mumkin variant - sozlash faqat tayyorlik testiva xavfli hayot chetga qoldiring.

Umumiy bog'liqliklar muvaffaqiyatsizlikka uchraganda, ikkala turdagi tekshiruv ham muvaffaqiyatsiz bo'lmasligi kerak, aks holda bu barcha podslarning kaskadli (ko'chkiga o'xshash) ishdan chiqishiga olib keladi. Boshqa so'z bilan, o'zingizga zarar yetkazmang.

3. Har bir HTTP xizmati uchun LoadBalancer

Katta ehtimol bilan sizning klasteringizda tashqi dunyoga yo'naltirmoqchi bo'lgan HTTP xizmatlari mavjud.

Agar siz xizmatni sifatida ochsangiz type: LoadBalancer, uning boshqaruvchisi (xizmat ko'rsatuvchi provayderga qarab) tashqi LoadBalancerni ta'minlaydi va muzokaralar olib boradi (albatta L7 da emas, balki hatto L4 da ishlaydi) va bu narxga ta'sir qilishi mumkin (tashqi statik IPv4 manzili, hisoblash quvvati, soniyasiga hisob-kitob qilish) ) bunday resurslarni ko'p miqdorda yaratish zarurati bilan bog'liq.

Bunday holda, xizmatlarni ochish uchun bitta tashqi yuk balanslagichidan foydalanish mantiqiyroq type: NodePort. Yoki yaxshiroq, shunga o'xshash narsalarni kengaytiring nginx-ingress-controller (yoki trafik), kim yagona bo'ladi NodePort tashqi yuk balanslagichi bilan bog'langan so'nggi nuqta va klasterdagi trafikni ishlatib yo'naltiradi kirish- Kubernetes resurslari.

Bir-biri bilan o'zaro aloqada bo'lgan boshqa klaster ichidagi (mikro) xizmatlar kabi xizmatlardan foydalangan holda "muloqot qilishi" mumkin ClusterIP va DNS orqali o'rnatilgan xizmatlarni aniqlash mexanizmi. Faqat ularning umumiy DNS/IP-dan foydalanmang, chunki bu kechikishga ta'sir qilishi va bulutli xizmatlar narxini oshirishi mumkin.

4. Klasterni uning xususiyatlarini hisobga olmasdan avtomatik masshtablash

Klasterga tugunlarni qo'shish va ularni o'chirishda siz ushbu tugunlarda protsessordan foydalanish kabi ba'zi asosiy ko'rsatkichlarga tayanmasligingiz kerak. Podni rejalashtirish ko'pchilikni hisobga olishi kerak cheklovlar, masalan, pod/tugunga yaqinlik, nosozliklar va ruxsatlar, resurs so'rovlari, QoS va boshqalar. Ushbu nuanslarni hisobga olmaydigan tashqi avtoskalerdan foydalanish muammolarga olib kelishi mumkin.

Tasavvur qiling-a, ma'lum bir podkastni rejalashtirish kerak, lekin barcha mavjud protsessor quvvati so'raladi/demontaj qilinadi va pod holatga tushib qoladi Pending. Tashqi avtoskaler protsessorning o'rtacha joriy yukini (so'ralgan emas) ko'radi va kengaytirishni boshlamaydi (kengaytirish) - boshqa tugunni qo'shmaydi. Natijada, bu podkast rejalashtirilmaydi.

Bunday holda, teskari o'lchov (kattalashtirish) — klasterdan tugunni olib tashlash har doim amalga oshirish qiyinroq. Tasavvur qiling-a, sizda statistik pod (doimiy xotira ulangan) bor. Doimiy hajmlar odatda tegishli maxsus mavjudlik zonasi va mintaqada takrorlanmaydi. Shunday qilib, agar tashqi avtoskaler ushbu podkast bilan tugunni o'chirib tashlasa, rejalashtiruvchi bu podani boshqa tugunga rejalashtira olmaydi, chunki bu faqat doimiy xotira joylashgan mavjudlik zonasida amalga oshirilishi mumkin. Pod holatida tiqilib qoladi Pending.

Kubernetes hamjamiyatida juda mashhur klaster-avtoshkalyer. U klasterda ishlaydi, yirik bulut provayderlarining API-larini qo'llab-quvvatlaydi, barcha cheklovlarni hisobga oladi va yuqoridagi holatlarda masshtablasha oladi. Shuningdek, u barcha o'rnatilgan chegaralarni saqlab qolgan holda kengayishi mumkin va shu bilan pulni tejashga qodir (aks holda foydalanilmagan quvvatga sarflanadi).

5. IAM/RBAC imkoniyatlarini e'tiborsiz qoldirish

Doimiy sirlarga ega IAM foydalanuvchilaridan ehtiyot bo'ling mashinalar va ilovalar. Rollar va xizmat hisoblari yordamida vaqtinchalik kirishni tashkil qiling (xizmat hisoblari).

Biz ko'pincha kirish kalitlari (va sirlari) ilova konfiguratsiyasida qattiq kodlanganligi, shuningdek, Cloud IAM-ga kirish imkoniga ega bo'lishiga qaramay, sirlarni aylantirishni e'tiborsiz qoldiradigan faktlarga duch kelamiz. Kerakli hollarda foydalanuvchilar oʻrniga IAM rollari va xizmat hisoblaridan foydalaning.

Kubernetes-dan foydalanishda 10 ta keng tarqalgan xato

Kube2iam haqida unuting va to'g'ridan-to'g'ri xizmat hisoblari uchun IAM rollariga o'ting ( bir xil nomdagi eslatma Shtepan Vrani):

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
  name: my-serviceaccount
  namespace: default

Bitta izoh. Unchalik qiyin emas, to'g'rimi?

Shuningdek, xizmat hisoblari va namuna profillariga imtiyozlar bermang admin и cluster-adminagar ularga kerak bo'lmasa. Buni amalga oshirish biroz qiyinroq, ayniqsa RBAC K8-larda, lekin albatta harakatga arziydi.

6. Podkalar uchun avtomatik anti-affinityga tayanmang

Tasavvur qiling-a, sizda tugunda ba'zi joylashtirishning uchta nusxasi bor. Tugun tushadi va u bilan birga barcha replikalar. Noxush holat, to'g'rimi? Lekin nima uchun barcha nusxalar bitta tugunda edi? Kubernetes yuqori mavjudlikni (HA) ta'minlashi kerak emasmi?!

Afsuski, Kubernetes rejalashtiruvchisi o'z tashabbusi bilan alohida mavjudlik qoidalariga mos kelmaydi. (yaqinlikka qarshi) podalar uchun. Ular aniq ko'rsatilishi kerak:

// опущено для краткости
      labels:
        app: zk
// опущено для краткости
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - zk
              topologyKey: "kubernetes.io/hostname"

Ana xolos. Endi podkastlar turli tugunlarga rejalashtirilgan bo'ladi (bu holat faqat rejalashtirish vaqtida tekshiriladi, lekin ularning ishlashi paytida emas - shuning uchun requiredDuringSchedulingIgnoredDuringExecution).

Bu erda biz gaplashamiz podAntiAffinity turli tugunlarda: topologyKey: "kubernetes.io/hostname", - va turli mavjudlik zonalari haqida emas. To'liq huquqli HAni amalga oshirish uchun siz ushbu mavzuni chuqurroq o'rganishingiz kerak bo'ladi.

7. PodDisruptionBudgets-ga e'tibor bermaslik

Tasavvur qiling-a, sizda Kubernetes klasterida ishlab chiqarish yuki bor. Vaqti-vaqti bilan tugunlar va klasterning o'zi yangilanishi (yoki foydalanishdan chiqarilishi) kerak. PodDisruptionBudget (PDB) klaster ma'murlari va foydalanuvchilar o'rtasidagi xizmatlarni kafolatlash shartnomasiga o'xshaydi.

PDB sizga tugunlarning etishmasligi tufayli xizmat ko'rsatishdagi uzilishlarning oldini olishga imkon beradi:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: zookeeper

Ushbu misolda siz, klaster foydalanuvchisi sifatida administratorlarga: "Hey, menda hayvonot bog'i xizmati bor va nima qilsangiz ham, men ushbu xizmatning kamida ikkita nusxasi doimo mavjud bo'lishini xohlayman" deb aytasiz.

Bu haqda ko'proq o'qishingiz mumkin shu yerda.

8. Umumiy klasterda bir nechta foydalanuvchilar yoki muhitlar

Kubernetes nom maydonlari (nom bo'shliqlari) kuchli izolyatsiyani ta'minlamang.

Keng tarqalgan noto'g'ri tushuncha shundaki, agar siz bitta nom maydoniga mahsulot bo'lmagan yukni va boshqasiga ishlab chiqarish yukini joylashtirsangiz, ular hech qanday tarzda bir-biriga ta'sir qilmaydi... Biroq, resurs so'rovlari/cheklovlari, kvotalar belgilash va priorityClasses o'rnatish yordamida ma'lum darajadagi izolyatsiyaga erishish mumkin. Ma'lumotlar tekisligidagi ba'zi "jismoniy" izolyatsiya yaqinlik, bardoshlik, qoralash (yoki tugunni tanlash) bilan ta'minlanadi, ammo bunday ajratish juda mos keladi. qiyin amalga oshirish.

Ikkala turdagi ish yukini bir xil klasterda birlashtirishi kerak bo'lganlar murakkablik bilan shug'ullanishlari kerak. Agar bunday ehtiyoj bo'lmasa va siz bunga ega bo'lishingiz mumkin yana bitta klaster (aytaylik, ommaviy bulutda), keyin buni qilish yaxshiroqdir. Bu izolyatsiyaning ancha yuqori darajasiga erishadi.

9. tashqi TrafficPolicy: Klaster

Ko'pincha biz klaster ichidagi barcha trafik standart siyosat o'rnatilgan NodePort kabi xizmat orqali kelishini ko'ramiz. externalTrafficPolicy: Cluster... Bu shuni anglatadiki NodePort klasterdagi har bir tugunda ochiq bo'lib, siz ulardan istalganidan istalgan xizmat (podkalar to'plami) bilan ishlash uchun foydalanishingiz mumkin.

Kubernetes-dan foydalanishda 10 ta keng tarqalgan xato

Shu bilan birga, yuqorida aytib o'tilgan NodePort xizmati bilan bog'liq haqiqiy podlar odatda faqat ma'lum bir joyda mavjud. ushbu tugunlarning kichik to'plami. Boshqacha qilib aytadigan bo'lsak, agar men kerakli podkastga ega bo'lmagan tugunga ulansam, u trafikni boshqa tugunga yo'naltiradi, hop qo'shish va ortib borayotgan kechikish (agar tugunlar turli xil mavjud zonalarda/ma'lumotlar markazlarida joylashgan bo'lsa, kechikish ancha yuqori bo'lishi mumkin; qo'shimcha ravishda, chiqish trafigi xarajatlari oshadi).

Boshqa tomondan, agar ma'lum bir Kubernetes xizmatida siyosat to'plami bo'lsa externalTrafficPolicy: Local, keyin NodePort faqat kerakli bo'laklar ishlayotgan tugunlarda ochiladi. Holatni tekshiradigan tashqi yuk balanslagichidan foydalanilganda (salomatlikni tekshirish) so'nggi nuqtalar (bu qanday qiladi AWS ELB), U trafikni faqat kerakli tugunlarga yuboradi, bu kechikishlar, hisoblash ehtiyojlari, chiqish to'lovlariga foydali ta'sir ko'rsatadi (va sog'lom fikr ham xuddi shunday talab qiladi).

Siz allaqachon shunga o'xshash narsadan foydalanayotgan bo'lishingiz ehtimoli yuqori trafik yoki nginx-ingress-controller HTTP kirish trafigini yo'naltirish uchun NodePort so'nggi nuqtasi (yoki NodePort-dan ham foydalanadigan LoadBalancer) sifatida va ushbu parametrni o'rnatish bunday so'rovlar uchun kechikish vaqtini sezilarli darajada kamaytirishi mumkin.

В Ushbu nashr Siz externalTrafficPolicy, uning afzalliklari va kamchiliklari haqida ko'proq bilib olishingiz mumkin.

10. Klasterlarga bog'lanib qolmang va boshqaruv tekisligini suiiste'mol qilmang

Ilgari serverlarni tegishli nomlar bilan chaqirish odatiy hol edi: Anton, HAL9000 va Colossus... Bugungi kunda ular tasodifiy yaratilgan identifikatorlar bilan almashtirildi. Biroq, odat saqlanib qoldi va endi tegishli nomlar klasterlarga o'tadi.

Oddiy hikoya (haqiqiy voqealarga asoslangan): barchasi kontseptsiyani isbotlash bilan boshlandi, shuning uchun klaster g'ururli nomga ega edi. sinov... Yillar o'tdi va u HANIMIZ ishlab chiqarishda qo'llanilmoqda va hamma unga tegishdan qo'rqadi.

Klasterlarning uy hayvonlariga aylanishida qiziq narsa yo'q, shuning uchun biz ularni mashq paytida vaqti-vaqti bilan olib tashlashni tavsiya qilamiz. falokatni tiklash (bu yordam beradi xaos muhandisligi - taxminan. tarjima.). Bundan tashqari, nazorat qatlamida ishlash zarar qilmaydi (boshqaruv samolyoti). Unga tegishdan qo'rqish yaxshi belgi emas. Va hokazo o'lganmi? Bolalar, siz haqiqatan ham muammoga duch keldingiz!

Boshqa tomondan, siz uni manipulyatsiya qilish bilan shug'ullanmasligingiz kerak. Vaqt bilan boshqaruv qatlami sekinlashishi mumkin. Ehtimol, bu juda ko'p sonli ob'ektlarning aylantirilmasdan yaratilganligi bilan bog'liq (Helm-ni standart sozlamalar bilan ishlatishda odatiy holat, shuning uchun uning konfiguratsiya xaritalari/sirlaridagi holati yangilanmaydi - buning natijasida minglab ob'ektlar to'planadi. nazorat qatlami) yoki kube-api ob'ektlarini doimiy tahrirlash bilan (avtomatik masshtablash uchun, CI/CD uchun, monitoring uchun, voqealar jurnallari, kontrollerlar va boshqalar).

Bundan tashqari, biz boshqariladigan Kubernetes provayderi bilan SLA/SLO shartnomalarini tekshirishni va kafolatlarga e'tibor berishni tavsiya qilamiz. Sotuvchi kafolat berishi mumkin qatlam mavjudligini nazorat qilish (yoki uning subkomponentlari), lekin siz unga yuborgan so'rovlarning p99 kechikishi emas. Boshqacha qilib aytganda, siz kiritishingiz mumkin kubectl get nodes, va javobni faqat 10 daqiqadan so'ng oling va bu xizmat shartnomasi shartlarini buzmaydi.

11. Bonus: oxirgi tegdan foydalanish

Ammo bu allaqachon klassik. So'nggi paytlarda biz ushbu texnikani kamroq uchratdik, chunki ko'pchilik achchiq tajribadan o'rganib, tegdan foydalanishni to'xtatdilar. :latest va versiyalarni mahkamlashni boshladi. Xayr!

ECR tasvir teglarining o'zgarmasligini saqlaydi; Ushbu ajoyib xususiyat bilan tanishib chiqishingizni tavsiya qilamiz.

Xulosa

Hamma narsa bir kechada ishlashini kutmang: Kubernetes panatseya emas. Yomon dastur Hatto Kubernetesda ham shunday qoladi (va ehtimol yomonlashadi). Ehtiyotsizlik nazorat qatlamining haddan tashqari murakkabligiga, sekin va stressli ishiga olib keladi. Bundan tashqari, siz falokatni tiklash strategiyasisiz qolishingiz mumkin. Kubernetes izolyatsiya va yuqori darajadagi mavjudlikni ta'minlaydi deb kutmang. Ilovangizni haqiqiy bulutli qilish uchun biroz vaqt sarflang.

Siz turli jamoalarning muvaffaqiyatsiz tajribalari bilan tanishishingiz mumkin bu hikoyalar to'plami Henning Jacobs tomonidan.

Ushbu maqolada keltirilgan xatolar ro'yxatiga qo'shmoqchi bo'lganlar biz bilan Twitter orqali bog'lanishlari mumkin (@MarekBartik, @MstrsObserver).

Tarjimondan PS

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish