Kyckling eller Àgg: vi krossar IaC

Kyckling eller Àgg: vi krossar IaC
Vad kom först – kycklingen eller Ă€gget? En ganska mĂ€rklig början pĂ„ en artikel om Infrastructure-as-Code, eller hur?

Vad Àr ett Àgg?

I de flesta fall Àr Infrastructure-as-Code (IaC) ett deklarativt sÀtt att representera infrastruktur. Vi beskriver det tillstÄnd vi vill uppnÄ, frÄn hÄrdvarudelen till mjukvarukonfigurationen. DÀrför anvÀnds IaC för:

  1. Resursbereddning. Det handlar om VMs, S3, VPC osv. De viktigaste verktygen att anvÀnda Àr: Terraform och CloudFormation.
  2. Programvarukonfiguration. De viktigaste verktygen: Ansible, Chef, etc.

All kod finns i git-repositorier. Och förr eller senare kommer teamledaren att besluta att det behövs stÀdning i dem. Och dÄ kommer han att refaktorera. Och han kommer att skapa en viss struktur. Och han kommer att se att detta Àr bra.

Det Àr ocksÄ bra att det redan finns GitLab och GitHub-en leverantör för Terraform (och detta Àr programvarukonfiguration). Med deras hjÀlp kan man hantera hela projektet: teammedlemmar, CI/CD, git-flow osv.

Var kom Àgget ifrÄn?

HÀr kommer vi gradvis till den stora frÄgan.

Först och frÀmst mÄste man börja med det repository som beskriver strukturen av andra repositories, inklusive sig sjÀlv. Och givetvis, inom ramen för GitOps, mÄste man lÀgga till CI sÄ att förÀndringar automatiskt genomförs.

Om Git Ànnu inte Àr skapat?

  1. Hur ska man lagra det i Git?
  2. Hur ska man ansluta CI?
  3. Om vi ocksÄ implementerar GitLab med hjÀlp av IaC, och dessutom i Kubernetes?
  4. Och GitLab Runner ocksÄ i Kubernetes?
  5. Och Kubernetes hos en molnleverantör?

Vad kom först: GitLab, dÀr jag ska ladda upp min kod, eller koden som beskriver vilken GitLab jag behöver?

Kyckling med Àgg

«Oyakodon3 med dinosaurien» [src]

LÄt oss försöka laga en rÀtt som anvÀnder som molnleverantör Managed Kubernetes Selectel.

TL;DR

Kan vi fÄ allt i ett kommando?

$ export MY_SELECTEL_TOKEN=
$ curl https://gitlab.com/chicken-or-egg/mks/make/-/snippets/2002106/raw | bash

Ingredienser:

  • Ett konto frĂ„n my.selectel.ru;
  • Token frĂ„n kontot;
  • Kubernetes fĂ€rdigheter;
  • Helm fĂ€rdigheter;
  • Terraform fĂ€rdigheter;
  • Helm chart för GitLab;
  • Helm chart för GitLab Runner.

Recept:

  1. FÄ MY_SELECTEL_TOKEN frÄn panelen my.selectel.ru.
  2. Skapa en Kubernetes-kluster och överföra token frÄn kontot.
  3. FÄ KUBECONFIG frÄn den skapade klustret.
  4. Installera GitLab i Kubernetes.
  5. FÄ GitLab-token frÄn den skapade GitLab för anvÀndaren. root.
  6. Skapa projektstrukturen i GitLab med hjÀlp av GitLab-token.
  7. Pusha existerande kod till GitLab.
  8. ???
  9. Vinst!

Steg 1. Token kan erhÄllas i avsnittet API-nycklar.

Kyckling eller Àgg: vi krossar IaCSteg 2Vi förbereder vÄr Terraform för att "baka" en kluster av 2 noder. Om du Àr sÀker pÄ att du har tillrÀckligt med resurser kan du aktivera auto-kvoter:

provider "selectel" {
 token = var.my_selectel_token
}

variable "my_selectel_token" {}
variable "username" {}
variable "region" {}


resource "selectel_vpc_project_v2" "my-k8s" {
 name = "my-k8s-cluster"
 theme = {
   color = "269926"
 }
 quotas {
   resource_name = "compute_cores"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     value = 16
   }
 }
 quotas {
   resource_name = "network_floatingips"
   resource_quotas {
     region = var.region
     value = 1
   }
 }
 quotas {
   resource_name = "load_balancers"
   resource_quotas {
     region = var.region
     value = 1
   }
 }
 quotas {
   resource_name = "compute_ram"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     value = 32768
   }
 }
 quotas {
   resource_name = "volume_gigabytes_fast"
   resource_quotas {
     region = var.region
     zone = "${var.region}a"
     # (20 * 2) + 50 + (8 * 3 + 10)
     value = 130
   }
 }
}

resource "selectel_mks_cluster_v1" "k8s-cluster" {
 name         = "k8s-cluster"
 project_id   = selectel_vpc_project_v2.my-k8s.id
 region       = var.region
 kube_version = "1.17.9"
}

resource "selectel_mks_nodegroup_v1" "nodegroup_1" {
 cluster_id        = selectel_mks_cluster_v1.k8s-cluster.id
 project_id        = selectel_mks_cluster_v1.k8s-cluster.project_id
 region            = selectel_mks_cluster_v1.k8s-cluster.region
 availability_zone = "${var.region}a"
 nodes_count       = 2
 cpus              = 8
 ram_mb            = 16384
 volume_gb         = 15
 volume_type       = "fast.${var.region}a"
 labels            = {
   "project": "my",
 }
}

Vi lÀgger till en anvÀndare i projektet:

resource "random_password" "my-k8s-user-pass" {
 length = 16
 special = true
 override_special = "_%@"
}

resource "selectel_vpc_user_v2" "my-k8s-user" {
 password = random_password.my-k8s-user-pass.result
 name = var.username
 enabled  = true
}

resource "selectel_vpc_keypair_v2" "my-k8s-user-ssh" {
 public_key = file("~/.ssh/id_rsa.pub")
 user_id    = selectel_vpc_user_v2.my-k8s-user.id
 name = var.username
}

resource "selectel_vpc_role_v2" "my-k8s-role" {
 project_id = selectel_vpc_project_v2.my-k8s.id
 user_id    = selectel_vpc_user_v2.my-k8s-user.id
}

Utdata:

output "project_id" {
 value = selectel_vpc_project_v2.my-k8s.id
}

output "k8s_id" {
 value = selectel_mks_cluster_v1.k8s-cluster.id
}

output "user_name" {
 value = selectel_vpc_user_v2.my-k8s-user.name
}

output "user_pass" {
 value = selectel_vpc_user_v2.my-k8s-user.password
}

Vi startar:

$ env 
TF_VAR_region=ru-3 
TF_VAR_username=diamon 
TF_VAR_my_selectel_token= 
terraform plan -out planfile

$ terraform apply -input=false -auto-approve planfile

Kyckling eller Àgg: vi krossar IaC
Steg 3. Vi fÄr kubkonfigureringen.

För att programmÀssigt ladda ner KUBECONFIG, mÄste du fÄ en token frÄn OpenStack:

openstack token issue -c id -f value > token

Och med den hÀr tokenen gör du en förfrÄgan till Managed Kubernetes Selectel API. k8s_id utger terraform:

curl -XGET -H "x-auth-token: $(cat token)" "https://ru-3.mks.selcloud.ru/v1/clusters/$(cat k8s_id)/kubeconfig" -o kubeConfig.yaml

Kubkonfigurationen kan Àven fÄs via panelen.

Kyckling eller Àgg: vi krossar IaC
Steg 4. NÀr klustret har bakats och vi har Ätkomst till det kan vi lÀgga till yaml efter smak.

Jag föredrar att lÀgga till:

  • namespace,
  • storage class,
  • pod security policy och annat.

Storage Class för Selectel kan tas frÄn det officiella arkivet.

Eftersom jag ursprungligen valde en kluster i zonen ru-3a, sÄ behöver jag Àven en Storage Class frÄn den hÀr zonen.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
 name: fast.ru-3a
 annotations:
   storageclass.kubernetes.io/is-default-class: "true"
provisioner: cinder.csi.openstack.org
parameters:
 type: fast.ru-3a
 availability: ru-3a
allowVolumeExpansion: true

Steg 5. Vi installerar lastbalanseraren.

Vi kommer att anvÀnda den standard som mÄnga nginx-ingress. Det finns redan gott om instruktioner för installation, sÄ vi stannar inte vid det.

$ helm repo add nginx-stable https://helm.nginx.com/stable
$ helm upgrade nginx-ingress nginx-stable/nginx-ingress -n ingress --install -f ../internal/K8S-cluster/ingress/values.yml

Vi vÀntar pÄ att den ska fÄ extern IP-adress, cirka 3-4 minuter:

Kyckling eller Àgg: vi krossar IaC
Fick extern IP-adress:

Kyckling eller Àgg: vi krossar IaC
Steg 6. Vi installerar GitLab.

$ helm repo add gitlab https://charts.gitlab.io
$ helm upgrade gitlab gitlab/gitlab -n gitlab  --install -f gitlab/values.yml --set "global.hosts.domain=gitlab.$EXTERNAL_IP.nip.io"

Vi vÀntar igen pÄ att alla pods ska starta.

kubectl get po -n gitlab
NAME                                      	READY   STATUS  	RESTARTS   AGE
gitlab-gitaly-0                           	0/1 	Pending 	0      	0s
gitlab-gitlab-exporter-88f6cc8c4-fl52d    	0/1 	Pending 	0      	0s
gitlab-gitlab-runner-6b6867c5cf-hd9dp     	0/1 	Pending 	0      	0s
gitlab-gitlab-shell-55cb6ccdb-h5g8x       	0/1 	Init:0/2	0      	0s
gitlab-migrations.1-2cg6n                 	0/1 	Pending 	0      	0s
gitlab-minio-6dd7d96ddb-zd9j6             	0/1 	Pending 	0      	0s
gitlab-minio-create-buckets.1-bncdp       	0/1 	Pending 	0      	0s
gitlab-postgresql-0                       	0/2 	Pending 	0      	0s
gitlab-prometheus-server-6cfb57f575-v8k6j 	0/2 	Pending 	0      	0s
gitlab-redis-master-0                     	0/2 	Pending 	0      	0s
gitlab-registry-6bd77b4b8c-pb9v9          	0/1 	Pending 	0      	0s
gitlab-registry-6bd77b4b8c-zgb6r          	0/1 	Init:0/2	0      	0s
gitlab-shared-secrets.1-pc7-5jgq4         	0/1 	Completed   0      	20s
gitlab-sidekiq-all-in-1-v1-54dbcf7f5f-qbq67   0/1 	Pending 	0      	0s
gitlab-task-runner-6fd6857db7-9x567       	0/1 	Pending 	0      	0s
gitlab-webservice-d9d4fcff8-hp8wl         	0/2 	Pending 	0      	0s
Waiting gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
waiting for pod...
waiting for pod...
waiting for pod...

Pods har startat:

Kyckling eller Àgg: vi krossar IaC
Steg 7. Vi fÄr GitLab-token.

Först tar vi reda pÄ lösenordet för att logga in:

kubectl get secret -n gitlab gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 --decode

Nu loggar vi in och fÄr token:

python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.io

Steg 8. Vi organiserar Git-repositorier i rÀtt hierarki med GitLab Provider.

cd ../internal/gitlab/hierarchy && terraform apply -input=false -auto-approve planfile

TyvÀrr finns det en flytande bugg. DÄ mÄste vi ta bort konfliktande projekt manuellt för att reparera tf.state. NÀr det Àr klart, kör kommandot `$ make all` igen.

Steg 9. Vi flyttar lokala repositorier till servern.

$ make push

[master (root-commit) b61d977]  Första Ätagandet
 3 filer Àndrade, 46 insÀttningar(+)
 skapa lÀge 100644 .gitignore
 skapa lÀge 100644 values.yml
UpprÀkning av objekt: 5, klart.
Objekt rÀknas: 100% (5/5), klart.
Delta-komprimering med upp till 8 trÄdar
Komprimerar objekt: 100% (5/5), klart.
Skriver objekt: 100% (5/5), 770 byte | 770.00 KiB/s, klart.
Totalsumma 5 (delta 0), ÄteranvÀnt 0 (delta 0)

FĂ€rdigt:

Kyckling eller Àgg: vi krossar IaC
Kyckling eller Àgg: vi krossar IaC
Kyckling eller Àgg: vi krossar IaC

Slutsats

Vi har uppnÄtt att vi frÄn vÄr lokala maskin kan deklarativt hantera allt. Nu vill vi flytta alla dessa uppgifter till CI och bara trycka pÄ knapparna. För detta behöver vi överföra vÄra lokala tillstÄnd (Terraform state) till CI. Om hur man gör detta, i nÀsta del.

Prenumerera pÄ vÄr bloggen, för att inte missa nya artiklar!

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster