Kurča alebo vajce: rozbíjame IaC

Kurča alebo vajce: rozbíjame IaC
Čo bolo skôr — sliepka alebo vajce? Celkom zvláštny začiatok článku o Infrastructure-as-Code, nemyslíte?

Čo je to vajce?

Najčastejšie je Infrastructure-as-Code (IaC) deklaratívny spôsob predstavenia infraštruktúry. V ňom popisujeme stav, ktorý chceme dosiahnuť, od hardvérovej časti až po konfiguráciu softvéru. Preto sa IaC používa na:

  1. Provisioning zdrojov. Sú to VMs, S3, VPC atď. Hlavné nástroje na prácu: Terraform a CloudFormation.
  2. Konfigurácia softvéru. Hlavné nástroje: Ansible, Chef atď.

Akýkoľvek kód leží v git-repozitároch. A skôr či neskôr sa líder tímu rozhodne, že je potrebné urobiť poriadok v nich. A začne refaktorovať. A vytvorí určitú štruktúru. A uvidí, že to je dobré.

Takisto je dobré, že už existuje GitLab a GitHub-provider pre Terraform (a toto je Konfigurácia softvéru). S ich pomocou môžeme riadiť celý projekt: členov tímu, CI/CD, git-flow atď.

Odkiaľ sa vzalo vajce?

A tu sa postupne dostávame k hlavnej otázke.

Predovšetkým treba začať s repozitárom, ktorý popisuje štruktúru iných repozitárov, vrátane seba samého. A samozrejme, v rámci GitOps je potrebné pridať CI, aby sa zmeny automaticky vykonávali.

Čo ak Git ešte neexistuje?

  1. Ako ho uložiť do Gitu?
  2. Ako pripojiť CI?
  3. Ak aj GitLab rozvíjame pomocou IaC, a to ešte aj v Kubernetes?
  4. A GitLab Runner tiež v Kubernetes?
  5. A Kubernetes v cloudovom provideri?

Čo bolo skôr: GitLab, do ktorého nahrám svoj kód, alebo kód, ktorý popisuje, aký GitLab potrebujem?

Sliepka s vajcami

«Oyakodon3 s dinosaurem» [src]

Skúsime pripraviť jedlo s použitím ako cloudového providera Managed Kubernetes Selectel.

TL;DR

Ale môže to byť hneď v jednej príkazovej línii?

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

Ingrediencie:

  • Účet z my.selectel.ru;
  • Token z účtu;
  • Zručnosti v Kubernetes;
  • Zručnosti v Helme;
  • Zručnosti v Terrasform;
  • Helm graf GitLab;
  • Helm graf GitLab Runner.

Recept:

  1. Získať MY_SELECTEL_TOKEN z panela my.selectel.ru.
  2. Vytvoriť klastry Kubernetes, pričom mu poskytneme token z účtu.
  3. Získať KUBECONFIG z vytvoreného klastra.
  4. Nainštalovať GitLab v Kubernetes.
  5. Získať GitLab-token z vytvoreného GitLab pre používateľa root.
  6. Vytvoriť štruktúru projektov v GitLab používajúc GitLab-token.
  7. Nahráť existujúci kód do GitLab.
  8. ???
  9. Zisk!

Krok 1. Token si môžete získať v sekcii API kľúče.

Kurča alebo vajce: rozbíjame IaCKrok 2. Pripravujeme náš Terraform na "piekarní" klaster zo 2 uzlov. Ak ste si istí, že máte dostatok zdrojov, môžete zapnúť automatické kvóty:

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",
 }
}

Pridávame používateľa do projektu:

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
}

Výstupné dáta:

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
}

Spúšťame:

$ 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

Kurča alebo vajce: rozbíjame IaC
Krok 3. Získavame kubekonfig.

Aby sme mohli programovo stiahnuť KUBECONFIG, je potrebné získať token od OpenStack:

openstack token issue -c id -f value > token

A s týmto tokenom vykonať požiadavku na Managed Kubernetes Selectel API. k8s_id vracia terraform:

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

Kubekonfig môžeme získať aj cez panel.

Kurča alebo vajce: rozbíjame IaC
Krok 4. Potom, čo sa klaster inicializoval a máme k nemu prístup, môžeme pridať yaml podľa chuti.

Preferujem pridávať:

  • namespace,
  • storage class,
  • pod security policy a iné.

Trieda úložiska pre Selectel môžeme brať z oficiálneho repozitára.

Keďže som pôvodne zvolil klaster v zóne ru-3a, tak aj Storage Class potrebujem z tejto zóny.

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

Krok 5. Nainštalujeme vyvažovač zaťaženia.

Použijeme štandardný pre mnohých nginx-ingress. Pokynov na jeho inštaláciu je už dostatok, takže sa na tom nebudeme zdržiavať.

$ 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

Čakáme, kým získa externú IP, približne 3-4 minúty:

Kurča alebo vajce: rozbíjame IaC
Získali sme externú IP:

Kurča alebo vajce: rozbíjame IaC
Krok 6. Inštalujeme 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"

Opäť čakáme, kým sa všetky pody spustia.

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
Čakáme na gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
čakanie na pod...
čakanie na pod...
čakanie na pod...

Pody sa spustili:

Kurča alebo vajce: rozbíjame IaC
Krok 7. Získavame GitLab-token.

Najprv zistíme heslo na prihlásenie:

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

Teraz sa autentifikujeme a získame token:

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

Krok 8. Usporiadame Git-repozitáre do správnej hierarchie pomocou Gitlab Provider.

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

Žiaľ, v terraform GitLab provider je plávajúci bug. Potom bude potrebné ručne odstrániť konfliktné projekty, aby sa tf.state opravilo. Následne spustite príkaz `$ make all`

Krok 9. Prenášame lokálne repozitáre na server.

$ make push

[master (root-commit) b61d977]  Počiatočný commit
 3 súbory sa zmenilo, 46 vkladov(+)
 vytvorenie režimu 100644 .gitignore
 vytvorenie režimu 100644 values.yml
Enumerovanie objektov: 5, hotovo.
Počítanie objektov: 100% (5/5), hotovo.
Delta kompresia pomocou najviac 8 vlákien
Kompresia objektov: 100% (5/5), hotovo.
Písanie objektov: 100% (5/5), 770 bajtov | 770.00 KiB/s, hotovo.
Celkovo 5 (delta 0), opakované 0 (delta 0)

Hotovo:

Kurča alebo vajce: rozbíjame IaC
Kurča alebo vajce: rozbíjame IaC
Kurča alebo vajce: rozbíjame IaC

Záver

Podarilo sa nám, že na našom lokálnom stroji môžeme deklaratívne spravovať všetko. Teraz chceme presunúť všetky tieto úlohy do CI a iba stlačiť tlačidlá. Na to je potrebné preniesť naše lokálne stavy (Terraform state) do CI. O tom, ako to urobiť, v nasledujúcej časti.

Prihláste sa na náš blog, aby vám nič neuniklo z nových článkov!

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster