This is an old revision of the document!
Despre deployments ați învățat în cadrul laboratorului trecut. În cadrul laboratorului curent veți învăța despre upgrade-ul unui deployment și despre rollback-ul unui deployment.
Pentru un fișier de deployment putem să avem următorul template:
apiVersion: apps/v1 kind: Deployment metadata: name: <> #name spec: replicas: <x> #no of replicas selector: matchLabels: key: value template: metadata: labels: pod-key: pod-value spec: containers: - name: nginx image: <> #you can use the nginx image
Dorim, de exemplu, să facem următorul deploymentul, cu numele cc-dep-01
, cu 4 replici și cu un label-ul app: lab3cc
:
kind: Deployment metadata: name: cc-dep-01 spec: replicas: 10 selector: matchLabels: app: lab3cc template: metadata: labels: app: lab3cc spec: containers: - name: nginx image: nginx
kubectl apply -f lab3dep.yaml
Ajungem la partea de upgrade a unui deployment. Un use-case relevant este unul des întâlnit în ziua de azi, presupunem că a apărut o nouă versiune a aplicației și vrem să folosim versiunea curentă.
În cazul deployment-ului nostru, vrem să folosim o nouă versiune a webserver-ului aplicației noastre, deci vrem să folosim o versiune mai nouă a nginx.
nginx:1.21.1
. kubectl apply -f mynewdep.yaml
În primul rând, un aspect foarte important este că pod-urile sunt upgraded secvențial, nu toate odată, după ce un număr de noi pod-uri au fost create, urmează să se șteargă cele vechi, procedeul se repetă până când toate pod-urile au fost updated.
numeDeployment-identificatorReplicaSet-identificatorPod
kubectl get rs # am folosit o prescurtare
Din câte puteți observa, avem două ReplicaSets care corespund aceluiași deployment. Motivul este pentru că în momentul în care am făcut upgrade deployment-ului, a fost creat un nou ReplicaSet cu nouă imagine de nginx folosită. Obiectul ReplicaSet vechi este și el păstrat pentru că există mereu o șansă să vrem să ne întoarcem la versiunea anterioară a aplicației.
Am realizat că avem o greșeală în deploymentul nostru, pentru a reveni la versiunea anterioară folosim următoarea comandă: kubectl rollout history deployment <depname>
kubectl scale deployment <depname> –replicas=2
kubectl scale deployment <depname> –replicas=5
Pentru a modifica imaginea folosită de un deployment, avem următoarea comandă: kubectl set image deployment <depname> nginx=nginx:failTest
În comanda de mai sus am introdus intenționat o imagine care nu există. Dacă urmariți comportamentul deployment-ului, o să observați că noile pod-uri nu vor fi create deoarece nu poate fi gasită imaginea specificată.
Am ajuns în situația în care vrem să ne întoarcem la o versiunea anterioară. Pentru a vedea istoricul modificărilor făcute pe acest deployment, avem următoarea comandă: kubectl rollout history deoployment <depname>
Observați ca avem mai multe “revizii” ale deployment-ului nostru. Pentru a ne întoarce la o anumită revizie, folosim următoarea comandă:
kubectl rollout history deployment cc-dep-01 –revision=2
Care sunt serviciile cunoscute în Kubernetes? Care este diferența între ele? Ne interesează în mod special diferența dintre ClusterIP și NodePort.
Pentru a instanția o aplicație simplă care conține o bază de date și un API care face interogări, avem nevoie, asa cum intuiți, de 2 pod-uri.
Pentru a porni un pod de Postgres, avem nevoie de a seta variabilele POSTGRES_USER
și POSTGRES_PASSWORD
, dar și numele bazei de date pe care urmează să o folosim - POSTGRES_DB
. Avem mai multe moduri prin care putem face asta, cel mai simplu exemplu (și cel mai nesigur) este cu un ConfigMap.
Exemplu:
apiVersion: v1 kind: ConfigMap metadata: name: db-config-map data: POSTGRES_USER: "admin" POSTGRES_PASSWORD: "admin" POSTGRES_DB: "books"
Când o să creăm pod-ul / deployment-ul, o să folosim acest ConfigMap pentru a injecta variabilele de mediu. Pentru a avea datele persistente, avem nevoie, asa cum știm din labul trecut, de un PV și de un PVC:
PersistentVolume
(PV):apiVersion: v1 kind: PersistentVolume metadata: name: postgres-pv-volume labels: type: local spec: storageClassName: manual capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"
PersistentVolumeClaim
(PVC):apiVersion: v1 kind: PersistentVolumeClaim metadata: name: posgress-pvc spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
Pentru a crea pod-ul de Postgres, avem următorul fișier:
apiVersion: v1 kind: Pod metadata: name: db-pod labels: app: postgres spec: containers: - image: postgres:10.4 name: postgres volumeMounts: - name: myvol mountPath: /etc/config ports: - containerPort: 5432 envFrom: - configMapRef: name: db-config-map volumes: - name: myvol persistentVolumeClaim: claimName: posgress-pvc
Pentru ca podul nostru de API să comunice cu cel de baze de date, trebuie să expunem pod-ul de Postgres printr-un serviciu de tip ClusterIP:
apiVersion: v1 kind: Service metadata: name: postgres labels: app: postgres spec: type: ClusterIP ports: - port: 5432 selector: app: postgres
Pentru a porni podul de API, avem următorul fișier:
apiVersion: v1 kind: Pod metadata: name: apipod labels: app: api spec: containers: - image: andreidamian/lab3cc:first name: apicontainer env: - name: PGUSER value: "admin" - name: PGPASSWORD value: "admin" - name: PGDATABASE value: "books" - name: PGHOST value: "postgres" - name: PGPORT value: "5432"
Dupa ce și acest pod este up and running, trebuie să îl expunem printr-un serviciu de tip NodePort pentru a putea comunica cu el de pe mașina noastră. Facem asta prin următoarea comandă (se poate face și printr-un fișier YAML): kubectl expose pod apipod –port 80 –type=NodePort
Apoi verificați portul asignat de noul serviciu (31598):
Folosiți Postman pentru a accesa API-ul deployed:
Avem această eroare pentru că baza de date nu a fost configurată. Pentru a configura baza de date avem mai multe variante, cea mai simpla (dar și cea mai ineficientă) este următoarea:
kubectl exec -it db-pod bash
psql -h localhost -U admin –password books
CREATE TABLE IF NOT EXISTS books ( id uuid PRIMARY KEY NOT NULL , title VARCHAR NOT NULL, author VARCHAR NOT NULL );
Incercați din nou comanda GET din Postman. Inserați ceva în baza de date:
Stergeți pod-ul de Postgres și incercați să faceți GET. Ar trebui să primiți următoarea eroare: