This is an old revision of the document!


Laboratorul 06 - Lucrul cu fișiere YAML în Kubernetes

Intro

In laboratorul trecut am vazut cum putem deploya o aplicatie distribuita sub forma Pod-uri de kubernetes, folosind comenzi de kubectl. Rularea comenzilor manual este primul pas pentru invatare, insa nu este recomandat la nivel de productie. Pentru productie, precum si in cazul Docker Swarm, este indicata folosirea configuratiilor declarative.

Kubernetes ofera suport pentru rularea configuratiilor declarative de tip .yaml. In acest laborator vom explora cum este posibil.

O alta modalitate, mai noua, de deploy a aplicatiilor este Helm, care este un package manager pentru Kubernetes (precum NPM pentru NodeJS)

Generarea de fișiere YAML

Fisierele YAML pot fi scrise de la 0, sau pot fi generate prin rularea uscata a pod-urilor.

#Exemplu oficial de fisier YAML
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    run: nginx
    whatever: dude
spec:
 containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Pentru a genera fișiere YAML plecand de la o comanda imperativa putem folosi flag-urile –dry-run=client -o yaml. Exemplu: kubectl run nginx - -image=nginx - -dry-run=client -o yaml

Orice fișier YAML are 4 componente importante:

  • apiVersion - versiunea de comenzi folosita (asemanator cu version din docker compose/docker swarm)

apiVersion difera in functie de kind (e.g.: in cazul deployment-ului este apps/v1, in cazul pod-ului este v1

  • kind - tipul de obiect (e.g.: Pod, Deployment, etc…)
  • metadata - informatii aditionale atasate unui obiect (e.g.: name, labels)
  • spec - continutul obiectului (asemanator cu ce se scrie in directiva service din docker compose/docker swarm)

Pentru a face deploy la unul (sau mai multe) obiecte dintr-un fisier YAML folosim următoarea comandă: kubectl apply -f myfile.yaml

Obiectul va avea tipul definit in YAML (de exemplu, deployment)

Se pot folosi si comenzile kubectl create, kubectl upate, kubectl delete, dar este indicat sa folositi direct kubectl apply, care combina create, replace si delete. Aceasta reprezinta cel mai avansat model de aplicare a unei configuratii declarative.

kubectl apply se poate da si pe un folder care contine fisiere .yaml sau pe un url care pointeaza catre un fisier .yaml

Labels și Selectors

În fișierul YAML generat de comanda anterioară, putem observa că în câmpul metadata, pe lângă atributul name, avem și atributul labels:

metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx

Aceste labels sunt perechi de tipul cheie-valoare care sunt folosite pentru identificarea obiectelor din Kubernetes. În exemplul de mai sus, avem perechea run=nginx. Această pereche poate fi folosită de către un label selector pentru a referi acest obiect (mai multe detalii în continuare).

Label Selectors

Spre deosebire de nume, label-urile nu asigură unicitate. În general, ne așteptăm ca mai multe obiecte să aibă aceleași label-uri.

Asa cum am spus anterior, cu ajutorul unor Label Selectors putem identifica numite seturi de obiecte în Kubernetes. Un exemplu relevant este expunerea unui pod printr-un serviciu. În cadrul laboratorului trecut, ați expus poduri cu ajutor unor servicii de tipul ClusterIp și NodePort. De unde știe serviciul ClusterIp ce nod să expuna? (hint: kubectl describe myservice #cautati label selectors).

Un exemplu comun de utilizare a labels și labels selectors prin intermediul fișierelor de configurare YAML este următorul: kubectl run nginx –image=nginx –port=8080 –dry-run=client -o yaml >vtest.yaml

Adăugați podului următorul label:

app: myapp

Creați pod-ul:

kubectl apply -f test.yaml.
kubectl describe pod nginx # analizate label-urile podului.

Pentru a expune acest pod trebuie creat un serviciu de tipul ClusterIP care să selecteze podul nostru prin intermediul label selectors. Un fișier de configurare YAML pentru acest serviciu este următorul:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null    
  name: nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp #select the pod/pods
status:
  loadBalancer: {}

Observați că nu am definit tipul de serviciu, astfel Kubernetes a creat by default un serviciu de tipul ClusterIP. Verificați faptul că podul nginx este expus.

Obiecte avansate declarate in YAML

In exemplul precedent am scris definitia unui Pod in YAML. De obicei, nu veti dori sa lucrati cu pod-uri, ci cu un obiect care controleaza starea de viata a pod-urilor, precum un deployment.

Deployment-ul are o sintaxa putin mai grea:

#Exemplu oficial de fisier YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Observati ce este scris in template. Aceasta bucata reprezinta pod-ul care va fi coordonat de deployment.

Observati ca ce este scris in template este identic cu ce este scris in sectiunea anterioara.

Deployment-ul aplicatiei de laborator folosind YAML

Faceti referire la aplicatia propusa in laboratorul trecut. Vom reface rezolvarea, folosind fisiere YAML pentru declararea pod-urilor si a serviciilor.

Este indicat sa va scrieti fisierele de yaml de la zero, insa pentru rapiditate vom folosi dry-run

DB

Generare fișier YAML pentru containerul DB:

kubectl run db --image=axonedge/lab-k8s-database --dry-run=client -o yaml > db-pod.yaml

Deschidem fisierul YAML și adăugam câmpul env în spec:

spec:
  containers:
  - image: axonedge/lab-k8s-database
    name: db
    env:
    - name: POSTGRES_USER
      value: student
    - name: POSTGRES_PASSWORD
      value: student
    - name: POSTGRES_DB
      value: library

Creăm un fișier YAML pentru un serviciu care expune pod-ul creat anterior:

apiVersion: v1
kind: Service
metadata:
  name: db-cluster-ip-service
spec:
  ports:
  - port: 5432
    protocol: TCP
    targetPort: 5432
  selector:
    run: db
RabbitMQ

Cum pod-ul de RabbitMq este unul basic, Îl puteam crea direct cu metoda imperativă:

kubectl run rabbitmq --image=rabbitmq:3 --port=5672

Copiați fisierul pentru serivicul anterior si modificați-l astfel încât acesta să folosească portul 5672 și să expună pod-ul de RabbitMQ:

apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-cluster-ip-service
spec:
  ports:
  - port: 5672
    protocol: TCP
    targetPort: 5672
  selector:
    run: rabbitmq

Creați serviciul:

kubectl create -f serviciu-rabbitmq.yaml
Procesator

Generați un fișier YAML pentru pod-ul de procesator:

kubectl run procesator --image=axonedge/lab-k8s-procesator --dry-run=client -o yaml > procesator-pod.yaml

Adăugați variabilele de mediu necesare:

    env:
    - name: PGHOST
      value: db-cluster-ip-service
    - name: PGDATABASE
      value: library
    - name: PGPORT
      value: "5432"
    - name: PGUSER
      value: student
    - name: PGPASSWORD
      value: student
    - name: AMQPURL
      value: amqp://rabbitmq-cluster-ip-service
API

Generați fișierul YAML pentru acest pod:

kubectl run api --image=axonedge/lab-k8s-api --dry-run=client -o yaml > api-pod.yaml

Adăugați variabilele de mediu:

    env:
    - name: PORT
      value: "8000"
    - name: PGHOST
      value: db-cluster-ip-service
    - name: PGDATABASE
      value: library
    - name: PGPORT
      value: "5432"
    - name: PGUSER
      value: student
    - name: PGPASSWORD
      value: student
    - name: AMQPURL
      value: amqp://rabbitmq-cluster-ip-service

Scrieți un fișier de configurare pentru serviciul nodeport:

apiVersion: v1
kind: Service
metadata:
  name: api-nodeport-service
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 8000
  selector:
    run: api #select the pod/pods
  type: NodePort

Puteti sa rulati toate configuratiile de yaml daca sunt puse impreuna intr-un folder, folosind kubectl apply -R -f NumeFolder

kubectl apply -R -f .\Deployment\

Ce urmeaza?

Cu aceasta teorie pusa in practica, am reusit sa acoperim o parte consistenta din baza kubernetes. Cu toate acestea, inca nu am terminat. La laboratorul urmator vom invata urmatoarele:

  • stocare persistenta (PV & PVC)
  • secrete (Secrets)
  • configurari (ConfigMaps)
  • load balancer (LoadBalancer Service)

Tema optionala

Adaptati configuratiile facute astazi, transformand pod-urile in deployment-uri. Api-ul ar trebui sa aiba 2 replici, clientul de rabbit 3 si baza de date 1.

cc/laboratoare/06.1637579720.txt.gz · Last modified: 2021/11/22 13:15 by alexandru.hogea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0