Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cc:laboratoare:04 [2021/11/09 14:12]
radu.ciobanu [Exemplu Comenzi]
cc:laboratoare:04 [2022/10/30 19:29] (current)
florin.mihalache
Line 1: Line 1:
-===== Laboratorul 04 - Introducere in Kubernetes ​=====+====== Laboratorul 04 - Terraform ​=====
 +===== Ce este Terraform? ===== 
 +[[https://​developer.hashicorp.com/​terraform | Terraform]] reprezintă un instrument open-source folosit pentru Infrastructure as Code, dezvoltat de HashiCorp, prin care, mai exact, se automatizează procese de infrastructură / devops.
  
-==== Introducere ====+Un use-case principal al Terraform îl reprezintă conectarea la cloud providers, precum Google Cloud Platform (GCP) și Amazon Web Services (AWS), și gestionarea resurselor oferite de către cloud providers.
  
-Kubernetes (prescurtat K8s) este cel mai popular orchestrator,​ folosit la scara larga si oferit ca si CaaS (Container as a Service) de toti vendorii de infrastructura (Amazon, Google, Microsoft). Este considerat **standard** in materie de deployment al serviciilor orchestrate. 
  
-Varianta originala este dezvoltata de Google, este open source, si face parte din Cloud Native Foundation (CNF). Fiecare vendor adauga pachete in plus, pentru a il adapta la ecosistemul proprietar (de exemplu, Azure adauga comenzi ​si straturi in plus peste varianta de baza).+===== Instalare Terraform ===== 
 +Folosim site-ul oficial al Terraform ​pentru a instala tool-ul. Găsiți toate detaliile necesare aici: https://​www.terraform.io/​downloads
  
-Este mai complicat decat Docker Swarm, dar in multe situatii nu veti fi nevoiti sa rulati propriul vostru cluster de K8s, ci doar sa rulati aplicatii peste un cluster ​de kubernetes gata oferit (de exempluAzure Kubernetes Service (AKS)). +Pentru a instala Terraform pe o mașinp cu un sistem ​de operare Ubuntu / Debianfolosim următoarele comenzi: 
- +<code bash> 
-Avantajul **major** asupra Docker Swarm il ofera utilizarea sa in industrie, cat si faptul ca este mai flexibil si ofera mai multe functionalitati,​ insa nu out of the box. Faptul ca este customizabil implica, bineinteles,​ si un factor de dificultate mai mare. Kubernetes este mai greu de invatat decat Swarm, dar are si mai multe capabilitati. +wget -O- https://apt.releases.hashicorp.com/gpg gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg 
- +echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release ​-cs) main" ​sudo tee /etc/apt/sources.list.d/hashicorp.list 
-<note tip>[[https://kubernetes.io/partners/#​conformance|Aici]] puteti vedea toti partenerii Kubernetes<​/note> +sudo apt update && sudo apt install terraform 
- +</code>
-==== Instalare ==== +
- +
-Kubernetes se poate seta in multe moduri: +
- +
-=== Bootstrap la propriul cluster === +
- +
-Este metoda cea mai dificila, in care se leaga mai multe masini in retea folosind [[https://kubernetes.io/docs/​setup/​production-environment/​tools/​kubeadm/​create-cluster-kubeadm/​|Kubeadm]]Se foloseste pentru a crea un cluster de la 0 si necesita un nivel de cunostinte mediu-avansat. +
- +
-=== Folosirea unui cluster deja setat === +
- +
-Asa cum am precizat in introducere,​ sunt putine cazurile cand veti trebui sa setati un cluster de la 0, deoarece vendorii principali de infrastructura au versiunile lor de Kubernetes si sistemele de CaaS deja pregatite. +
- +
-=== Instalare locala === +
- +
-Cea mai buna metoda de a invata este sa va setati local un cluster cu un singur nod de kubernetes. Acest lucru se poate face in mai multe moduri: +
-  * Pentru utilizatorii Windows PRO care au si Docker instalat, Kubernetes vine preinstalat +
-  * Pentru utilizatorii Windows Non-Pro se foloseste [[https://minikube.sigs.k8s.io/docs/start/​|Minikube]+
-  * Pentru utilizatorii Linux, se foloseste [[https://microk8s.io/​|MicroK8s]] +
- +
-==== Arhitectura Kubernetes ==== +
- +
-{{:​cc:​laboratoare:​kubernetesarhitecture.png?​800|}} +
- +
-Precum Docker Swarm, Kubernetes este un sistem format din mai multe [[https://​kubernetes.io/​docs/​concepts/​overview/​components/#​master-components|componente]]:​ +
-  - **Kubectl** - CLI pentru configurarea clusterului si managementului aplicatiilor. Asemanator cu comanda ​//docker/+
-  - **Node** - nodul fizic din cadrul unui cluster +
-  - **Kubelet** - agentul (daemon) de Kubernetes care ruleaza pe fiecare nod +
-  - **Control Plane** - colectia de noduri care fac management la clusterInclude API Server, Scheduler, Controller Manager, CoreDNS, EtcdAsemanator cu nodurile "​master"​ din Docker Swarm. +
- +
-{{:​cc:​laboratoare:​controlplane.png?​800|}} +
- +
-==== Componentele unei aplicatii Kubernetes ==== +
- +
-La fel ca in cadrul Docker Swarm, Kubernetes foloseste o ierarhie logica de componente pentru aplicatii:​ +
- +
-  * **Pod** - unitatea fundamentala de lucru. Un pod contine intotdeauna containere. +
-  * **Controllere** - creaza, actualizeaza si mentine starea de rulare a pod-urilor. Echivalentul unui serviciu din docker swarm. +
-<note tip>​Exemple de controllere:​ **Deployment**,​ ReplicaSet, StatefulSet,​ DaemonSet, Job, CronJob</note> +
-  * **Service** - endpoint de conectare in retea. Se ataseaza unui pod. Echivalentul configuratiei de retea din docker swarm+
-<note tip>​Tipurile de services sunt: NodePort, ClusterIP si LoadBalancer.</​note>​ +
-  * **Storage** - obiecte care se ocupa de persistarea datelor. PersistentVolume (PV) si PersistentVolumeClaim (PVC). Asemanator cu docker mounts. +
-<note tip>​Datorita PV si PVC, in kubernetes se poate realiza persistarea datelor chiar si intre mai multe noduri. In cadrul Docker Swarm eram limitati la utilizarea unui NFS extern.</note>+
  
-  * **Namespace** - grup de obiecte intr-un cluster. Asemanator cu stack din docker swarm+Pentru a verifica dacă instalarea fost efectuată cu succes, încercăm să obținem versiunea ​de Terraform instalată: ''​terraform ​-version''​
  
-  * **Configurations** - obiecte ​de configuratie. Exemple de obiecte de configuratieSecrets, ConfigMaps+=== Terraform autocomplete === 
 +Pentru a putea utiliza funcția ​de autocomplete cu Terraform''​terraform -install-autocomplete''​
  
-==== Exemplu Comenzi ​====+===== Terraform + Docker ​===== 
 +În laboratorul curent o să folosim Terraform împreună cu Docker, cu care suntem deja familiari. Începem prin a crea un director nou pentru configuratia noastră:
 <code bash> <code bash>
 +mkdir lab4cc
 +cd lab4cc ​
 +</​code>​
  
-## Kubernetes Local Install+Creăm un fișier cu numele ''​main.tf''​ și introducem următorul cod: 
 +<code terraform>​ 
 +terraform { 
 + ​required_providers { 
 +   ​docker = { 
 +     ​source = "​kreuzwerker/​docker"​ 
 +     ​version = "~> 2.13.0"​ 
 +   } 
 + } 
 +
 +  
 +provider "​docker"​ {} 
 +  
 +resource "​docker_image"​ "​nginx"​ { 
 + ​name ​        = "​nginx:​latest"​ 
 + ​keep_locally = false 
 +
 +  
 +resource "​docker_container"​ "​nginx"​ { 
 + image = docker_image.nginx.latest 
 + ​name ​ = "​tutorial"​ 
 + ports { 
 +   ​internal = 80 
 +   ​external = 8000 
 + } 
 +
 +</​code>​
  
-### minikube 
  
-minikube start+Să analizăm pe rând fiecare bloc de cod introdus: 
 +  * ''​terraform {}''​ - conține setarile de Terraform, inclusiv provider-ul pe care urmează să îl folosim. Pentru fiecare provider, câmpul ''​source''​ definește numele provider-ului. By default, Terraform folosește Terraform Registry pentru a instala un provider. Astfel, în exemplul nostru, ''​kreuzwerker/​docker''​ este un provider care se găsește în registrul Terraform la path-ul ''​registry.terraform.io/​kreuzwerker/​docker''​. Câmpul ''​version''​ este opțional, dacă nu îl folosim, Terraform o să descarce by default ultima versiune disponibilă. 
 +  * ''​provider {}''​ - un block de tipul provider conține configurările necesare pentru ca acel provider să poată fi folosit. În cazul nostru, am folosit ''​docker''​. Un provider este doar un plugin pe care Terraform îl folosește pentru a crea și pentru a gestiona resursele. 
 +  * Blocurile de tip resource - un astfel de bloc, așa cum sugerează și numele, este folosit pentru a defini resurse ale infrastructurii noastre. Așa cum putem observa, un bloc de tip resursă are 2 labels: ''​resource "​docker_image"​ "​nginx"''​. În acest exemplu, ''​docker_image''​ este tipul de resursă, iar ''​nginx''​ este numele resursei. Fiecare astfel de bloc are mai multe proprietăți,​ acestea diferă de la resursă la resursă. Exemplu: în laboratorul viitor o sa configurăm o mașină virtuală într-un provider de cloud unde o să folosim parametrii ca tipul de masină, hard disk, dimensiune hard disk, regiunea în care să fie deployed masina, etc.
  
-### microk8s+Recapitulare cod: 
 +  - Am populat block-ul ''​terraform''​ cu config-ul unde am specificat providerul ''​docker''​ și versiunea dorită. 
 +  - Am inițializat providerul ''​docker''​. 
 +  - Am creat o resursă de tipul ''​docker_image''​ cu numele ''​nginx''​ (numele variabilei). 
 +  - Am creat o resursă de tipul ''​docker_container''​ cu numele ''​nginx''​. În această resursă, pentru imagine am folosit imaginea definită mai sus, iar numele container-ului este dat de câmpul ''​name''​.
  
-microk8s.kubectl+Pentru a pune in picioare infrastructura:​ 
 +  - Initializare:​ ''​terraform init''​Urmăriți output-ul comenzii pentru a înțelege ce face această comandă. 
 +  - Formatarea codului. Acest pas este opțional, dar foarte util: ''​terraform fmt''​ 
 +  - Validarea configurării (și acest pas este optional, în cazul în care mergem mai departe cu o configurare invalidă, o să primim eroare): ''​terraform validate''​ 
 +  - Rulăm comanda ''​terraform plan''​. Această comandă este un dry-run, deci putem observa cum o să arate infrastructura noastră după ce o să aplicăm configurarea creată anterior. **Atenție**,​ această comandă nu modifică infrastructura. 
 +  - Aplicăm configurația:​ ''​terraform apply''​
  
-microk8s.enable dns+<note tip> 
 +Task: urmati instrucțiunile din shell-ul interactiv și faceți deploy la infrastructură. Observați output-ul comenzii.
  
-alias kubectl=microk8s.kubectl+Pentru a observa state-ul: ''​terraform show''​ 
 +</​note>​
  
-## Kubectl runcreate and apply+<note tip> 
 +Task: modificarea unei infrastructuri existente - modificati fișierul anteriorastfel încât container-ul să folosească portul 8080, nu 8000
  
-kubectl run+Rulați comanda pentru a vedea planul. Modificarea este facută in-place?
  
-kubectl create+Ștergere infrastructură - rulați comanda ''​terraform destroy''​ 
 +</​note>​
  
-kubectl apply+===== Variabile în Terraform ===== 
 +Avem următorul fișier''​ outputs.tf'',​ unde avem acest bloc: 
 +<code terraform>​ 
 +output "​Lab"​ { 
 +  value="​lab4 first output"​ 
 +
 +</​code>​
  
-## Pornirea unui Pod+Am creat primul output în Terraform. Pentru a observa comportamentul,​ urmați pașii din exercițiul anterior pentru a "​aplica"​ infrastructura.
  
-kubectl version+Avem acest bloc cu următorul cod: 
 +<code terraform>​ 
 +variable "​LabCCTerraform"​ { 
 +  description = "​primul lab in terraform"​ 
 +  default = "​valoare default a primului lab in terraform"​ 
 +
 +</​code>​ 
 +Aplicați planul și observați comportamentul.
  
-kubectl run my-nginx --image nginx+==== Prioritatea variabilelor ==== 
 +Un alt mod de a seta variabile în Terraform este prin variabile de mediu. By default, Terraform caută variabilele de mediu care încep cu ''​F_VAR_''​. De exemplu, o variabilă de mediu cu numele ''​TF_VAR_MYTESTVAR=myvalue''​ o să atribuie valoarea myvalue unei variabile cu numele ''​MYTESTVAR''​. Variabila cu numele ''​MYTESTVAR''​ trebuie sa fie totuși declarată in configurația noastră de Terraform.
  
-kubectl get pods+<note tip> 
 +Task: 
 +  * Creați o variabilă de mediu care sa suprascrie variabilă folosită de noi: ''​export TF_VAR_LabCCTerraform="​Value from environment"''​ 
 +  * Rulați din nou comanda ''​terraform apply''​ pentru a observa comportamentul. 
 +</​note>​
  
-kubectl get all+==== Fișiere tfvars ==== 
 +<note tip> 
 +Task: 
 +  * Creați un nou fișier cu numele terraform.tfvars si adăugați următoarea linie de cod: ''​LabCCTerraform="​Value from tfvars file"''​. Acest fișier, deși are extensia diferită față de cele anterioare foloseste exact aceeași sintaxă. 
 +  * Folosiți din nou comanda terraform apply pentru a observa comportamentul. 
 +</​note>​
  
-kubectl delete deployment my-nginx+==== Injectare variabile din linia de comandă ==== 
 +Un alt mod prin care putem atribui o valoare unei variabile este prin linia de comandă.
  
-kubectl get all+Rulați următoarea comandă: ''​terraform apply -var LabCCTerraform=valueFromCommandLine''​
  
-## Scalarea unui Pod (se foloseste ​de ReplicaSet)+In urma acestui exercițiu, am aflat ca ordinea ​de prioritizare a variabilelor este următoarea:​ 
 +  - linie de comandă 
 +  - fișier tfvars 
 +  - varibila de mediu 
 +  - valoarea default
  
-kubectl run my-apache --image httpd+==== Tipuri de variabile ==== 
 +Un alt tip de variabilă pe care îl putem folosi este lista: 
 +<code terraform>​ 
 +variable "​mylist"​ { 
 +  default = ["​ana",​ "​are",​ "​mere"​] 
 +
 +</​code>​ 
 +Pentru a accesa un element dintr-o listă avem 2 variante. 
 +  * folosind o funcție: 
 +<code terraform>​ 
 +output "​getelement"​ { 
 +  value = element(var.mylist,​1) 
 +
 +</​code>​ 
 +  * folosind accesare direct cu indexul: 
 +<code terraform>​ 
 +output "​useindex"​ { 
 +  value = var.mylist[1] 
 +
 +</​code>​
  
-kubectl get all+Liste nested: 
 +<code terraform>​ 
 +variable "​nestedlist"​ { 
 +  type = list 
 +    default = [ 
 +      ["​item1",​ "​item2"​],​ 
 +      ["​item3",​ "​item4"​] 
 +    ] 
 +
 +</​code>​ 
 +Pentru a accesa elementele dintr-o listă nested, folosim sintaxa asemănătoare:​ 
 +<code terraform>​ 
 +output "​nestedlist"​ { 
 +  value = var.nestedlist[1][1] 
 +
 +</​code>​
  
-kubectl scale deploy/my-apache --replicas2+Maps: 
 +<code terraform>​ 
 +variable mymap { 
 +  default = { 
 +    us = "​United States"​ 
 +    eu = "​Europe"​ 
 +    apac = "Asia/Pacific"​ 
 +  } 
 +
 +output "​my_region_map"​ { 
 +  value = var.mymap 
 +
 +</​code>​
  
-kubectl scale deployment my-apache ​--replicas2+Pentru a accesa elementele dintr-un map, folosim functia lookup, mai multe detalii gasiți în link-ul: https://​developer.hashicorp.com/​terraform/​language/​functions/​lookup 
 +<code terraform>​ 
 +output "​oneMapElement"​ { 
 +  value = lookup(var.mymap,​ "​us"​) 
 +
 +</​code>​ 
 +==== Organizarea codului Terraform ==== 
 +Având în vedere că deja devine greu de urmărit codul nostru, avem nevoie de o refactorizare.
  
-kubectl get all +Best practices Terraform recomandă să avem fișiere separate pentru variabile și outputs. Simplu spus, toate variabilele stau într-un fișier ''​variables.tf'',​ toate output-urile stau într-un fișier ''​outputs.tf''​. ​
- +
-## Inspectarea obiectelor Kubernetes +
- +
-kubectl get pods +
- +
-kubectl logs deployment/​my-apache +
- +
-kubectl logs deployment/​my-apache ​--follow --tail 1 +
- +
-kubectl logs -l run=my-apache +
- +
-kubectl get pods +
- +
-kubectl describe pod/​my-apache-<​pod id> +
- +
-kubectl get pods -w +
- +
-kubectl delete pod/​my-apache-<​pod id> +
- +
-kubectl get pods +
- +
-kubectl delete deployment my-apache +
-</​code>​+
  
-Gasiti cateva exemple de fisiere declarative in [[https://​gitlab.com/​mobylab-cc/​laborator-4|repository-ul laboratorului]]. 
cc/laboratoare/04.1636459955.txt.gz · Last modified: 2021/11/09 14:12 by radu.ciobanu
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