Նշում. թարգմ.Այս հոդվածը հանրային սեփականությունում հրապարակված նախագծի նյութերի մի մասն է Learnk8s, վերապատրաստում է ընկերություններին և անհատ ադմինիստրատորներին Kubernetes-ի հետ աշխատելու համար: Դրանում նախագծի մենեջեր Դանիելե Պոլենսիչը կիսվում է տեսողական հրահանգներով, թե ինչ քայլեր ձեռնարկել K8s կլաստերի վրա աշխատող հավելվածների հետ կապված ընդհանուր խնդիրների դեպքում:
TL;DR. ահա մի դիագրամ, որը կօգնի ձեզ կարգաբերել Kubernetes-ում տեղակայումը.
Կլաստերում սխալներ գտնելու և շտկելու համար գծապատկեր: Բնօրինակը (անգլերեն) հասանելի է PDF и որպես նկար.
Հավելվածը Kubernetes-ում տեղակայելիս սովորաբար պետք է սահմանեք երեք բաղադրիչ.
տեղակայումը - սա մի տեսակ բաղադրատոմս է հավելվածի պատճենների ստեղծման համար, որը կոչվում է pods;
Ծառայությունների - ներքին բեռի հավասարակշռող, որը բաշխում է երթևեկությունը պատիճների միջև.
Մուտք — նկարագրություն, թե ինչպես է երթևեկությունը արտաքին աշխարհից հասնելու Ծառայություն:
Ահա արագ գրաֆիկական ամփոփում.
1) Kubernetes-ում հավելվածները երթևեկություն են ստանում արտաքին աշխարհից բեռի հավասարակշռողների երկու շերտերի միջոցով՝ ներքին և արտաքին:
2) Ներքին հավասարակշռիչը կոչվում է Սերվիս, արտաքինը՝ Ingress։
3) Տեղակայումը ստեղծում է պատյաններ և վերահսկում է դրանք (դրանք ձեռքով չեն ստեղծվում):
Ենթադրենք, դուք ցանկանում եք տեղադրել պարզ հավելված a la Ողջույն աշխարհ. YAML կոնֆիգուրացիան դրա համար կունենա հետևյալ տեսքը.
Ինչ վերաբերում է պիտակին track: canary Տեղակայման բաժնի վերևում: Արդյո՞ք այն պետք է համապատասխանի:
Այս պիտակը հատուկ է տեղակայմանը և չի օգտագործվում ծառայության կողմից երթևեկության երթուղու համար: Այլ կերպ ասած, այն կարող է հեռացվել կամ նշանակվել այլ արժեք:
Ինչ վերաբերում է ընտրողին matchLabels?
Այն միշտ պետք է համապատասխանի Pod-ի պիտակներին, քանի որ այն օգտագործվում է Deployment-ի կողմից՝ պատիճները հետևելու համար:
Ենթադրենք, դուք կատարել եք ճիշտ խմբագրումներ։ Ինչպե՞ս ստուգել դրանք:
Դուք կարող եք ստուգել pod պիտակը հետևյալ հրամանով.
kubectl get pods --show-labels
Կամ, եթե պատյանները պատկանում են մի քանի հավելվածների.
kubectl get pods --selector any-name=my-app --show-labels
Որտեղ any-name=my-app պիտակ է any-name: my-app.
Դժվարություններ մնացե՞լ են։
Դուք կարող եք միանալ պատիճին: Դա անելու համար հարկավոր է օգտագործել հրամանը port-forward kubectl-ում։ Այն թույլ է տալիս միանալ ծառայությանը և ստուգել կապը:
service/<service name> - ծառայության անվանումը; մեր դեպքում այդպես է my-service;
3000 այն նավահանգիստն է, որը պետք է բացվի համակարգչում;
80 - դաշտում նշված նավահանգիստ port սպասարկում.
Եթե կապը հաստատվել է, ապա կարգավորումները ճիշտ են:
Եթե կապը ձախողվի, ապա պիտակների հետ կապված խնդիր կա կամ պորտերը չեն համընկնում:
Ծառայության և Ինգրեսի միջև հարաբերությունները
Հավելվածին հասանելիություն ապահովելու հաջորդ քայլը ներառում է Ingress-ի կարգավորումը: Ingress-ը պետք է իմանա, թե ինչպես գտնել ծառայություն, այնուհետև գտնել պատյաններ և ուղղորդել երթևեկությունը դեպի դրանք: Ingress-ը գտնում է պահանջվող ծառայությունը անունով և բաց նավահանգստով:
Ingress-ի և Service-ի նկարագրության մեջ երկու պարամետր պետք է համընկնեն.
servicePort Ingress-ում պետք է համապատասխանի պարամետրին port ծառայության մեջ;
serviceName Ingress-ում պետք է համապատասխանի դաշտին name ծառայության մեջ։
Հետևյալ դիագրամը ամփոփում է նավահանգիստների միացումները.
1) Ինչպես արդեն գիտեք, Սերվիսը լսում է որոշակի port:
2) Ingress-ն ունի պարամետր, որը կոչվում է servicePort:
3) Այս պարամետրը (servicePort) միշտ պետք է համապատասխանի port Ծառայության սահմանման մեջ.
4) Եթե 80 նավահանգիստը նշված է Service-ում, ապա դա անհրաժեշտ է servicePort նույնպես հավասար էր 80:
Գործնականում պետք է ուշադրություն դարձնել հետևյալ տողերին.
Այժմ ամեն անգամ, երբ դուք հարցում եք ուղարկում ձեր համակարգչի 3000 նավահանգիստին, այն կուղարկվի ներդիրի 80-րդ նավահանգիստ՝ Ingress կարգավորիչով: Գնալով http://localhost:3000, դուք պետք է տեսնեք հավելվածի կողմից ստեղծված էջը:
Նավահանգիստների ամփոփում
Եկեք ևս մեկ անգամ հիշենք, թե որ նավահանգիստներն ու պիտակները պետք է համապատասխանեն.
Ծառայության սահմանման ընտրիչը պետք է համապատասխանի պատի պիտակին.
targetPort սահմանման մեջ Ծառայությունը պետք է համապատասխանի containerPort կոնտեյներ պատիճ ներսում;
port Սահմանման մեջ Ծառայությունը կարող է լինել ցանկացած բան: Տարբեր ծառայություններ կարող են օգտագործել նույն նավահանգիստը, քանի որ նրանք ունեն տարբեր IP հասցեներ.
servicePort Ներթափանցումը պետք է համապատասխանի port Ծառայության սահմանման մեջ;
Ծառայության անունը պետք է համապատասխանի դաշտին serviceName Ինգրեսում։
Ցավոք, բավական չէ իմանալ, թե ինչպես ճիշտ ձևավորել YAML կոնֆիգուրացիան:
Ի՞նչ է պատահում, երբ ամեն ինչ սխալ է ընթանում:
Պատիճը կարող է չսկսվել կամ խափանվել:
3 քայլ Kubernetes-ում կիրառական խնդիրների ախտորոշման համար
Նախքան ձեր տեղակայման վրիպազերծումը սկսելը, դուք պետք է լավ իմանաք, թե ինչպես է աշխատում Kubernetes-ը:
Քանի որ K8-ում ներբեռնված յուրաքանչյուր հավելված ունի երեք բաղադրիչ, դրանք պետք է կարգաբերվեն որոշակի հերթականությամբ՝ սկսած հենց ներքևից:
Նախ պետք է համոզվել, որ պատյանները աշխատում են, հետո...
Ստուգեք՝ արդյոք ծառայությունը երթևեկություն է մատակարարում պատյաններին, այնուհետև...
Ստուգեք, արդյոք Ingress-ը ճիշտ է կազմաձևված:
Տեսողական ներկայացում.
1) Դուք պետք է սկսեք խնդիրներ փնտրել ամենաներքևից: Նախ ստուգեք, որ պատիճները ստատուսներ ունեն Ready и Running:
2) Եթե պատյանները պատրաստ են (Ready), դուք պետք է պարզեք, թե արդյոք ծառայությունը բաշխում է երթևեկությունը պատիճների միջև.
3) Վերջապես, դուք պետք է վերլուծեք կապը ծառայության և Ingress-ի միջև.
1. Դիագնոստիկա պատիճ
Շատ դեպքերում խնդիրը կապված է պատիճի հետ: Համոզվեք, որ պատիճները նշված են որպես Ready и Running. Դուք կարող եք դա ստուգել՝ օգտագործելով հրամանը.
kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 0/1 ImagePullBackOff 0 47h
app2 0/1 Error 0 47h
app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
Վերևի հրամանի ելքում վերջին պատիճը նշված է որպես Running и Ready, սակայն, մյուս երկուսի դեպքում դա այդպես չէ։
Ինչպե՞ս հասկանալ, թե ինչն է սխալ եղել:
Գոյություն ունեն չորս օգտակար հրամաններ՝ պատիճ ախտորոշելու համար.
kubectl logs <имя pod'а> թույլ է տալիս տեղեկամատյաններ հանել բեռնարկղերից պատիճով;
kubectl describe pod <имя pod'а> թույլ է տալիս դիտել պատի հետ կապված իրադարձությունների ցանկը.
kubectl get pod <имя pod'а> թույլ է տալիս ստանալ Kubernetes-ում պահվող pod-ի YAML կոնֆիգուրացիան.
kubectl exec -ti <имя pod'а> bash թույլ է տալիս գործարկել ինտերակտիվ հրամանի կեղևը pod կոնտեյներներից մեկում
Ո՞ր մեկն ընտրել:
Փաստն այն է, որ համընդհանուր հրաման չկա: Դրանց համակցությունը պետք է օգտագործվի:
Տիպիկ պատիճ խնդիրներ
Գոյություն ունեն երկու հիմնական տեսակի pod սխալներ՝ գործարկման սխալներ և գործարկման ժամանակի սխալներ:
Գործարկման սխալներ.
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Գործարկման ժամանակի սխալներ.
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Որոշ սխալներ ավելի տարածված են, քան մյուսները: Ահա մի քանի ամենատարածված սխալները և ինչպես դրանք շտկել:
ImagePullBackOff
Այս սխալը տեղի է ունենում, երբ Kubernetes-ը չի կարողանում պատկեր ստանալ պատիճ կոնտեյներներից մեկի համար: Ահա դրա երեք ամենատարածված պատճառները.
Պատկերի անունը սխալ է, օրինակ՝ դուք սխալվել եք դրանում, կամ պատկերը գոյություն չունի.
Պատկերի համար նշվել է գոյություն չունեցող պիտակ;
Պատկերը պահվում է մասնավոր ռեգիստրում, և Kubernetes-ը չունի մուտք գործելու թույլտվություն:
Առաջին երկու պատճառները հեշտ է վերացնել, պարզապես ուղղեք պատկերի անունը և պիտակը: Վերջինիս դեպքում պետք է գաղտնի մուտքագրել փակ ռեեստրի հավատարմագրերը և դրան հղումներ ավելացնել pods-ով։ Kubernetes-ի փաստաթղթերում օրինակ կա ինչպես կարելի է դա անել:
Crash Loop Back Off
Կուբենետեսը սխալ է թույլ տալիս CrashLoopBackOff, եթե բեռնարկղը չի կարող գործարկվել: Սա սովորաբար տեղի է ունենում, երբ.
Հավելվածում կա վրիպակ, որը թույլ չի տալիս այն գործարկել.
Դուք պետք է փորձեք տարայից հասնել գերաններին՝ պարզելու դրա ձախողման պատճառը: Եթե դժվար է մուտք գործել տեղեկամատյաններ, քանի որ բեռնարկղը շատ արագ է վերագործարկվում, կարող եք օգտագործել հետևյալ հրամանը.
kubectl logs <pod-name> --previous
Այն ցուցադրում է բեռնարկղի նախորդ մարմնավորման սխալի հաղորդագրությունները:
RunContainerError
Այս սխալը տեղի է ունենում, երբ բեռնարկղը չի գործարկվում: Այն համապատասխանում է հավելվածի գործարկմանը նախորդող պահին։ Այն սովորաբար առաջանում է սխալ կարգավորումների պատճառով, օրինակ՝
փորձելով տեղադրել գոյություն չունեցող ծավալ, ինչպիսիք են ConfigMap կամ Secrets;
փորձեք տեղադրել միայն կարդալու ծավալը որպես կարդալ-գրել:
Թիմը լավ հարմար է նման սխալները վերլուծելու համար kubectl describe pod <pod-name>.
Պոդները Սպասող վիճակում են
Ստեղծվելուց հետո պատիճը մնում է վիճակում Pending.
Ինչու է դա տեղի ունենում:
Ահա հնարավոր պատճառները (ես ենթադրում եմ, որ ժամանակացույցը լավ է աշխատում).
Կլաստերը չունի բավարար ռեսուրսներ, ինչպիսիք են մշակման հզորությունը և հիշողությունը, որպեսզի աշխատի պատիճը:
Օբյեկտը տեղադրված է համապատասխան անվանատարածքում ResourceQuota և պատիճ ստեղծելը կհանգեցնի, որ անվանատարածքը դուրս կգա քվոտայից:
Pod-ը կապված է Սպասում PersistentVolumeClaim.
Այս դեպքում խորհուրդ է տրվում օգտագործել հրամանը kubectl describe և ստուգեք բաժինը Events:
kubectl describe pod <pod name>
հետ կապված սխալների դեպքում ResourceQuotas, խորհուրդ է տրվում դիտել կլաստերի տեղեկամատյանները՝ օգտագործելով հրամանը
kubectl get events --sort-by=.metadata.creationTimestamp
Պատիճները պատրաստ չեն
Եթե pod նշված է որպես Running, բայց վիճակում չէ Ready, նշանակում է ստուգել դրա պատրաստվածությունը (պատրաստականության զոնդ) ձախողվում է.
Երբ դա տեղի է ունենում, պատիճը չի միանում ծառայությանը և ոչ մի երթևեկություն չի հոսում դեպի այն: Պատրաստության թեստի ձախողումը պայմանավորված է հավելվածում առկա խնդիրների պատճառով: Այս դեպքում սխալը գտնելու համար հարկավոր է վերլուծել բաժինը Events հրամանի ելքում kubectl describe.
2. Սպասարկման ախտորոշում
Եթե պատիճները նշված են որպես Running и Ready, սակայն հավելվածից դեռ պատասխան չկա, դուք պետք է ստուգեք ծառայության կարգավորումները։
Ծառայությունները պատասխանատու են երթևեկության ուղղորդման համար՝ կախված դրանց պիտակներից: Հետևաբար, առաջին բանը, որ դուք պետք է անեք, ստուգեք, թե քանի պատիճ է աշխատում ծառայության հետ: Դա անելու համար կարող եք ստուգել ծառայության վերջնակետերը.
kubectl describe service <service-name> | grep Endpoints
Վերջնակետը ձևի արժեքների զույգ է <IP-адрес:порт>, և առնվազն մեկ այդպիսի զույգ պետք է ներկա լինի ելքում (այսինքն, առնվազն մեկ պատիճ աշխատում է ծառայության հետ):
Եթե բաժինը Endpoins դատարկ, հնարավոր է երկու տարբերակ.
ճիշտ պիտակով պատյաններ չկան (հուշում. ստուգեք՝ արդյոք անվանատարածքը ճիշտ է ընտրված);
Ընտրիչում սպասարկման պիտակների մեջ սխալ կա:
Եթե տեսնում եք վերջնակետերի ցանկը, բայց դեռ չեք կարողանում մուտք գործել հավելված, ապա հավանական մեղավորը սխալ է targetPort ծառայության նկարագրության մեջ:
Ինչպե՞ս ստուգել ծառայության ֆունկցիոնալությունը:
Անկախ ծառայության տեսակից, կարող եք օգտագործել հրամանը kubectl port-forward դրան միանալու համար.
3000-ը այն պորտն է, որը դուք բացում եք համակարգչի վրա;
80 - նավահանգիստ սպասարկման կողմում:
3. Ingress ախտորոշում
Եթե այսքան հեռու եք կարդացել, ապա.
պատիճները նշված են որպես Running и Ready;
ծառայությունը հաջողությամբ բաշխում է երթևեկությունը պատիճների միջև:
Այնուամենայնիվ, դուք դեռ չեք կարող հասնել հավելվածին:
Սա նշանակում է, որ Ingress կարգավորիչը, ամենայն հավանականությամբ, ճիշտ կազմաձևված չէ: Քանի որ Ingress կարգավորիչը կլաստերի երրորդ կողմի բաղադրիչն է, կան վրիպազերծման տարբեր մեթոդներ՝ կախված դրա տեսակից:
Բայց նախքան Ingress-ը կարգավորելու համար հատուկ գործիքներ օգտագործելը, կարող եք շատ պարզ բան անել: Ingress օգտագործում serviceName и servicePort ծառայությանը միանալու համար: Դուք պետք է ստուգեք, արդյոք դրանք ճիշտ են կազմաձևված: Դուք կարող եք դա անել՝ օգտագործելով հրամանը.
kubectl describe ingress <ingress-name>
Եթե սյունակ Backend դատարկ, մեծ է կազմաձևման սխալի հավանականությունը: Եթե հետին պլանները տեղում են, բայց հավելվածը դեռ հասանելի չէ, ապա խնդիրը կարող է կապված լինել.
Հանրային ինտերնետից մուտքի հասանելիության կարգավորումներ;
կլաստերի հասանելիության կարգավորումներ հանրային ինտերնետից:
Դուք կարող եք բացահայտել ենթակառուցվածքի հետ կապված խնդիրները՝ անմիջապես միանալով Ingress pod-ին: Դա անելու համար նախ գտեք Ingress Controller pod-ը (այն կարող է լինել այլ անվանատարածքում).
Այժմ համակարգչի վրա 3000 պորտի բոլոր հարցումները կվերահղվեն դեպի pod 80 նավահանգիստ:
Արդյո՞ք այն աշխատում է հիմա:
Եթե այո, ապա խնդիրը ենթակառուցվածքի մեջ է։ Պետք է պարզել, թե ինչպես է երթևեկությունը ուղղորդվում դեպի կլաստեր:
Եթե ոչ, ապա խնդիրը Ingress վերահսկիչի հետ է:
Եթե չկարողանաք գործարկել Ingress կարգավորիչը, դուք պետք է վրիպազերծեք այն:
Ingress կարգավորիչների բազմաթիվ տեսակներ կան: Առավել հայտնի են Nginx, HAProxy, Traefik և այլն: (առկա լուծումների մասին լրացուցիչ տեղեկությունների համար տե՛ս մեր վերանայումը - մոտ. թարգմ.) Դուք պետք է դիմեք անսարքությունների վերացման ուղեցույցին համապատասխան վերահսկիչի փաստաթղթերում: Քանի որ Ingress Nginx ամենահայտնի Ingress կարգավորիչն է, մենք հոդվածում մի քանի խորհուրդ ենք ներառել դրա հետ կապված խնդիրները լուծելու համար։
Ingress Nginx կարգավորիչի վրիպազերծում
Ingress-nginx նախագիծն ունի պաշտոնական plugin kubectl-ի համար. Թիմ kubectl ingress-nginx կարող են օգտագործվել հետևյալի համար.
տեղեկամատյանների, հետին պլանների, վկայագրերի և այլնի վերլուծություն;
kubectl ingress-nginx backend — ուսումնասիրում է հետնամասը (նման kubectl describe ingress <ingress-name>);
kubectl ingress-nginx logs - ստուգում է տեղեկամատյանները:
Նկատի ունեցեք, որ որոշ դեպքերում ձեզ հարկավոր է նշել Ingress վերահսկիչի ճիշտ անվանատարածքը՝ օգտագործելով դրոշը --namespace <name>.
Ամփոփում
Kubernetes-ի անսարքությունների վերացումը կարող է դժվար լինել, եթե չգիտեք, թե որտեղից սկսել: Դուք միշտ պետք է խնդրին մոտենաք ներքևից վեր՝ սկսեք պատիճներից, այնուհետև անցեք ծառայությանը և Ingress-ին: Այս հոդվածում նկարագրված վրիպազերծման տեխնիկան կարող է կիրառվել այլ օբյեկտների վրա, ինչպիսիք են՝