Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

Dagoeneko gure blogean egon dira gai honi buruz hitz egiten duten artikuluak Kubernetes-en operadore-gaitasunak eta nola idatzi zuk zeuk operadore soil bat. Oraingo honetan, zure arreta aurkeztu nahi dizugu gure Open Source irtenbidea, operadoreen sorrera maila oso erraz batera eramaten duena - begiratu shell-operadore!

Zergatik?

Shell-operadore baten ideia nahiko erraza da: harpidetu Kubernetes objektuetako gertaeretara, eta gertaera hauek jasotzen direnean, abiarazi kanpoko programa bat, gertaerari buruzko informazioa emanez:

Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

Horren beharra sortu zen, klusterren funtzionamenduan, benetan modu egokian automatizatu nahi genituen zeregin txikiak agertzen hasi zirenean. Zeregin txiki hauek guztiak bash script sinpleak erabiliz konpondu ziren, nahiz eta, dakizuenez, hobe den operadoreak Golang-en idaztea. Jakina, zeregin txiki bakoitzerako operadore baten eskala osoko garapenean inbertitzea ez litzateke eraginkorra izango.

Eragilea 15 minututan

Ikus dezagun Kubernetes kluster batean automatiza daitekeenaren adibide bat eta shell-operadoreak nola lagun dezakeen. Adibide bat honako hau izango litzateke: sekretu bat errepikatzea docker erregistroan sartzeko.

Erregistro pribatu bateko irudiak erabiltzen dituzten podek beren manifestuan erregistroan sartzeko datuekin sekretu baterako esteka eduki behar dute. Sekretu hau izen-espazio bakoitzean sortu behar da lekak sortu aurretik. Hau eskuz egin daiteke, baina ingurune dinamikoak konfiguratzen baditugu, orduan aplikazio baten izen-espazioa asko bihurtuko da. Eta 2-3 aplikazio ere ez badira... sekretuen kopurua oso handia bihurtzen da. Eta sekretuei buruz beste gauza bat: gakoa aldatu nahiko nuke noizean behin erregistrora sartzeko. Azkenean, eskuzko eragiketak irtenbide gisa guztiz eraginkorra — sekretuak sortzea eta eguneratzea automatizatu behar dugu.

Automatizazio sinplea

Idatzi dezagun N segundoro behin exekutatzen den shell script bat eta izen-espazioak egiaztatzen dituen sekretu bat dagoen, eta sekreturik ez badago, orduan sortuko da. Irtenbide honen abantaila cron-en shell script baten itxura duela da - guztientzako ikuspegi klasiko eta ulergarria. Alde txarra da abiarazi arteko tartean izen-espazio berri bat sor daitekeela eta denbora pixka bat sekretu gabe geratuko dela, eta horrek akatsak ekarriko ditu pods abiarazteko.

Automatizazioa shell-operadorearekin

Gure script-a behar bezala funtziona dezan, cron-en abiarazte klasikoa abiarazte batekin ordezkatu behar da izen-espazio bat gehitzen denean: kasu honetan, sekretu bat sor dezakezu erabili aurretik. Ikus dezagun nola inplementatu hau shell-operator erabiliz.

Lehenik eta behin, ikus dezagun gidoia. Shell-operadore terminoetan scriptei hook deitzen zaie. Amu bakoitza bandera batekin exekutatzen denean --config shell-operadoreari bere loturen berri ematen dio, hau da. zein ekitalditan jarri behar den martxan. Gure kasuan erabiliko dugu onKubernetesEvent:

#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
  { "kind": "namespace",
    "event":["add"]
  }
]}
EOF
fi

Hemen deskribatzen da gertaerak gehitzea interesatzen zaigula (add) motako objektuak namespace.

Orain, gertaera gertatzen denean exekutatuko den kodea gehitu behar duzu:

#!/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

Bikaina! Emaitza gidoi txiki eta ederra izan zen. "Berpiztu" egiteko, bi urrats geratzen dira: irudia prestatu eta klusterean abiarazi.

Kako batekin irudi bat prestatzea

Scriptari erreparatuz gero, komandoak erabiltzen direla ikusiko duzu kubectl и jq. Horrek esan nahi du irudiak gauza hauek izan behar dituela: gure hook, gertaerak entzun eta amua exekutatuko duen shell-operadore bat eta amuak erabiltzen dituen komandoak (kubectl eta jq). Hub.docker.com-ek dagoeneko badu prest egindako irudi bat, zeinetan shell-operator, kubectl eta jq bilduta dauden. Kako soil bat gehitzea besterik ez da geratzen 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

Kluster batean korrika

Ikus dezagun berriro kakoari eta oraingoan idatzi zer ekintza eta zer objekturekin egiten duen klusterrean:

  1. izen-gunea sortzeko ekitaldietara harpidetzen da;
  2. sekretu bat sortzen du abiarazten den lekuetan ez diren izen-espazioetan.

Gertatzen da gure irudia abiaraziko den podak ekintza hauek egiteko baimenak izan behar dituela. Hau zure Zerbitzu-kontua sortuz egin daiteke. Baimena ClusterRole eta ClusterRoleBinding moduan egin behar da, izan ere kluster osoko objektuak interesatzen zaizkigu.

YAML-en azken deskribapena honelakoa izango da:

---
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

Muntatutako irudia Inplementazio sinple gisa abiarazi dezakezu:

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

Erosotasunerako, izen-eremu bereizi bat sortzen da non shell-operadorea abiaraziko den eta sortutako manifestuak aplikatuko diren:

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

Hori da guztia: shell-operadorea abiaraziko da, izen-espazioen sorkuntza-gertaeretara harpidetu eta amua exekutatuko da behar denean.

Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

Horrela, bada, shell script soil bat Kubernetesentzako benetako operadore bihurtu zen eta kluster baten parte gisa funtzionatzen du. Eta hori guztia Golang-en operadoreak garatzeko prozesu konplexurik gabe:

Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

Bada beste ilustrazio bat gai honi buruz...Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

Bere esanahia zehatzago azalduko dugu hurrengo argitalpenetako batean.

iragazte

Objektuen jarraipena ona da, baina askotan erreakzionatu beharra dago objektuen propietate batzuk aldatzea, adibidez, Deployment-en erreplika kopurua aldatzeko edo objektuen etiketak aldatzeko.

Gertaera bat iristen denean, shell-operadoreak objektuaren JSON manifestua jasotzen du. JSON honetan interesatzen zaizkigun propietateak hauta ditzakegu eta amua exekutatu bakarrik aldatzen direnean. Horretarako eremu bat dago jqFilter, non JSON manifestuari aplikatuko zaion jq adierazpena zehaztu behar duzun.

Adibidez, Deployment objektuen etiketen aldaketei erantzuteko, eremua iragazi behar duzu labels zelaitik kanpo metadata. Konfigurazioa honela izango da:

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

jqFilter adierazpen honek Deployment-en JSON manifestu luzea JSON labur bihurtzen du etiketak dituena:

Shell-operator aurkezten: Kubernetes-erako operadoreak sortzea errazagoa da

shell-operator-ek JSON labur hau aldatzen denean bakarrik exekutatuko du hook, eta beste propietateen aldaketak ez dira aintzat hartuko.

Hook abiarazteko testuingurua

Hook konfigurazioari esker, gertaeren hainbat aukera zehazten dituzu, adibidez, Kuberneteseko ekitaldietarako 2 aukera eta 2 ordutegi:

{"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"
]}

Digresio txiki bat: bai, shell-operadoreen euskarriak crontab estiloko scriptak exekutatzen. Xehetasun gehiago hemen aurki daitezke dokumentazioa.

Hook zergatik abiarazi den bereizteko, shell-operadoreak aldi baterako fitxategi bat sortzen du eta haren bidea aldagai batean pasatzen dio kakoari. BINDING_CONTEXT_TYPE. Fitxategiak amua exekutatzeko arrazoiaren JSON deskribapena dauka. Adibidez, 10 minuturo amua hurrengo edukiarekin abiaraziko da:

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

... eta astelehenean honekin hasiko da:

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

For onKubernetesEvent JSON abiarazle gehiago egongo dira, zeren objektuaren deskribapena dauka:

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

Eremuen edukia haien izenetatik uler daiteke, eta xehetasun gehiago irakur daitezke dokumentazioa. Eremu batetik baliabide-izen bat lortzeko adibide bat resourceName jq erabiliz sekretuak errepikatzen dituen kako batean erakutsi da jada:

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

Beste eremu batzuk antzera lor ditzakezu.

Zer da hurrengoa?

Proiektuaren biltegian, urtean /examples direktorioa, kluster batean exekutatzeko prest dauden kakoen adibideak daude. Zure kakoak idazterakoan, oinarri gisa erabil ditzakezu.

Prometheus erabiliz neurketak biltzeko laguntza dago; eskuragarri dauden neurketak atalean deskribatzen dira METRIKA.

Asma dezakezun bezala, shell-operadorea Go-n idatzita dago eta Iturburu Irekiko lizentzia baten pean banatzen da (Apache 2.0). Garapenerako edozein laguntza eskertuko dugu proiektua GitHub-en: eta izarrak, eta arazoak, eta tira eskaerak.

Sekretuaren beloa altxatuz, shell-operatzailea dela ere jakinaraziko dizugu txikia Kubernetes klusterrean instalatutako gehigarriak eguneratuta eduki ditzaketen gure sistemaren parte da eta hainbat ekintza automatiko egin ditzake. Irakurri gehiago sistema honi buruz kontatu literalki astelehenean HighLoad++ 2019 San Petersburgon - laster argitaratuko dugu txosten honen bideoa eta transkripzioa.

Gainontzeko sistema hau irekitzeko plana dugu: gehigarri-operatzailea eta gure kako eta moduluen bilduma. Bide batez, gehigarri-operadorea dagoeneko dago github-en eskuragarri, baina horretarako dokumentazioa bidean dago oraindik. Modulu bildumaren kaleratzea udarako aurreikusita dago.

Stay tuned!

PS

Irakurri ere gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria