Ներկայացնում ենք shell-օպերատորը. Kubernetes-ի համար օպերատորների ստեղծումը պարզապես հեշտացել է

Մեր բլոգում արդեն եղել են հոդվածներ, որոնց մասին խոսում են օպերատորի հնարավորությունները Kubernetes-ում և ինչպես ինքներդ գրեք պարզ օպերատոր. Այս անգամ մենք ցանկանում ենք ձեր ուշադրությանը ներկայացնել մեր բաց կոդով լուծումը, որը օպերատորների ստեղծումը տեղափոխում է գերհեշտ մակարդակ. ստուգեք shell-օպերատոր!

Ինչու?

Shell-օպերատորի գաղափարը բավականին պարզ է. բաժանորդագրվեք իրադարձություններին Kubernetes-ի օբյեկտներից, և երբ այդ իրադարձությունները ստացվեն, գործարկեք արտաքին ծրագիր՝ նրան տրամադրելով տեղեկատվություն իրադարձության մասին.

Ներկայացնում ենք 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:

$ cat Dockerfile
FROM flant/shell-operator:v1.0.0-beta.1-alpine3.9
ADD namespace-hook.sh /hooks

$ docker build -t registry.example.com/my-operator:v1 . 
$ docker push registry.example.com/my-operator:v1

Վազում է կլաստերի մեջ

Եկեք նորից նայենք մանգաղին և այս անգամ գրենք, թե ինչ գործողություններ և ինչ առարկաներով է այն կատարում կլաստերում.

  1. բաժանորդագրվում է անվանատարածքի ստեղծման իրադարձություններին.
  2. ստեղծում է գաղտնիք այլ անունների տարածքներում, բացի այն, որտեղ այն գործարկվել է:

Պարզվում է, որ պատիճը, որում կգործարկվի մեր պատկերը, պետք է թույլտվություն ունենա այս գործողությունները կատարելու համար: Դա կարելի է անել՝ ստեղծելով ձեր սեփական ServiceAccount: Թույլտվությունը պետք է արվի ClusterRole-ի և ClusterRoleBinding-ի տեսքով, քանի որ մեզ հետաքրքրում են ողջ կլաստերի առարկաները:

YAML-ի վերջնական նկարագրությունը այսպիսի տեսք կունենա.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitor-namespaces-acc

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: monitor-namespaces
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "patch"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: monitor-namespaces
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: monitor-namespaces
subjects:
  - kind: ServiceAccount
    name: monitor-namespaces-acc
    namespace: example-monitor-namespaces

Դուք կարող եք գործարկել հավաքված պատկերը որպես պարզ տեղակայում.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1
      serviceAccountName: monitor-namespaces-acc

Հարմարության համար ստեղծվում է առանձին անվանատարածք, որտեղ կգործարկվի shell-օպերատորը և կկիրառվեն ստեղծված մանիֆեստները.

$ kubectl create ns example-monitor-namespaces
$ kubectl -n example-monitor-namespaces apply -f rbac.yaml
$ kubectl -n example-monitor-namespaces apply -f deployment.yaml

Այսքանը. shell-օպերատորը կսկսի, կբաժանորդագրվի անվանատարածքի ստեղծման իրադարձություններին և անհրաժեշտության դեպքում կաշխատի կեռիկը:

Ներկայացնում ենք shell-օպերատորը. Kubernetes-ի համար օպերատորների ստեղծումը պարզապես հեշտացել է

Այսպիսով, պարզ shell սցենար վերածվել է իրական օպերատորի Kubernetes-ի համար և աշխատում է որպես կլաստերի մի մաս: Եվ այս ամենը առանց Golang-ում օպերատորների զարգացման բարդ գործընթացի.

Ներկայացնում ենք shell-օպերատորը. Kubernetes-ի համար օպերատորների ստեղծումը պարզապես հեշտացել է

Այս հարցում կա ևս մեկ օրինակ․․․Ներկայացնում ենք shell-օպերատորը. Kubernetes-ի համար օպերատորների ստեղծումը պարզապես հեշտացել է

Դրա իմաստն առավել մանրամասն կբացահայտենք հաջորդ հրապարակումներից մեկում։

զտման

Օբյեկտներին հետևելը լավ է, բայց հաճախ արձագանքելու կարիք կա փոխելով որոշ օբյեկտների հատկություններ, օրինակ՝ Deployment-ում կրկնօրինակների քանակը փոխելու կամ օբյեկտների պիտակները փոխելու համար:

Երբ իրադարձություն է գալիս, shell-օպերատորը ստանում է օբյեկտի JSON մանիֆեստը: Մենք կարող ենք ընտրել այն հատկությունները, որոնք մեզ հետաքրքրում են այս JSON-ում և գործարկել կեռիկը միայն երբ փոխվում են։ Սրա համար դաշտ կա jqFilter, որտեղ դուք պետք է նշեք jq արտահայտությունը, որը կկիրառվի JSON մանիֆեստի վրա:

Օրինակ, Deployment օբյեկտների պիտակների փոփոխություններին արձագանքելու համար անհրաժեշտ է զտել դաշտը labels դաշտից դուրս metadata. Կազմաձևը կլինի հետևյալը.

cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "deployment",
  "event":["update"],
  "jqFilter": ".metadata.labels"
}
]}
EOF

Այս jqFilter արտահայտությունը Deployment-ի երկար JSON մանիֆեստը վերածում է կարճ JSON-ի՝ պիտակներով.

Ներկայացնում ենք shell-օպերատորը. Kubernetes-ի համար օպերատորների ստեղծումը պարզապես հեշտացել է

shell-օպերատորը կաշխատի միայն այն ժամանակ, երբ այս կարճ JSON-ը փոխվի, և այլ հատկությունների փոփոխություններն անտեսվեն:

Կեռիկի գործարկման համատեքստ

Hook config-ը թույլ է տալիս նշել իրադարձությունների մի քանի տարբերակ, օրինակ՝ 2 տարբերակ Kubernetes-ից իրադարձությունների համար և 2 ժամանակացույց.

{"onKubernetesEvent":[
  {"name":"OnCreatePod",
  "kind": "pod",
  "event":["add"]
  },
  {"name":"OnModifiedNamespace",
  "kind": "namespace",
  "event":["update"],
  "jqFilter": ".metadata.labels"
  }
],
"schedule": [
{ "name":"every 10 min",
  "crontab":"* */10 * * * *"
}, {"name":"on Mondays at 12:10",
"crontab": "* 10 12 * * 1"
]}

Մի փոքր շեղում. այո, shell-operator աջակցում է գործարկում crontab ոճի սցենարներ. Ավելի մանրամասն կարելի է գտնել փաստաթղթավորում.

Տարբերակելու համար, թե ինչու է գործարկվել կեռիկը, shell-օպերատորը ստեղծում է ժամանակավոր ֆայլ և փոխանցում դեպի այն ուղին փոփոխականով դեպի կեռիկ: BINDING_CONTEXT_TYPE. Ֆայլը պարունակում է կեռիկի գործարկման պատճառի JSON նկարագրությունը: Օրինակ, յուրաքանչյուր 10 րոպեն մեկ կեռիկը կաշխատի հետևյալ բովանդակությամբ.

[{ "binding": "every 10 min"}]

... իսկ երկուշաբթի օրը կսկսվի այսպես.

[{ "binding": "every 10 min"}, { "binding": "on Mondays at 12:10"}]

Համար onKubernetesEvent Ավելի շատ JSON գործարկիչներ կլինեն, քանի որ այն պարունակում է օբյեկտի նկարագրությունը.

[
 {
 "binding": "onCreatePod",
 "resourceEvent": "add",
 "resourceKind": "pod",
 "resourceName": "foo",
 "resourceNamespace": "bar"
 }
]

Դաշտերի բովանդակությունը կարելի է հասկանալ նրանց անուններից, և ավելի մանրամասն կարելի է կարդալ այստեղ փաստաթղթավորում. Դաշտից ռեսուրսի անվանում ստանալու օրինակ resourceName jq-ի օգտագործումն արդեն ցուցադրվել է գաղտնիքները կրկնող կեռիկում.

jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH

Նմանատիպ եղանակով կարող եք ստանալ այլ դաշտեր:

Ինչ հաջորդ?

Ծրագրի շտեմարանում, ք /օրինակների դիրեկտորիաներ, կան կեռիկների օրինակներ, որոնք պատրաստ են աշխատելու կլաստերի վրա։ Ձեր սեփական կեռիկները գրելիս կարող եք դրանք հիմք ընդունել:

Աջակցություն կա Պրոմեթևսի միջոցով չափումների հավաքագրման համար. հասանելի չափումները նկարագրված են բաժնում ՄԵԹՐԻԿՆԵՐ.

Ինչպես կարող եք կռահել, shell-օպերատորը գրված է Go-ում և տարածվում է բաց կոդով լիցենզիայի ներքո (Apache 2.0): Մենք երախտապարտ կլինենք զարգացման ցանկացած աջակցության համար նախագիծը GitHub-ումև աստղեր, և հարցեր, և pull հարցումներ:

Վերացնելով գաղտնիության շղարշը՝ կտեղեկացնենք նաև, որ shell-operator է փոքր մեր համակարգի մի մասը, որը կարող է թարմացնել Kubernetes կլաստերում տեղադրված հավելումները և կատարել տարբեր ավտոմատ գործողություններ: Կարդացեք ավելին այս համակարգի մասին ասաց բառացիորեն երկուշաբթի օրը՝ HighLoad++ 2019-ին Սանկտ Պետերբուրգում - շուտով կհրապարակենք այս զեկույցի տեսանյութն ու սղագրությունը։

Մենք ծրագիր ունենք բացելու այս համակարգի մնացած մասը՝ հավելյալ օպերատորը և կեռիկների և մոդուլների մեր հավաքածուն: Ի դեպ, addon-operator արդեն կա հասանելի է github-ում, սակայն դրա համար փաստաթղթերը դեռ ճանապարհին են։ Մոդուլների հավաքածուի թողարկումը նախատեսվում է ամռանը։

Մնացեք մեզ հետ!

PS

Կարդացեք նաև մեր բլոգում.

Source: www.habr.com

Добавить комментарий