Differences

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

Link to this comparison view

cc:laboratoare:05 [2021/11/14 21:39]
alexandru.hogea [Testare]
cc:laboratoare:05 [2022/11/11 23:12] (current)
florin.mihalache
Line 1: Line 1:
-===== Laboratorul 05. Kubernetes & Kubectl=====+====== Laboratorul 05 - Terraform + AWS ======
  
-==== Introducere ​====+===== Deployments & virtual machines în AWS ===== 
 +În cadrul acestui laborator veți învăța cum să creați mașini virtuale în cadru AWS (Amazon Web Services), care reprezintă o platformă care furnizează servicii de tip cloud computing, baze de date, stocare de fișiere, device farms, etc.
  
-In acest laborator ​vom parcurge crearea ​de **pods** folosind comanda **kubectl**Activitatea este echivalenta cu pornirea mai multor containere de Docker folosind **docker run**.+Pentru ​acest laborator ​presupunem că avem deja Terraform instalat ​de la laboratorul precedentDacă nu aveți Terraform instalat, puteți urma pașii din laboratorul anterior.
  
-==== Aplicatia Propusa ====+Pe langa Terraform, avem nevoie de AWS CLI instalat. Pentru a instala, urmati pasii de [[https://​docs.aws.amazon.com/​cli/​latest/​userguide/​getting-started-install.html | aici]].
  
-Va propunem o mini aplicatie formata din 4 componente:​ +Pe lângă asta, avem nevoie ​de un cont pentru Amazon AWS. După ce ați făcut pașii pentru a avea propriul cont AWS, vrem sa conectăm AWS CLI la consola ​de AWS.
-  - un API webserver +
-  - un script care proceseaza informatii +
-  - o baza de date +
-  - un broker ​de rabbitMQ +
-{{:​cc:​laboratoare:​schema_cod.png?800|}}+
  
-Aplicatia reprezinta un model simplificat de [[https://​martinfowler.com/​bliki/​CQRS.html|CQRS]]. ​ +Pentru a face asta, mergem în AWS și intrăm în secțiunea IAM
-<note tip>​CQRS ​Command and Query Responsibility Segregation se refera la despartirea logica intre cereri si actiuni care modifica starea dintr-un sistem</​note>​+{{ :​cc:​laboratoare:​lab-5-image3.png?​700 |}}
  
-Fluxul este urmatorul+Apoi mergem la "My security credentials"​
-  * Serverul **API** accepta doua __cereri HTTP__un POST si un GET +{{ :cc:​laboratoare:​lab-5-image1.png?700 |}}
-  * Cererile de tip POST sunt trimise catre **Procesator**Procesatorul adauga un timestamp si apoi scrie intrarea in baza de date +
-  * Cererile de tip GET sunt procesate direct de API care trage informatia din baza de date+
  
-Codul este accesibil ​pe [[https://​gitlab.com/​mobylab-cc/laborator-k8s|repo-ul nostru]].+Următorul pas este să mergem la "​Access Keys" și să apăsăm ​pe butonul de ''​Create New Access Key'':​ 
 +{{ :cc:​laboratoare:​lab-5-image5.png?700 |}}
  
-==== Deployment folosind Kubernetes ====+Păstrați fișierul generat. Rulați comanda ''​aws configure''​ și introduceți datele generate în fisierul creat anterior (''​AWSAccessKeyId''​ și ''​AWSSecretKey''​).
  
-In codul sursa aveti un exemplu de **docker-compose.yml**,​ pentru ​avea perspectiva familiara asupra cum va arata deploymentul local. In Kubernetes, fiecare serviciu va fi reprezentat ​de un Pod.+Pentru ​crea instanță simplă de EC2 (o mașina virtuală) folosim următorul ​fișier de Terraform:​ 
 +<code terraform>​ 
 +terraform { 
 + ​required_providers { 
 +   aws = { 
 +     ​source ​ = "​hashicorp/​aws"​ 
 +     ​version = "~> 4.16" 
 +   } 
 + } 
 +  
 + ​required_version = ">= 1.2.0"​ 
 +
 +  
 +provider "​aws"​ { 
 + ​region = "​us-west-2"​ # regiunea in care o sa se faca deploy la resurse 
 +
 +  
 +resource "​aws_instance"​ "​app_server"​ { 
 + ​ami ​          = "​ami-830c94e3"​ # tipul de masina folosita (ami = Amazon Machine Image) 
 + ​instance_type = "​t2.micro"​ # tipul de instanta (resursele pe care le are masina) 
 +  
 + tags = { 
 +   Name = "​labAwsTerraform"​ 
 + } 
 +
 +</​code>​
  
-In continuare vom folosi ​comenzile ​de Kubectl, prezentate la laboratorul trecut, ​pentru a porni fiecare Pod independent. +Rulați ​comenzile ​cunoscute ​pentru a face deployment acestei infrastructuri:​ 
-<note tip>La laboratorul urmator vom face deployment folosind configuratie declarativa yaml</note>+<code bash> 
 +terraform init 
 +terraform fmt 
 +terraform plan 
 +terraform apply 
 +</code>
  
-==== Testare ====+Pentru a verifica ca mașina virtuală a fost deployed, căutăm serviciul EC2: 
 +{{ :​cc:​laboratoare:​lab-5-image7.png?​700 |}}
  
-Pentru ​testa aplicatia va recomandam sa folositi [[https://www.postman.com/​|Postman]].+Ajungem în pagina următoare în care vedem că nu avem nicio instanță up and running, deși planul nostru de Terraform ​fost executat cu succes. De ce? 
 +{{ :cc:​laboratoare:​lab-5-image4.png?​700 ​|}}
  
-Testarea se realizeaza in felul urmator: +Observați diferența de regiuni (Frankfurtîn cazul din imaginea anterioară,​ față ​de us-west-2 în Terraform). Pentru a modifica regiunea în care facem deployment la resurse modificăm codul Terraform. În cazul de față, putem să facem click pe Frankfurt și să selectăm us-west-2 (Oregon). În acest moment putem vedea că avem o instanță up and running: 
-  - Adaugati o intraretrimitand o cerere ​de tip POST pe linkul **http://localhost:PORT_ALES/​api/​v1/​books** cu urmatorul body+{{ :cc:laboratoare:​lab-5-image2.png?​700 |}} 
-<code json+ 
-{ +<note tip
-    "​name"​"De ce iubim femeile?"+În codul Terraform modificați numele masinii din ''​labAwsTerraform''​ în ''​testUpdate''​. 
-    "​author":​ "​Mircea Cartarescu"​+Rulatț comenzile obișnuite pentru a vedea planul. 
-    "​price":​ 69+Observați că această modificare nu implică distrugerea mașinii existente, ci doar modificarea in-place. 
-    "​description"​"Autoironie"+</​note>​ 
 + 
 +{{ :cc:​laboratoare:​lab-5-image6.png?700 |}} 
 + 
 +===== Cluster Kubernetes în AWS ===== 
 +Pentru a face deployment unui cluster de Kubernetes în AWS avem 2 opțiuni. 
 +  - Facem deploy la mai multe mașini virtuale și instalăm și configurăm un cluster de mână. 
 +  - Folosim serviciul AWS special conceput pentru clusters de KubernetesAWS EKS Cluster 
 + 
 +În cazul acestui laboratoro să facem deployment la un cluster folosind EKS. 
 + 
 +Pentru a urma best practices recomandate de hashicorpo să spargem codul în mai multe fișiere. 
 + 
 +Fișierul ''​variables.tf''​ o sa conțină o simplă variabilă în care definim zona în care vrem să facem deployment:​ 
 +<code terraform>​ 
 +variable ​"region"​ { 
 + description ​"AWS region" 
 + ​type ​       = string 
 + ​default ​    = "​us-west-2"
 } }
 </​code>​ </​code>​
-   Vizualizati intrareatrimitand o cerere ​de tip GET pe acelasi link+ 
-<note tip>Observati ​ca intrarea va avea campul **insertedAt** adaugat</note>+Mai departe avem nevoie de un VPC, deci vom crea un nou fisier ''​vpc.tf''​. Mai multe despre ce este un VPC: [[https://​docs.aws.amazon.com/​vpc/​latest/​userguide/​what-is-amazon-vpc.html | aici]]. 
 +<​code>​ 
 +module "​vpc"​ { 
 + ​source ​ = "​terraform-aws-modules/​vpc/​aws"​ 
 + ​version = "​3.14.2"​ 
 +  
 + name = "​cc-vpc"​ 
 +  
 + cidr = "​10.0.0.0/​16"​ 
 + ​azs ​ = slice(data.aws_availability_zones.available.names0, 3) 
 +  
 + ​private_subnets = ["​10.0.1.0/​24",​ "​10.0.2.0/​24",​ "​10.0.3.0/​24"​] 
 + ​public_subnets ​ = ["​10.0.4.0/​24",​ "​10.0.5.0/​24",​ "​10.0.6.0/​24"​] 
 +  
 + ​enable_nat_gateway ​  = true 
 + ​single_nat_gateway ​  = true 
 + ​enable_dns_hostnames = true 
 +  
 + ​public_subnet_tags = { 
 +   "​kubernetes.io/​cluster/​${local.cluster_name}"​ = "​shared"​ 
 +   "​kubernetes.io/​role/​elb" ​                     = 1 
 + } 
 +  
 + ​private_subnet_tags = { 
 +   "​kubernetes.io/​cluster/​${local.cluster_name}"​ = "​shared"​ 
 +   "​kubernetes.io/​role/​internal-elb" ​            = 1 
 + } 
 +
 +</​code>​ 
 + 
 +Mai multe detalii despre modulul ​de Terraform pentru VPC: [[https://​registry.terraform.io/​providers/​hashicorp/​aws/​latest/​docs/​resources/​vpc | aici]]. 
 + 
 +În continuare avem nevoie de 2 security groups, ​pe care o să le folosească cluster-ul nostruAșadar creăm un nou fișier cu numele ''​securityGroups.tf''​ cu următorul conținut: 
 +<code> 
 +resource "​aws_security_group"​ "​node_group_one"​ { 
 + ​name_prefix = "​node_group_one"​ 
 + ​vpc_id ​     = module.vpc.vpc_id 
 +  
 + ​ingress { 
 +   ​from_port = 22 
 +   ​to_port ​  = 22 
 +   ​protocol ​ = "​tcp"​ 
 +  
 +   ​cidr_blocks = [ 
 +     "​10.0.0.0/​8",​ 
 +   ] 
 + } 
 +
 +  
 +resource "​aws_security_group"​ "​node_group_two"​ { 
 + ​name_prefix = "​node_group_two"​ 
 + ​vpc_id ​     = module.vpc.vpc_id 
 +  
 + ​ingress { 
 +   ​from_port = 22 
 +   ​to_port ​  = 22 
 +   ​protocol ​ = "​tcp"​ 
 +  
 +   ​cidr_blocks = [ 
 +     "​192.168.0.0/​16",​ 
 +   ] 
 + } 
 +
 +</​code>​ 
 + 
 +Ne putem gândi la un security group ca la un firewall. Mai multe detalii în [[https://​aviatrix.com/​learn-center/​cloud-security/​aws-security-groups/​ | documentație]]. Documentația unui security group de AWS în Terraform: [[https://​registry.terraform.io/​providers/​hashicorp/​aws/​latest/​docs/​resources/​security_group | aici]]. 
 + 
 + 
 +Până acum am definit doar componentele de care o să ne folosim în momentul în care configurăm cluster-ul nostru. Pentru a face asta, avem un nou fișier ''​cluster.tf''​ cu următoarea configurație:​ 
 +<code> 
 +module "​eks"​ { 
 + ​source ​ = "​terraform-aws-modules/eks/​aws"​ 
 + ​version = "​18.26.6"​ 
 +  
 + ​cluster_name ​   = local.cluster_name 
 + ​cluster_version = "​1.22"​ 
 +  
 + ​vpc_id ​    = module.vpc.vpc_id 
 + ​subnet_ids = module.vpc.private_subnets 
 +  
 + ​eks_managed_node_group_defaults = { 
 +   ​ami_type = "​AL2_x86_64"​ 
 +  
 +   ​attach_cluster_primary_security_group = true 
 +  
 +   # Disabling and using externally provided security groups 
 +   ​create_security_group = false 
 + } 
 +  
 + ​eks_managed_node_groups = { 
 +   one = { 
 +     name = "​node-group-1"​ 
 +  
 +     ​instance_types = ["​t3.small"​] 
 +  
 +     ​min_size ​    = 1 
 +     ​max_size ​    = 3 
 +     ​desired_size = 2 
 +  
 +     ​pre_bootstrap_user_data = <<​-EOT 
 +     echo 'foo bar' 
 +     EOT 
 +  
 +     ​vpc_security_group_ids = [ 
 +       ​aws_security_group.node_group_one.id 
 +     ] 
 +   } 
 +  
 +   two = { 
 +     name = "​node-group-2"​ 
 +  
 +     ​instance_types = ["​t3.medium"​] 
 +  
 +     ​min_size ​    = 1 
 +     ​max_size ​    = 2 
 +     ​desired_size = 1 
 +  
 +     ​pre_bootstrap_user_data = <<​-EOT 
 +     echo 'foo bar' 
 +     EOT 
 +  
 +     ​vpc_security_group_ids = [ 
 +       ​aws_security_group.node_group_two.id 
 +     ] 
 +   } 
 + } 
 +
 +</code> 
 + 
 +Mai avem doar de creat un fișier ''​main.tf''​ cu următoarea configurație:​ 
 +<​code>​ 
 +provider "​kubernetes"​ { 
 + ​host ​                  = module.eks.cluster_endpoint 
 + ​cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) 
 +
 +  
 +provider "​aws"​ { 
 + ​region = var.region 
 +
 +  
 +data "​aws_availability_zones"​ "​available"​ {} 
 +  
 +locals { 
 + ​cluster_name = "​cc-eks-${random_string.suffix.result}"​ 
 +
 +  
 +resource "​random_string"​ "​suffix"​ { 
 + ​length ​ = 8 
 + ​special = false 
 +
 +</​code>​ 
 + 
 +Pentru a afișa câteva informații legate de infrastructura noastră avem nevoie de câteva outputs. Așa cum am învățat data trecută, facem un fișier separat în care definim acest outputs: 
 +<​code>​ 
 +output "​cluster_id"​ { 
 + ​description = "EKS cluster ID" 
 + ​value ​      = module.eks.cluster_id 
 +
 +  
 +output "​cluster_endpoint"​ { 
 + ​description = "​Endpoint for EKS control plane"​ 
 + ​value ​      = module.eks.cluster_endpoint 
 +
 +  
 +output "​cluster_security_group_id"​ { 
 + ​description = "​Security group ids attached to the cluster control plane"​ 
 + ​value ​      = module.eks.cluster_security_group_id 
 +
 +  
 +output "​region"​ { 
 + ​description = "AWS region"​ 
 + ​value ​      = var.region 
 +
 +  
 +output "​cluster_name"​ { 
 + ​description = "​Kubernetes Cluster Name"​ 
 + ​value ​      = local.cluster_name 
 +
 +</​code>​  
 + 
 +Rulăm comenzile obișnuite pentru a crea infrastructura. Observați ca sunt foarte multe resurse care urmează să se construiască. 
 + 
 +In cazul in care ați realizat ca lipsește ceva (nu am definit niciunde ce versiuni ale provider-ilor vrem să folosim), best practices recomandă să avem un fișier numit ''​terraform.tf''​ care să conțină această configurație:​ 
 +<​code>​ 
 +terraform { 
 + ​required_providers { 
 +   aws = { 
 +     ​source ​ = "​hashicorp/​aws"​ 
 +     ​version = "~> 4.15.0"​ 
 +   } 
 +  
 +   ​random = { 
 +     ​source ​ = "​hashicorp/​random"​ 
 +     ​version = "~> 3.1.0"​ 
 +   } 
 +  
 +   tls = { 
 +     ​source ​ = "​hashicorp/​tls"​ 
 +     ​version = "~> 3.4.0"​ 
 +   } 
 +  
 +   ​cloudinit = { 
 +     ​source ​ = "​hashicorp/​cloudinit"​ 
 +     ​version = "~> 2.2.0"​ 
 +   } 
 +  
 +   ​kubernetes = { 
 +     ​source ​ = "​hashicorp/​kubernetes"​ 
 +     ​version = "~> 2.12.1"​ 
 +   } 
 + } 
 +
 +</​code>​ 
 + 
 +Asteptați ca planul să se termine de rulat sș verificați infrastructura creată în AWS (o să dureze în jur de 15-20 minute). Apoi, pentru a ne conecta la cluster-ul nostru proaspăt creat de Kubernetes, folosim următoarea comandă: 
 +<code bash> 
 +aws eks --region $(terraform output -raw region) update-kubeconfig \ 
 +    --name $(terraform output -raw cluster_name) 
 +</​code>​ 
 + 
 +Verificați conexiunea cu următoarea comandă: ''​kubectl cluster-info''​ 
 + 
 +În acest moment avem un cluster configurat în AWS EKS și suntem conectați la el. Orice comandă de kubectl rulată o să fie executată pe cluster-ul nostru. 
 + 
cc/laboratoare/05.1636918745.txt.gz · Last modified: 2021/11/14 21:39 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