It idee fan in shell-operator is frij simpel: abonnearje op eveneminten fan Kubernetes-objekten, en as dizze eveneminten wurde ûntfongen, lansearje in ekstern programma, it leverjen fan ynformaasje oer it evenemint:
It ferlet dêrfoar ûntstie doe't der by de eksploitaasje fan klusters lytse taken begûnen te ferskinen dy't wy echt op de goede manier automatisearje woene. Al dizze lytse taken waarden oplost mei ienfâldige bash-skripts, hoewol, lykas jo witte, it better is om operators yn Golang te skriuwen. Fansels soe ynvestearje yn folsleine ûntwikkeling fan in operator foar elke sa'n lytse taak net effektyf wêze.
Operator yn 15 minuten
Litte wy nei in foarbyld sjen fan wat kin wurde automatisearre yn in Kubernetes-kluster en hoe't de shell-operator kin helpe. In foarbyld soe it folgjende wêze: in geheim replikearje om tagong te krijen ta it docker-register.
Pods dy't ôfbyldings brûke fan in privee register moatte yn har manifest in keppeling befetsje nei in geheim mei gegevens foar tagong ta it register. Dit geheim moat makke wurde yn elke nammeromte foardat jo pods meitsje. Dit kin mei de hân dien wurde, mar as wy dynamyske omjouwings ynstelle, dan sil de nammeromte foar ien applikaasje in soad wurde. En as der ek gjin 2-3 oanfragen binne... wurdt it tal geheimen hiel grut. En noch ien ding oer geheimen: ik wol de kaai feroarje om fan tiid ta tiid tagong te krijen ta it register. Úteinlik, hânmjittich operaasjes as oplossing folslein net effektyf - wy moatte it oanmeitsjen en bywurkjen fan geheimen automatisearje.
Ienfâldige automatisearring
Litte wy in shellskript skriuwe dat ien kear elke N sekonden rint en nammeromten kontrolearret op de oanwêzigens fan in geheim, en as der gjin geheim is, dan wurdt it makke. It foardiel fan dizze oplossing is dat it liket op in shell-skript yn cron - in klassike en begryplike oanpak foar elkenien. It neidiel is dat yn it ynterval tusken har lansearringen in nije nammeromte kin wurde oanmakke en in skoft sil it sûnder geheim bliuwe, wat sil liede ta flaters by it lansearjen fan pods.
Automatisearring mei shell-operator
Foar ús skript om goed te wurkjen, moat de klassike cron-lansearring wurde ferfongen troch in lansearring as in nammeromte wurdt tafoege: yn dit gefal kinne jo in geheim meitsje foardat jo it brûke. Litte wy sjen hoe't jo dit ymplementearje mei help fan shell-operator.
Litte wy earst nei it skript sjen. Skripten yn termen fan shell-operator wurde haken neamd. Elke heak doe't rinne mei in flagge --config ynformearret de shell-operator oer syn bindingen, d.w.s. op hokker eveneminten it moat wurde lansearre. Yn ús gefal sille wy brûke onKubernetesEvent:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
fi
It wurdt hjir beskreaun dat wy ynteressearre binne yn it tafoegjen fan eveneminten (add) objekten fan type namespace.
No moatte jo de koade tafoegje dy't sil wurde útfierd as it evenemint bart:
#!/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
Grut! It resultaat wie in lyts, moai skript. Om it te "werlibjen" binne d'r twa stappen oer: tariede de ôfbylding en lansearje it yn it kluster.
It tarieden fan in ôfbylding mei in heak
As jo nei it skript sjogge, kinne jo sjen dat de kommando's wurde brûkt kubectl и jq. Dit betsjut dat de ôfbylding de folgjende dingen moat hawwe: ús hook, in shell-operator dy't harkje nei eveneminten en de hook útfiere, en de kommando's dy't brûkt wurde troch de hook (kubectl en jq). Hub.docker.com hat al in klearmakke ôfbylding wêryn shell-operator, kubectl en jq binne ferpakt. Alles wat oerbliuwt is in ienfâldige heak ta te foegjen Dockerfile:
Litte wy nochris nei de heak sjen en dizze kear opskriuwe hokker aksjes en mei hokker objekten it útfiert yn it kluster:
abonnearret op nammeromte skepping eveneminten;
makket in geheim yn oare nammeromten as dejinge wêr't it lansearre wurdt.
It docht bliken dat de pod wêryn ús ôfbylding sil wurde lansearre tagongsrjochten moat hawwe om dizze aksjes te dwaan. Dit kin dien wurde troch jo eigen ServiceAccount oan te meitsjen. De tastimming moat dien wurde yn 'e foarm fan ClusterRole en ClusterRoleBinding, om't wy binne ynteressearre yn objekten út it hiele kluster.
De definitive beskriuwing yn YAML sil der sa útsjen:
Dat is alles: de shell-operator sil begjinne, abonnearje op eveneminten foar skepping fan nammeromte en de heak útfiere as it nedich is.
sa, in ienfâldich shell-skript feroare yn in echte operator foar Kubernetes en wurket as ûnderdiel fan in kluster. En dit alles sûnder it komplekse proses fan it ûntwikkeljen fan operators yn Golang:
D'r is in oare yllustraasje oer dizze saak ...
Wy sille har betsjutting yn mear detail iepenbierje yn ien fan 'e folgjende publikaasjes.
filtering
Tracking foarwerpen is goed, mar der is faak in ferlet om te reagearjen op feroarjen fan guon foarwerp eigenskippen, bygelyks, om it oantal replika's yn Deployment te feroarjen of om objektetiketten te feroarjen.
As in evenemint oankomt, ûntfangt de shell-operator it JSON-manifest fan it objekt. Wy kinne de eigenskippen selektearje dy't ús ynteressearje yn dizze JSON en de heak útfiere allinnich as se feroarje. Dêr is in fjild foar jqFilter, wêr't jo de jq-ekspresje moatte opjaan dy't tapast wurde sil op it JSON-manifest.
Bygelyks, om te reagearjen op feroarings yn labels foar Deployment-objekten, moatte jo it fjild filterje labels út it fjild metadata. De konfiguraasje sil sa wêze:
In lytse digresje: ja, shell-operator stipet draait crontab styl skripts. Mear details kinne fûn wurde yn dokumintaasje.
Om te ûnderskieden wêrom't de heak lansearre is, makket de shell-operator in tydlik bestân en jout it paad dernei troch yn in fariabele nei de heak BINDING_CONTEXT_TYPE. It bestân befettet in JSON-beskriuwing fan 'e reden foar it útfieren fan de heak. Bygelyks, elke 10 minuten sil de heak rinne mei de folgjende ynhâld:
De ynhâld fan 'e fjilden kin wurde begrepen út har nammen, en mear details kinne wurde lêzen yn dokumintaasje. In foarbyld fan it krijen fan in boarnenamme út in fjild resourceName it brûken fan jq is al werjûn yn in heak dy't geheimen replikearret:
jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH
Jo kinne oare fjilden op in fergelykbere manier krije.
Wat is folgjende?
Yn it projekt repository, yn /foarbylden mappen, Der binne foarbylden fan heakken dy't klear binne om te rinnen op in kluster. By it skriuwen fan jo eigen heakken kinne jo se as basis brûke.
D'r is stipe foar it sammeljen fan metriken mei Prometheus - de beskikbere metriken wurde beskreaun yn 'e seksje METRICS.
Lykas jo miskien riede, is de shell-operator skreaun yn Go en ferspraat ûnder in Open Source-lisinsje (Apache 2.0). Wy sille tankber wêze foar elke ûntwikkelingsbystân projekt op GitHub: en stjerren, en problemen, en pull fersiken.
Lifting de sluier fan geheimhâlding, wy sille ek ynformearje jo dat shell-operator is lyts diel fan ús systeem dat tafoegings ynstalleare yn it Kubernetes-kluster bywurke hâlde kin en ferskate automatyske aksjes útfiere. Lês mear oer dit systeem ferteld letterlik op moandei op HighLoad++ 2019 yn Sint Petersburg - wy sille ynkoarten de fideo en transkripsje fan dit rapport publisearje.
Wy hawwe in plan om de rest fan dit systeem te iepenjen: de addon-operator en ús kolleksje fan haken en modules. Trouwens, addon-operator is al beskikber op github, mar de dokumintaasje dêrfoar is noch ûnderweis. De frijlitting fan 'e kolleksje fan modules is pland foar de simmer.