Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

Blogissamme on jo ollut artikkeleita, joista puhutaan operaattoriominaisuudet Kubernetesissa ja miten kirjoita itse yksinkertainen operaattori. Tällä kertaa haluamme esitellä huomionne avoimen lähdekoodin ratkaisumme, joka vie operaattoreiden luomisen erittäin helpolle tasolle - tutustu kuorioperaattori!

Miksi?

Shell-operaattorin idea on melko yksinkertainen: tilaa tapahtumia Kubernetes-objekteista ja kun nämä tapahtumat vastaanotetaan, käynnistä ulkoinen ohjelma, joka antaa sille tietoa tapahtumasta:

Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

Tarve sille syntyi, kun klustereiden toiminnan aikana alkoi ilmaantua pieniä tehtäviä, jotka todella haluttiin automatisoida oikealla tavalla. Kaikki nämä pienet tehtävät ratkaistiin yksinkertaisilla bash-skripteillä, vaikka, kuten tiedät, on parempi kirjoittaa operaattorit Golangiin. On selvää, että investoiminen operaattorin täysimittaiseen kehittämiseen jokaista näin pientä tehtävää varten olisi tehotonta.

Operaattori 15 minuutissa

Katsotaanpa esimerkkiä siitä, mitä Kubernetes-klusterissa voidaan automatisoida ja miten shell-operaattori voi auttaa. Esimerkki olisi seuraava: salaisuuden replikointi Docker-rekisteriin pääsyä varten.

Yksityisen rekisterin kuvia käyttävien koteloiden luettelossa on oltava linkki salaisuuteen, joka sisältää tietoja rekisteriin pääsyä varten. Tämä salaisuus on luotava jokaiseen nimiavaruuteen ennen podien luomista. Tämä voidaan tehdä manuaalisesti, mutta jos määritämme dynaamisia ympäristöjä, yhden sovelluksen nimiavaruudesta tulee paljon. Ja jos ei myöskään ole 2-3 hakemusta... salaisuuksien määrästä tulee erittäin suuri. Ja vielä yksi asia salaisuuksista: Haluaisin vaihtaa avainta päästäkseni rekisteriin aika ajoin. Lopulta, manuaaliset toiminnot ratkaisuna täysin tehotonta — meidän on automatisoitava salaisuuksien luominen ja päivittäminen.

Yksinkertainen automaatio

Kirjoitetaan shell-skripti, joka suoritetaan kerran N:ssä sekunnissa ja tarkistaa nimiavaruuksista salaisuuden olemassaolon, ja jos salaisuutta ei ole, se luodaan. Tämän ratkaisun etuna on, että se näyttää shell-skriptiltä cronissa - klassinen ja kaikille ymmärrettävä lähestymistapa. Huono puoli on, että sen julkaisujen välissä voidaan luoda uusi nimiavaruus ja se pysyy jonkin aikaa ilman salaisuutta, mikä johtaa virheisiin podien käynnistämisessä.

Automaatio shell-operaattorilla

Jotta skriptimme toimisi oikein, klassinen cron-käynnistys on korvattava käynnistyksellä, kun nimiavaruus lisätään: tässä tapauksessa voit luoda salaisuuden ennen sen käyttöä. Katsotaanpa, kuinka tämä toteutetaan shell-operatorilla.

Katsotaanpa ensin käsikirjoitusta. Komentosarjoja kutsutaan komentotulkkioperaattoritermeillä kouksiksi. Jokainen koukku, kun juostaan ​​lipun kanssa --config ilmoittaa kuoren operaattorille sidoksistaan, ts. mitä tapahtumia se pitäisi käynnistää. Meidän tapauksessamme käytämme onKubernetesEvent:

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

Tässä on kuvattu, että olemme kiinnostuneita lisäämään tapahtumia (add) tyyppisiä esineitä namespace.

Nyt sinun on lisättävä koodi, joka suoritetaan, kun tapahtuma tapahtuu:

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

Loistava! Tuloksena oli pieni, kaunis käsikirjoitus. Sen elvyttämiseksi on kaksi vaihetta jäljellä: valmistele kuva ja käynnistä se klusterissa.

Kuvan valmistelu koukulla

Jos katsot komentosarjaa, näet, että komentoja käytetään kubectl и jq. Tämä tarkoittaa, että kuvassa on oltava seuraavat asiat: meidän koukku, shell-operaattori, joka tarkkailee tapahtumia ja suorittaa koukun, sekä koukun käyttämät komennot (kubectl ja jq). Hub.docker.com-sivustolla on jo valmis kuva, johon on pakattu shell-operator, kubectl ja jq. Jäljelle jää vain yksinkertainen koukku 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

Juokse klusterissa

Katsotaanpa koukkua uudelleen ja kirjoitetaan tällä kertaa, mitä toimia ja millä kohteilla se suorittaa klusterissa:

  1. tilaa nimitilan luontitapahtumia;
  2. luo salaisuuden muihin nimiavaruuksiin kuin siihen, jossa se käynnistetään.

Osoittautuu, että podilla, jossa kuvamme käynnistetään, on oltava oikeudet tehdä nämä toimet. Tämä voidaan tehdä luomalla oma ServiceAccount. Lupa on tehtävä muodossa ClusterRole ja ClusterRoleBinding, koska olemme kiinnostuneita koko klusterin esineistä.

Lopullinen kuvaus YAML:ssa näyttää suunnilleen tältä:

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

Voit käynnistää kootun kuvan yksinkertaisena käyttöönottona:

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

Mukavuussyistä luodaan erillinen nimiavaruus, jossa komentotulkkioperaattori käynnistetään ja luotuja luetteloita sovelletaan:

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

Siinä kaikki: shell-operaattori käynnistyy, tilaa nimitilan luontitapahtumat ja suorittaa koukun tarvittaessa.

Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

Näin ollen yksinkertainen shell-skripti muuttui todelliseksi operaattoriksi Kubernetesille ja toimii osana klusteria. Ja kaikki tämä ilman monimutkaista Golangin operaattoreiden kehittämisprosessia:

Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

Tästä aiheesta on toinenkin esimerkki...Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

Paljastamme sen merkityksen yksityiskohtaisemmin yhdessä seuraavista julkaisuista.

suodatus

Kohteiden jäljittäminen on hyvää, mutta siihen on usein reagoitava joidenkin objektien ominaisuuksien muuttaminen, esimerkiksi muuttaaksesi replikoiden määrää käyttöönotossa tai muuttaaksesi objektien tunnisteita.

Kun tapahtuma saapuu, komentotulkkioperaattori vastaanottaa objektin JSON-luettelon. Voimme valita tässä JSONissa meitä kiinnostavat ominaisuudet ja suorittaa koukun vain kun ne muuttuvat. Tätä varten on kenttä jqFilter, jossa sinun on määritettävä jq-lauseke, jota käytetään JSON-luetteloon.

Jos esimerkiksi haluat vastata käyttöönotto-objektien nimien muutoksiin, sinun on suodatettava kenttä labels pois kentältä metadata. Konfiguraatio tulee olemaan seuraava:

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

Tämä jqFilter-lauseke muuttaa käyttöönoton pitkän JSON-luettelon lyhyeksi JSON-tiedostoksi tunnisteilla:

Esittelyssä shell-operator: operaattoreiden luominen Kubernetesille on nyt helpompaa

shell-operator suorittaa koukun vain, kun tämä lyhyt JSON muuttuu, ja muiden ominaisuuksien muutokset ohitetaan.

Koukun käynnistyskonteksti

Hook-kokoonpanon avulla voit määrittää useita vaihtoehtoja tapahtumille - esimerkiksi 2 vaihtoehtoa tapahtumille Kubernetesista ja 2 aikataulua:

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

Pieni poikkeama: kyllä, shell-operaattorin tuet crontab-tyylisten komentosarjojen suorittaminen. Tarkemmat tiedot löytyvät osoitteesta dokumentointi.

Erottaakseen, miksi koukku käynnistettiin, shell-operaattori luo väliaikaisen tiedoston ja välittää polun siihen muuttujana koukkuun BINDING_CONTEXT_TYPE. Tiedosto sisältää JSON-kuvauksen koukun suorittamisen syystä. Esimerkiksi 10 minuutin välein koukku juoksee seuraavan sisällön kanssa:

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

... ja maanantaina se alkaa tällä:

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

varten onKubernetesEvent JSON-laukaisimia tulee lisää, koska se sisältää kuvauksen kohteesta:

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

Kenttien sisältö on ymmärrettävissä niiden nimistä ja tarkemmat tiedot ovat luettavissa dokumentointi. Esimerkki resurssin nimen saamisesta kentästä resourceName jq:n käyttö on jo esitetty koukussa, joka toistaa salaisuudet:

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

Voit saada muita kenttiä samalla tavalla.

Mitä seuraavaksi?

Projektivarastossa, sisään /esimerkit -hakemistot, on esimerkkejä koukuista, jotka ovat valmiita toimimaan klusterissa. Kun kirjoitat omia koukkujasi, voit käyttää niitä pohjana.

Mittareiden keräämiseen Prometheuksen avulla on olemassa tuki - käytettävissä olevat mittarit on kuvattu osiossa METRIKKA.

Kuten arvata saattaa, shell-operaattori on kirjoitettu Go-kielellä ja jaettu avoimen lähdekoodin lisenssillä (Apache 2.0). Olemme kiitollisia kaikesta kehitysavusta projekti GitHubissa: ja tähdet, ja ongelmat ja vetopyynnöt.

Salassapitoverhoa nostaen ilmoitamme myös, että shell-operaattori on pieni osa järjestelmäämme, joka voi pitää Kubernetes-klusteriin asennetut lisäosat ajan tasalla ja suorittaa erilaisia ​​automaattisia toimintoja. Lue lisää tästä järjestelmästä kertoi kirjaimellisesti maanantaina HighLoad++ 2019 -tapahtumassa Pietarissa - julkaisemme pian tämän raportin videon ja transkription.

Meillä on suunnitelma avata loput tästä järjestelmästä: lisäosien operaattori sekä koukku- ja moduulikokoelmamme. Muuten, addon-operaattori on jo saatavilla githubista, mutta sen dokumentaatio on vielä kesken. Moduulikokoelman julkaisu on suunniteltu kesällä.

Pysy kanavalla!

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti