Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

8 d'abril a la conferència Saint HighLoad++ 2019, dins de l'apartat “DevOps i Operacions”, es va fer un informe “Ampliant i complementant Kubernetes”, en la creació del qual van participar tres empleats de l'empresa Flant. En ell, parlem de nombroses situacions en les quals volíem ampliar i complementar les capacitats de Kubernetes, però per a les quals no hem trobat una solució ja feta i senzilla. Tenim les solucions necessàries en forma de projectes de codi obert, i aquest discurs també està dedicat a ells.

Per tradició, ens complau presentar vídeo del reportatge (50 minuts, molt més informatiu que l'article) i el resum principal en forma de text. Va!

Nucli i addicions en K8s

Kubernetes està canviant la indústria i els enfocaments de l'administració que s'han establert des de fa temps:

  • Gràcies a ell abstraccions, ja no operem amb conceptes com configurar una configuració o executar una comanda (Chef, Ansible...), sinó que utilitzem l'agrupació de contenidors, serveis, etc.
  • Podem preparar aplicacions sense pensar en els matisos del lloc específic, sobre el qual es llançarà: bare metal, núvol d'un dels proveïdors, etc.
  • Amb K8s mai has estat més accessible millors pràctiques sobre l'organització de la infraestructura: tècniques d'escalat, autocuració, tolerància a fallades, etc.

Tanmateix, per descomptat, tot no és tan fluid: Kubernetes també va portar els seus nous reptes.

Kubernetes no és una combinació que resol tots els problemes de tots els usuaris. El nucli Kubernetes només és responsable d'un conjunt de les funcions mínimes necessàries que hi ha presents cada clúster:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

El nucli de Kubernetes defineix un conjunt bàsic de primitives per agrupar contenidors, gestionar el trànsit, etc. N'hem parlat amb més detall a informe de fa 2 anys.

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

D'altra banda, K8s ofereix grans oportunitats per ampliar les funcions disponibles, que ajuden a tancar-ne d'altres - específic - necessitats dels usuaris. Les addicions a Kubernetes són responsabilitat dels administradors del clúster, que han d'instal·lar i configurar tot el necessari perquè el seu clúster "en la forma adequada" [per resoldre els seus problemes específics]. Quin tipus d'addicions són aquestes? Vegem-ne alguns exemples.

Exemples de complements

Un cop instal·lat Kubernetes, ens pot sorprendre que la xarxa tan necessària per a la interacció de pods tant dins d'un node com entre nodes no funcioni per si sola. El nucli de Kubernetes no garanteix les connexions necessàries; en canvi, determina la xarxa la interfície (CNI) per a complements de tercers. Hem d'instal·lar un d'aquests complements, que serà el responsable de la configuració de la xarxa.

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Un exemple proper són les solucions d'emmagatzematge de dades (disc local, dispositiu de bloqueig de xarxa, Ceph...). Inicialment estaven al nucli, però amb l'adveniment CSI la situació canvia a una cosa semblant a la ja descrita: la interfície es troba a Kubernetes i la seva implementació és en mòduls de tercers.

Altres exemples inclouen:

  • Ingrés-controladors (vegeu la seva ressenya a el nostre article recent).
  • Cert-Manager:

    Ampliar i complementar Kubernetes (visió general i informe de vídeo)

  • Operadors és tota una classe de complements (que inclou l'esmentat gestor de certificats), defineixen primitives i controladors. La lògica del seu treball només està limitada per la nostra imaginació i ens permet convertir components d'infraestructura ja fets (per exemple, un SGBD) en primitius, amb els quals és molt més fàcil treballar (que amb un conjunt de contenidors i la seva configuració). S'ha escrit un gran nombre d'operadors, encara que molts d'ells encara no estiguin preparats per a la producció, només és qüestió de temps:

    Ampliar i complementar Kubernetes (visió general i informe de vídeo)

  • Mètriques - una altra il·lustració de com Kubernetes va separar la interfície (API Metrics) de la implementació (complements de tercers com l'adaptador Prometheus, l'agent de clúster Datadog...).
  • Per seguiment i estadístiques, on a la pràctica no només calen Prometeu i Grafana, però també kube-state-metrics, node-exporter, etc.

I aquesta no és una llista completa d'addicions... Per exemple, a l'empresa Flant que instal·lem actualment 29 incorporacions (tots els quals creen un total de 249 objectes Kubernetes). En poques paraules, no podem veure la vida d'un clúster sense addicions.

Automatització

Els operadors estan dissenyats per automatitzar les operacions rutinàries que ens trobem cada dia. Aquests són exemples de la vida real per als quals escriure un operador seria una solució excel·lent:

  1. Hi ha un registre privat (és a dir, que requereix un inici de sessió) amb imatges per a l'aplicació. Se suposa que a cada pod se li assigna un secret especial que permet l'autenticació al registre. La nostra tasca és assegurar-nos que aquest secret es trobi a l'espai de noms perquè els pods puguin descarregar imatges. Hi pot haver moltes aplicacions (cadascuna de les quals necessita un secret) i és útil actualitzar els secrets periòdicament, de manera que s'elimina l'opció d'exposar secrets a mà. Aquí és on l'operador ve al rescat: creem un controlador que esperarà que aparegui l'espai de noms i, en funció d'aquest esdeveniment, afegirà un secret a l'espai de noms.
  2. Per defecte, l'accés des de pods a Internet està prohibit. Però de vegades pot ser necessari: és lògic que el mecanisme de permís d'accés funcioni de manera senzilla, sense requerir habilitats específiques, per exemple, per la presència d'una determinada etiqueta a l'espai de noms. Com ens pot ajudar l'operador aquí? Es crea un controlador que espera que l'etiqueta aparegui a l'espai de noms i afegeix la política adequada per a l'accés a Internet.
  3. Una situació semblant: suposem que hem d'afegir un cert contaminar, si té una etiqueta semblant (amb algun tipus de prefix). Les accions amb l'operador són evidents...

En qualsevol clúster, les tasques rutinàries s'han de resoldre, i correctament això es pot fer mitjançant operadors.

Resumint totes les històries descrites, vam arribar a la conclusió que per treballar còmode a Kubernetes que necessiteu: A) instal·lar complements, b) desenvolupar operadors (per resoldre tasques administratives quotidianes).

Com escriure una declaració per a Kubernetes?

En general, l'esquema és senzill:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

... però després resulta que:

  • L'API de Kubernetes és una cosa no trivial que necessita molt de temps per dominar-la;
  • La programació tampoc és per a tothom (el llenguatge Go es va triar com a llenguatge preferit perquè hi ha un marc especial per a això: SDK de l'operador);
  • La situació és similar amb el propi marc.

El resultat final: per escriure un controlador (operador) ha de gastar recursos importants per estudiar material. Això es justificaria per als operadors "grans", per exemple, per al SGBD MySQL. Però si recordem els exemples descrits anteriorment (desvelar secrets, accedir a pods a Internet...), que també volem fer correctament, aleshores entendrem que l'esforç invertit superarà el resultat que necessitem ara:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

En general, sorgeix un dilema: gastar molts recursos i trobar l'eina adequada per escriure declaracions, o fer-ho a l'antiga (però ràpidament). Per solucionar-ho, per trobar un compromís entre aquests extrems, vam crear el nostre propi projecte: operador de shell (vegeu també el seu anunci recent al hub).

Operador de Shell

Com treballa? El clúster té un pod que conté un binari Go amb un operador de shell. Al seu costat hi ha un conjunt de ganxos (més detalls sobre ells - vegeu a continuació). El propi operador d'intèrpret d'ordres subscriu a certs esdeveniments a l'API de Kubernetes, quan es produeixi el qual llança els ganxos corresponents.

Com sap l'operador de l'intèrpret d'ordres quins ganxos ha de cridar a quins esdeveniments? Aquesta informació es transmet a l'operador de l'intèrpret mitjançant els mateixos ganxos, i ho fan de manera molt senzilla.

Un ganxo és un script Bash o qualsevol altre fitxer executable que accepti un sol argument --config i respon amb JSON. Aquest últim determina quins objectes li interessen i a quins esdeveniments (per a aquests objectes) s'ha de respondre:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Il·lustraré la implementació a l'operador de shell d'un dels nostres exemples: descomposició de secrets per accedir a un registre privat amb imatges d'aplicacions. Consta de dues etapes.

Pràctica: 1. Escriure un ganxo

En primer lloc, en el ganxo que processarem --config, indicant que ens interessen els espais de noms, i concretament, el moment de la seva creació:

[[ $1 == "--config" ]] ; then
  cat << EOF
{
  "onKubernetesEvent": [
    {
      "kind": "namespace",
      "event": ["add"]
    }
  ]
}
EOF
…

Com seria la lògica? També bastant senzill:

…
else
  createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
  kubectl create -n ${createdNamespace} -f - << EOF
Kind: Secret
...
EOF
fi

El primer pas és esbrinar quin espai de noms es va crear i el segon és crear-lo amb kubectl secret per a aquest espai de noms.

Pràctica: 2. Muntatge de la imatge

Tot el que queda és passar el ganxo creat a l'operador de l'intèrpret d'ordres: com fer-ho? L'operador d'intèrpret d'ordres en si ve com una imatge de Docker, de manera que la nostra tasca és afegir el ganxo a un directori especial d'aquesta imatge:

FROM flant/shell-operator:v1.0.0-beta.1
ADD my-handler.sh /hooks

Només queda muntar-lo i empènyer-lo:

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

El toc final és desplegar la imatge al clúster. Per fer-ho, escrivim Desplegament:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1 # 1
      serviceAccountName: my-operator              # 2

Hi ha dos punts als quals cal prestar atenció:

  1. indicació de la imatge de nova creació;
  2. Aquest és un component del sistema que (com a mínim) necessita drets per subscriure's als esdeveniments a Kubernetes i per assignar secrets als espais de noms, de manera que creem un compte de servei (i un conjunt de regles) per al ganxo.

Resultat: hem resolt el nostre problema familiars per a Kubernetes d'una manera que creï un operador per descompondre secrets.

Altres funcions de l'operador d'intèrpret d'ordres

Per limitar els objectes del tipus escollit amb els quals funcionarà el ganxo, es poden filtrar, seleccionant segons determinades etiquetes (o utilitzant matchExpressions):

"onKubernetesEvent": [
  {
    "selector": {
      "matchLabels": {
        "foo": "bar",
       },
       "matchExpressions": [
         {
           "key": "allow",
           "operation": "In",
           "values": ["wan", "warehouse"],
         },
       ],
     }
     …
  }
]

Proporcionat mecanisme de deduplicació, que, utilitzant un filtre jq, us permet convertir objectes JSON grans en petits, on només queden aquells paràmetres que volem supervisar per veure si hi ha canvis.

Quan es crida un ganxo, l'operador de l'intèrpret el passa dades de l'objecte, que es pot utilitzar per a qualsevol necessitat.

Els esdeveniments que desencadenen ganxos no es limiten als esdeveniments de Kubernetes: l'operador de shell proporciona suport per cridant ganxos pel temps (similar a crontab en un programador tradicional), així com un esdeveniment especial A l'inici. Tots aquests esdeveniments es poden combinar i assignar al mateix ganxo.

I dues característiques més de l'operador de shell:

  1. Funciona de manera asíncrona. Com que es va rebre un esdeveniment de Kubernetes (com ara un objecte que s'està creant), es podrien haver produït altres esdeveniments (com ara l'eliminació del mateix objecte) al clúster i els ganxos han de tenir-ne en compte. Si el ganxo s'ha executat amb un error, ho serà per defecte tornar a trucar fins a la finalització correcta (aquest comportament es pot canviar).
  2. S'exporta mètriques per a Prometheus, amb el qual podeu entendre si l'operador d'intèrpret d'ordres funciona, esbrineu el nombre d'errors per a cada ganxo i la mida actual de la cua.

Per resumir aquesta part de l'informe:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Instal·lació de complements

Per treballar còmodament amb Kubernetes, també es va esmentar la necessitat d'instal·lar complements. Us ho explicaré fent servir l'exemple del camí de la nostra empresa cap a com ho fem ara.

Vam començar a treballar amb Kubernetes amb diversos clústers, l'única incorporació dels quals va ser Ingress. S'havia d'instal·lar de manera diferent a cada clúster i vam fer diverses configuracions YAML per a diferents entorns: metall nu, AWS...

Com que hi havia més clústers, hi havia més configuracions. A més, vam millorar aquestes configuracions, com a resultat de la qual cosa es van tornar força heterogènies:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Per posar-ho tot en ordre, vam començar amb un guió (install-ingress.sh), que va prendre com a argument el tipus de clúster al qual desplegarem, va generar la configuració YAML necessària i la va desplegar a Kubernetes.

En resum, el nostre camí posterior i el raonament associat amb ell van ser els següents:

  • per treballar amb configuracions YAML, cal un motor de plantilles (en les primeres etapes això és senzill);
  • amb l'augment del nombre de clústers, va arribar la necessitat d'actualització automàtica (la solució més primerenca va ser posar l'script a Git, actualitzar-lo amb cron i executar-lo);
  • es necessitava un script similar per a Prometeu (install-prometheus.sh), però, destaca pel fet que requereix moltes més dades d'entrada, així com el seu emmagatzematge (en bona manera - centralitzat i en un clúster), i algunes dades (contrasenyes) es podrien generar automàticament:

    Ampliar i complementar Kubernetes (visió general i informe de vídeo)

  • el risc de desplegar alguna cosa malament a un nombre creixent de clústers creixia constantment, així que ens vam adonar que els instal·ladors (és a dir, dos scripts: per a Ingress i Prometheus) calia la posada en escena (diverses branques a Git, diversos crons per actualitzar-los en els corresponents: clústers estables o de prova);
  • с kubectl apply s'ha tornat difícil de treballar perquè no és declaratiu i només pot crear objectes, però no prendre decisions sobre el seu estat/eliminar-los;
  • Ens faltaven algunes funcions que no havíem implementat en aquell moment:
    • control total sobre el resultat de les actualitzacions del clúster,
    • determinació automàtica d'alguns paràmetres (entrada per a scripts d'instal·lació) a partir de les dades que es poden obtenir del clúster (descobriment),
    • el seu desenvolupament lògic en forma de descobriment continu.

Tota aquesta experiència acumulada la vam implementar en el marc del nostre altre projecte: operador-complement.

Operador de complements

Es basa en l'operador de shell ja esmentat. Tot el sistema té aquest aspecte:

S'afegeix el següent als ganxos de l'operador de shell:

  • emmagatzematge de valors,
  • Quadre de timó,
  • component que supervisa la botiga de valors i - en cas de qualsevol canvi - demana a Helm que torni a tirar el gràfic.

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Així, podem reaccionar davant un esdeveniment a Kubernetes, llançar un ganxo i des d'aquest ganxo podem fer canvis a l'emmagatzematge, després dels quals es tornarà a descarregar el gràfic. En el diagrama resultant, separem el conjunt de ganxos i el gràfic en un component, que anomenem mòdul:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Hi pot haver molts mòduls, i a ells hi afegim hooks globals, una botiga de valors globals i un component que supervisa aquesta botiga global.

Ara, quan passa alguna cosa a Kubernetes, podem reaccionar-hi amb un ganxo global i canviar alguna cosa a la botiga global. Aquest canvi es notarà i farà que es desplegaran tots els mòduls del clúster:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

Aquest esquema compleix tots els requisits per instal·lar complements que s'han indicat anteriorment:

  • Helm és responsable de la plantilla i la declaració.
  • El problema de l'actualització automàtica es va resoldre mitjançant un ganxo global, que va al registre segons una programació i, si hi veu una nova imatge del sistema, la desplega (és a dir, "el mateix").
  • L'emmagatzematge de la configuració al clúster s'implementa amb ConfigMap, que conté les dades primàries dels emmagatzematges (a l'inici es carreguen als emmagatzematges).
  • Els problemes amb la generació de contrasenyes, el descobriment i el descobriment continu es van resoldre mitjançant ganxos.
  • La posada en escena s'aconsegueix gràcies a les etiquetes, que Docker admet des de la caixa.
  • El resultat es controla mitjançant mètriques amb les quals podem entendre l'estat.

Tot aquest sistema s'implementa en forma d'un únic binari a Go, que s'anomena addon-operator. Això fa que el diagrama sembli més senzill:

Ampliar i complementar Kubernetes (visió general i informe de vídeo)

El component principal d'aquest diagrama és un conjunt de mòduls (ressaltat en gris a continuació). Ara podem escriure un mòdul per al complement necessari amb una mica d'esforç i assegurar-nos que s'instal·larà a cada clúster, s'actualitzarà i respondrà als esdeveniments que necessiti al clúster.

Usos "Plant". operador-complement en més de 70 clústers de Kubernetes. Estat actual - versió alfa. Ara estem preparant documentació per llançar la beta, però de moment al repositori exemples disponibles, sobre la base del qual podeu crear el vostre propi complement.

On puc obtenir els mòduls per a l'operador de complements? La publicació de la nostra biblioteca és la següent etapa per a nosaltres; tenim previst fer-ho a l'estiu.

Vídeos i diapositives

Vídeo de l'actuació (~50 minuts):

Presentació de l'informe:

PS

Altres reportatges al nostre blog:

També us poden interessar les següents publicacions:

Font: www.habr.com

Afegeix comentari