Înainte să ne scufundăm în Manager pachet Helm, Voi explica câteva concepte cheie pentru implementarea oricărei aplicații oriunde. Vă voi oferi și o scurtă introducere la Terminologia Kubernetes.

Ce este Kubernetes?

Kubernetes (K8s) este un sistem open-source pentru automatizarea implementării, scalării și gestionării aplicațiilor containerizate
kubernetes.io

Acum s-ar putea să vă întrebați: „Ei bine, ce înseamnă asta?”

Kubernetes este în esență un set foarte frumos de API-uri pentru implementarea, gestionarea și scalarea aplicațiilor.

Aplicațiile sunt împachetate cu Docker, iar apoi logica în jurul implementării aplicației este exprimată folosind șabloanele Helm. Șabloanele în sine sunt instrucțiuni care sunt apoi rulate folosind API-ul Kubernetes.

Sunt o tonă de pachete Helm deja creat pentru a avea grijă de nevoile dvs. de implementare a aplicației!

Îmi place să mă gândesc la Kubernetes + Helm ca la un ghișeu unic pentru aplicația mea de care are nevoie DevOps.

Fun Fact Time!

Întregul ecosistem de containere, inclusiv Docker, are o temă nautică foarte distractivă. Docker are balene, Kubernetes are păstăi (de balene), iar logo-ul său arată ca porțiunea de conducere a unei nave, iar Helm este cârma unei nave.

Nu sunt drăguți?

O Introducere in Managerul de pachete Helm pentru Kubernetes
https://hub.docker.com/_/swarm

Implementarea unei aplicații pe Kubernetes

În primul rând, indiferent de locul în care implementați o aplicație, vor exista unele lucruri care rămân aceleași oriunde, și vreau să spun oriunde! 😉 Fie că implementați pe laptopul dvs., un server la distanță, o instanță AWS EC2, sisteme de calcul de înaltă performanță sau Kubernetes, conceptele de bază nu se modifică.

Mă gândesc la aproape totul, la conceptele tehnologice în special, ca la o serie de straturi. Odată ce ați înțeles care sunt aceste straturi fundamentale, puteți pregăti.

Straturi de aplicație

Acestea sunt:

General Kubernetes
Strat de date Revendicări din PVC sau volum persistent
Strat de aplicație Păstăi
Servicii SVC

Să le luăm pe rând.

Revendicări privind stratul de date / volum persistent (PVC)

Este drăguț și direct. Când trebuie să persistați datele, le păstrați într-un sistem de fișiere. Acesta poate fi stocare locală sau un fel de sistem de fișiere în rețea (NFS). Dacă utilizați o bază de date, baza de date persistă, de asemenea, într-un sistem de fișiere.

Aplicație Layer / Pods

Stratul de aplicație este ceea ce ne gândim de obicei într-o implementare. Este partea noastră apt-get install, npm run sau docker run. O aplicație poate fi un server web NGINX, o aplicație Python sau Node.js sau o aplicație Spark pentru a numi câteva.

Aplicațiile sunt fie Kubernetes Implementări sau Set de stare, în funcție de faptul dacă persistă sau nu datele (sau au o stare).

O bază de date MySQL ar fi un exemplu de Starea de stat cerere. Trebuie să țină evidența informațiilor despre sine.

Un server NGINX ar fi o implementare Kubernetes, deoarece nu trebuie să țină evidența niciunei informații despre sine – este Fara stare.

Servicii Layer / SVC

Stratul de servicii este locul în care ne expunem Cerere către lumea exterioară. Acest lucru se realizează, în general, spunând „Hei, am o aplicație care rulează pe acest port”. S-ar putea să le fi executat direct sau să fi făcut ceva de genul unui proxy pass în NGINX sau Apache.

Straturi de fiabilitate a site-ului

Fiabilitatea site-ului este capacitatea noastră de a spune cu încredere că aplicația noastră funcționează, funcționează și va fi probabil stai sus și aleargă!

Pentru a fi real, vrem ca un API să facă în esență acest lucru. ?

XKCD – Hard Reboot

XKCD Hard Reboot

General Kubernetes
Monitorizarea metrics-server
Scalare (sau echilibrare a sarcinii) Autoscaler pentru pod orizontal (HPA)
Reguli de service Specificațiile containerului

Monitorizare Layer / Metrics Server

Stratul de monitorizare răspunde la întrebarea „Cum merge aplicația noastră”? În mod ideal, ar răspunde la întrebări precum „Cât de mult CPU mai rămâne pe acel aparat?” și „Nu mai avem memoria”?

Stratul de scalare / HPA

Ați avut vreodată o aplicație care a funcționat excelent până când prea mulți oameni au început să o folosească simultan? Veți avea grijă de acest lucru scalând instanțele aplicației dvs. în sus sau în jos.

Cu aplicațiile web, veți vedea adesea și termenul de echilibrare a sarcinii. Această funcționalitate este încorporată în mulți manageri de proces și servere https, cum ar fi PM2 și Gunicorn.

În Kubernetes, realizați acest lucru cu un Autoscaler Pod Horizontal, sau HPA, pe care îl dați reguli specifice pentru cum să scăriți în sus sau în jos.

Stratul de reguli de service

Ați dorit vreodată să automatizați când / cum ar trebui să repornească aplicația dvs.? Poate doriți să repornească de 3 ori și apoi să renunțe. Sau poate doriți să repornească, dar nu imediat.

Dă-i ceva timp! De asemenea, este posibil să doriți o măsură obiectivă pentru a testa dacă aplicația dvs. funcționează sau nu.

Implementarea aplicațiilor pe Kubernetes

Aplicațiile Kubernetes pot fi implementate fie prin CLI, fie scriind șabloane YAML care descriu diferitele straturi PVC, Pod (indiferent dacă sunt implementări sau seturi de stare) și straturi Service (SVC).

Managerul de pachete Helm

Helm este cel mai bun mod de a găsi, partaja și utiliza software-ul conceput pentru Kubernetes.
https://helm.sh/

Managerul de pachete Helm ne permite să conectăm implementări complexe Kubernetes într-un singur pachet, care poate fi instalat cu o singură comandă.

Helm folosește un limbaj de șablonare peste definițiile Kubernetes YAML pentru a permite mai multă versatilitate implementărilor noastre.

Probabil cel mai important punct de reținut cu Helm este că a fost larg acceptat de comunitate. Aceasta înseamnă că există o mulțime de resurse pentru utilizarea Helm, pentru a începe, și, de asemenea, o mulțime de diagrame preconfigurate Helm!

Este foarte rar pentru mine să trebuiască vreodată să creez un pachet Helm complet de la zero. Aproape întotdeauna pot găsi un bun punct de plecare dintr-unul sau mai multe dintre Diagramele cârmei care sunt deja disponibile.

Implementați NGINX pe Kubernetes

În primul rând, să vorbim despre o implementare de bază NGINX fără Helm.

După cum puteți vedea, există o mulțime de lucruri de urmărit și probabil că nu am fi tastat acest lucru manual. Aici intervine managerul de pachete Helm, dar este bine să aruncăm o privire pentru a afla ce se întâmplă mai întâi! 😉

# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: nginx
    helm.sh/chart: nginx-6.0.1
    app.kubernetes.io/instance: nginx
    app.kubernetes.io/managed-by: Helm
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
      app.kubernetes.io/instance: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
        helm.sh/chart: nginx-6.0.1
        app.kubernetes.io/instance: nginx
        app.kubernetes.io/managed-by: Helm
    spec:      
      containers:
        - name: nginx
          image: docker.io/bitnami/nginx:1.19.0-debian-10-r2
          imagePullPolicy: "IfNotPresent"
          ports:
            - name: http
              containerPort: 8080
            
          livenessProbe:
            failureThreshold: 6
            initialDelaySeconds: 30
            tcpSocket:
              port: http
            timeoutSeconds: 5
          readinessProbe:
            initialDelaySeconds: 5
            periodSeconds: 5
            tcpSocket:
              port: http
            timeoutSeconds: 3
Definiția Kubernetes Deployment Pod pentru NGINX

Acum să descompunem diferitele părți ale definiției de implementare Kubernetes.

Metadate

Vreau să ating foarte scurt pe labels. Doar pe scurt, pentru că sunt șanse să fiți bine cu valorile implicite și să nu aveți nevoie să le atingeți.

Unul dintre obiectivele Kubernetes este acela de a abstra serverul fizic real. Nu ar trebui obișnuit trebuie să vă pese dacă aplicația dvs. rulează node1 sau node2. Bineînțeles că la un moment dat îți pasă, iar apoi vei începe să intri în etichete.

Până atunci, nu vă faceți griji cu privire la ele și rămâneți doar cu valorile implicite.

Containere

Aceasta este partea aplicației care va fi cea mai relevantă pentru dvs. atunci când implementați aplicații. Trebuie să vă definiți containerele.

Un singur Deployment Pod poate avea multe containere. Acel container are, cel puțin un name, A repo, și a tag:

      containers:
        - name: nginx
          #image:  "repo:tag"
          image: docker.io/bitnami/nginx:1.19.0-debian-10-r2
Definiția containerului pentru a rula aplicația noastră

Odată ce aveți baza, trebuie să definiți porturile care vor fi preluate de serviciu. Vedeți această separare a preocupărilor ?:

          ports:
            - name: http
              containerPort: 8080
Porturile aplicației vor fi expuse ulterior ca servicii

Regulile aplicației

Apoi, la un moment dat, vrem să știm dacă aplicația noastră rulează. Putem chiar determina exact unde se află în ciclul său de viață cu diferitele cârlige:

         livenessProbe:
            failureThreshold: 6
            initialDelaySeconds: 30
            tcpSocket:
              # This corresponds to the ports[0].name
              port: http
            timeoutSeconds: 5
          readinessProbe:
            initialDelaySeconds: 5
            periodSeconds: 5
            # This corresponds to the ports[0].name
            tcpSocket:
              port: http
            timeoutSeconds: 3
Reguli de service

Numele

Acesta este mai mult un concept general, dar vreau să subliniez că numirea lucrurilor este foarte importantă în ecosistemul Kubernetes. Observați că am dat-o pe a noastră container și port A name. Mai târziu, când trebuie să ne referim la ele, îl folosim name.

Implementați NGINX pe Kubernetes cu o diagramă Helm

Managerul de pachete Helm creează o serie de șabloane care pot fi modificate prin Helm CLI. Fiecare dintre aceste șabloane corespunde unuia dintre tipurile noastre Kubernetes despre care am discutat mai devreme.

Iată un exemplu de bitnami / nginx diagrama cârmei:

O Introducere in Managerul de pachete Helm pentru Kubernetes
Șabloane pentru diagrame Bitnami / NGINX

Iată același bloc cu limbajul de șablonare Helm. Din motive de scurtă durată, am omis unele părți ale șablonului. Dacă doriți să vedeți totul, puteți arunca o privire în el repo GitHub.

(Aceasta este în scop demonstrativ și nu este o diagramă complet funcțională. Nu folosiți aceasta. Prindeți în schimb diagrama actuală.)

# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "nginx.fullname" . }}
  labels: {{- include "nginx.labels" . | nindent 4 }}
spec:
  selector:
    matchLabels: {{- include "nginx.matchLabels" . | nindent 6 }}
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      labels: {{- include "nginx.labels" . | nindent 8 }}
      # Omitted the annotation labels!
    spec:
      containers:
        - name: nginx
          image: {{ template "nginx.image" . }}
          imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
          ports:
            - name: http
              containerPort: {{ .Values.containerPort }}
            {{ if .Values.containerTlsPort }}
            - name: https
              containerPort: {{ .Values.containerTlsPort }}
            {{ end }}
          {{- if .Values.livenessProbe }}
          livenessProbe: {{- toYaml .Values.livenessProbe | nindent 12 }}
          {{- end }}
          {{- if .Values.readinessProbe }}
          readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }}
          {{- end }}
          {{- if .Values.resources }}
          resources: {{- toYaml .Values.resources | nindent 12 }}
          {{- end }}
Șablon de implementare Helm din graficul bitnami / nginx

De unde vin valorile șablonului de cârmă?

Acum, asta îmi place foarte mult la Helm. Valorile expuse în șablon provin dintr-unul din cele două locuri.

Funcții șablonate

Ele provin din șablonul în sine, așa cum se arată aici.

{{ template "nginx.fullname" . }}

Putem constata că acest lucru este definit în templates/_helpers.tpl, care este un mod de a obține funcții mai complexe pe care le-am putea obține doar cu un yaml fişier.

# templates/_helpers.tpl
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
# Here is the nginx.fullname
{{- define "nginx.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
Funcții modelate în Diagrame Helm

Valori expuse în Values.yaml

Aceasta este de fapt o caracteristică foarte îngrijită și ceea ce face Helm atât de puternic și configurabil.

Fiecare diagramă Helm vine împreună cu un values.yaml. Puteți pune orice doriți în values.yaml, apoi folosiți-l în toată diagrama dvs. Helm și este expus prin CLI!

## Bitnami NGINX image version
## ref: https://hub.docker.com/r/bitnami/nginx/tags/
##
image:
  registry: docker.io
  repository: bitnami/nginx
  tag: 1.19.1-debian-10-r0
  ## Specify a imagePullPolicy
  ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
  ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
  ##
  pullPolicy: IfNotPresent
Valorile expuse ale graficului Helm în valori.yaml

Apoi vedem acest lucru în șabloanele noastre ca:

# templates/deployment.yaml 

# ...
      containers:
        - name: nginx
          image: {{ template "nginx.image" . }}
          imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
Câteva magii șablon Helm!

Totul în values.yaml poate fi, de asemenea, modificat prin Helm CLI:

helm upgrade --install nginx bitnami/nginx 
	--set image.tag="my-new-tag"
Puterile cosmice asupra graficului cârmei dvs. cu Helm CLI și valorile.yaml

Ar reda apoi containers[0].image la fel de image: docker.io/bitnami/nginx:my-new-tag

Învelire

Asta e! Sper că ați aflat puțin despre Kubernetes și despre managerul de pachete Helm. Sperăm că nu este la fel de înfricoșător ca odinioară.