Shell-օպերատորի գաղափարը բավականին պարզ է. բաժանորդագրվեք իրադարձություններին Kubernetes-ի օբյեկտներից, և երբ այդ իրադարձությունները ստացվեն, գործարկեք արտաքին ծրագիր՝ նրան տրամադրելով տեղեկատվություն իրադարձության մասին.
Դրա անհրաժեշտությունը ծագեց այն ժամանակ, երբ կլաստերների շահագործման ընթացքում սկսեցին ի հայտ գալ փոքր առաջադրանքներ, որոնք մենք իսկապես ցանկանում էինք ճիշտ ձևով ավտոմատացնել։ Այս բոլոր փոքր առաջադրանքները լուծվել են պարզ bash սկրիպտների միջոցով, չնայած, ինչպես գիտեք, ավելի լավ է օպերատորներ գրել Golang-ով: Ակնհայտ է, որ յուրաքանչյուր նման փոքր առաջադրանքի համար օպերատորի լայնածավալ զարգացման մեջ ներդրումներ կատարելն անարդյունավետ կլինի:
Օպերատոր 15 րոպեում
Եկեք նայենք մի օրինակ, թե ինչ կարող է ավտոմատացվել Kubernetes կլաստերում և ինչպես կարող է օգնել shell-օպերատորը: Օրինակ կարող է լինել հետևյալը. դոկերի ռեեստր մուտք գործելու գաղտնիքի կրկնօրինակում:
Մասնավոր գրանցամատյանից պատկերներ օգտագործող պատյաններն իրենց մանիֆեստում պետք է պարունակեն հղում դեպի գաղտնիք՝ ռեեստր մուտք գործելու համար: Այս գաղտնիքը պետք է ստեղծվի յուրաքանչյուր անվանատարածքում, նախքան պատյաններ ստեղծելը: Սա կարելի է ձեռքով անել, բայց եթե դինամիկ միջավայրեր ստեղծենք, ապա մեկ հավելվածի անվանական տարածքը շատ կդառնա: Իսկ եթե նույնպես 2-3 դիմում չկա... գաղտնիքների թիվը շատ մեծ է դառնում։ Եվ ևս մեկ բան գաղտնիքների մասին. ես կցանկանայի փոխել բանալին՝ ժամանակ առ ժամանակ գրանցամատյան մուտք գործելու համար: Ի վերջո, ձեռքով գործողություններ որպես լուծում բոլորովին անարդյունավետ — մենք պետք է ավտոմատացնենք գաղտնիքների ստեղծումն ու թարմացումը:
Պարզ ավտոմատացում
Եկեք գրենք shell script, որը աշխատում է N վայրկյանը մեկ և ստուգում է անունների տարածքները գաղտնիքի առկայության համար, իսկ եթե գաղտնիք չկա, ապա այն ստեղծվում է։ Այս լուծման առավելությունն այն է, որ այն կարծես կեղևի սցենար է cron-ում՝ դասական և հասկանալի մոտեցում բոլորի համար: Բացասական կողմն այն է, որ դրա գործարկումների միջև ընկած ժամանակահատվածում կարող է ստեղծվել նոր անվանատարածք և որոշ ժամանակ այն մնալ առանց գաղտնիքի, ինչը կհանգեցնի բլոկների գործարկման սխալների:
Ավտոմատացում shell-օպերատորի հետ
Որպեսզի մեր սկրիպտը ճիշտ աշխատի, դասական cron մեկնարկը պետք է փոխարինվի մեկնարկով, երբ ավելացվի անվանատարածք. այս դեպքում, դուք կարող եք գաղտնիք ստեղծել նախքան այն օգտագործելը: Տեսնենք, թե ինչպես դա իրականացնել՝ օգտագործելով shell-operator:
Նախ, եկեք նայենք սցենարին: Shell-operator տերմիններով սկրիպտները կոչվում են կեռիկներ: Յուրաքանչյուր կարթ, երբ վազում է դրոշակով --config տեղեկացնում է shell-օպերատորին իր կապերի մասին, այսինքն. ինչ միջոցառումների վերաբերյալ այն պետք է մեկնարկի: Մեր դեպքում մենք կօգտագործենք onKubernetesEvent:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
fi
Այստեղ նկարագրված է, որ մենք հետաքրքրված ենք իրադարձությունների ավելացմամբ (add) տիպի օբյեկտներ namespace.
Այժմ դուք պետք է ավելացնեք այն կոդը, որը կկատարվի, երբ իրադարձությունը տեղի ունենա.
#!/bin/bash
if [[ $1 == "--config" ]] ; then
# конфигурация
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
else
# реакция:
# узнать, какой namespace появился
createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
# создать в нём нужный секрет
kubectl create -n ${createdNamespace} -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
...
data:
...
EOF
fi
Հիանալի Արդյունքը փոքրիկ, գեղեցիկ սցենար էր։ Այն «վերակենդանացնելու» համար մնում է երկու քայլ՝ պատրաստել պատկերը և գործարկել այն կլաստերի մեջ։
Կեռիկով պատկերի պատրաստում
Եթե նայեք սցենարին, կարող եք տեսնել, որ հրամաններն օգտագործվում են kubectl и jq. Սա նշանակում է, որ պատկերը պետք է ունենա հետևյալ բաները՝ մեր կեռիկը, shell-օպերատորը, որը կվերահսկի իրադարձությունները և կգործարկի կեռիկը, և կեռիկի կողմից օգտագործվող հրամանները (kubectl և jq): Hub.docker.com-ն արդեն ունի պատրաստի պատկեր, որում փաթեթավորված են shell-operator, kubectl և jq։ Մնում է միայն ավելացնել պարզ կեռիկ Dockerfile:
Եկեք նորից նայենք մանգաղին և այս անգամ գրենք, թե ինչ գործողություններ և ինչ առարկաներով է այն կատարում կլաստերում.
բաժանորդագրվում է անվանատարածքի ստեղծման իրադարձություններին.
ստեղծում է գաղտնիք այլ անունների տարածքներում, բացի այն, որտեղ այն գործարկվել է:
Պարզվում է, որ պատիճը, որում կգործարկվի մեր պատկերը, պետք է թույլտվություն ունենա այս գործողությունները կատարելու համար: Դա կարելի է անել՝ ստեղծելով ձեր սեփական ServiceAccount: Թույլտվությունը պետք է արվի ClusterRole-ի և ClusterRoleBinding-ի տեսքով, քանի որ մեզ հետաքրքրում են ողջ կլաստերի առարկաները:
YAML-ի վերջնական նկարագրությունը այսպիսի տեսք կունենա.
Այսքանը. shell-օպերատորը կսկսի, կբաժանորդագրվի անվանատարածքի ստեղծման իրադարձություններին և անհրաժեշտության դեպքում կաշխատի կեռիկը:
Այսպիսով, պարզ shell սցենար վերածվել է իրական օպերատորի Kubernetes-ի համար և աշխատում է որպես կլաստերի մի մաս: Եվ այս ամենը առանց Golang-ում օպերատորների զարգացման բարդ գործընթացի.
Այս հարցում կա ևս մեկ օրինակ․․․
Դրա իմաստն առավել մանրամասն կբացահայտենք հաջորդ հրապարակումներից մեկում։
զտման
Օբյեկտներին հետևելը լավ է, բայց հաճախ արձագանքելու կարիք կա փոխելով որոշ օբյեկտների հատկություններ, օրինակ՝ Deployment-ում կրկնօրինակների քանակը փոխելու կամ օբյեկտների պիտակները փոխելու համար:
Երբ իրադարձություն է գալիս, shell-օպերատորը ստանում է օբյեկտի JSON մանիֆեստը: Մենք կարող ենք ընտրել այն հատկությունները, որոնք մեզ հետաքրքրում են այս JSON-ում և գործարկել կեռիկը միայն երբ փոխվում են։ Սրա համար դաշտ կա jqFilter, որտեղ դուք պետք է նշեք jq արտահայտությունը, որը կկիրառվի JSON մանիֆեստի վրա:
Օրինակ, Deployment օբյեկտների պիտակների փոփոխություններին արձագանքելու համար անհրաժեշտ է զտել դաշտը labels դաշտից դուրս metadata. Կազմաձևը կլինի հետևյալը.
Մի փոքր շեղում. այո, shell-operator աջակցում է գործարկում crontab ոճի սցենարներ. Ավելի մանրամասն կարելի է գտնել փաստաթղթավորում.
Տարբերակելու համար, թե ինչու է գործարկվել կեռիկը, shell-օպերատորը ստեղծում է ժամանակավոր ֆայլ և փոխանցում դեպի այն ուղին փոփոխականով դեպի կեռիկ: BINDING_CONTEXT_TYPE. Ֆայլը պարունակում է կեռիկի գործարկման պատճառի JSON նկարագրությունը: Օրինակ, յուրաքանչյուր 10 րոպեն մեկ կեռիկը կաշխատի հետևյալ բովանդակությամբ.
Դաշտերի բովանդակությունը կարելի է հասկանալ նրանց անուններից, և ավելի մանրամասն կարելի է կարդալ այստեղ փաստաթղթավորում. Դաշտից ռեսուրսի անվանում ստանալու օրինակ resourceName jq-ի օգտագործումն արդեն ցուցադրվել է գաղտնիքները կրկնող կեռիկում.
jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH
Նմանատիպ եղանակով կարող եք ստանալ այլ դաշտեր:
Ինչ հաջորդ?
Ծրագրի շտեմարանում, ք /օրինակների դիրեկտորիաներ, կան կեռիկների օրինակներ, որոնք պատրաստ են աշխատելու կլաստերի վրա։ Ձեր սեփական կեռիկները գրելիս կարող եք դրանք հիմք ընդունել:
Աջակցություն կա Պրոմեթևսի միջոցով չափումների հավաքագրման համար. հասանելի չափումները նկարագրված են բաժնում ՄԵԹՐԻԿՆԵՐ.
Ինչպես կարող եք կռահել, shell-օպերատորը գրված է Go-ում և տարածվում է բաց կոդով լիցենզիայի ներքո (Apache 2.0): Մենք երախտապարտ կլինենք զարգացման ցանկացած աջակցության համար նախագիծը GitHub-ումև աստղեր, և հարցեր, և pull հարցումներ:
Վերացնելով գաղտնիության շղարշը՝ կտեղեկացնենք նաև, որ shell-operator է փոքր մեր համակարգի մի մասը, որը կարող է թարմացնել Kubernetes կլաստերում տեղադրված հավելումները և կատարել տարբեր ավտոմատ գործողություններ: Կարդացեք ավելին այս համակարգի մասին ասաց բառացիորեն երկուշաբթի օրը՝ HighLoad++ 2019-ին Սանկտ Պետերբուրգում - շուտով կհրապարակենք այս զեկույցի տեսանյութն ու սղագրությունը։
Մենք ծրագիր ունենք բացելու այս համակարգի մնացած մասը՝ հավելյալ օպերատորը և կեռիկների և մոդուլների մեր հավաքածուն: Ի դեպ, addon-operator արդեն կա հասանելի է github-ում, սակայն դրա համար փաստաթղթերը դեռ ճանապարհին են։ Մոդուլների հավաքածուի թողարկումը նախատեսվում է ամռանը։