Kylling eller æg: splittelse af IaC

Kylling eller æg: splittelse af IaC
Hvad kom først — kyllingen eller ægget? En ret underlig start på en artikel om Infrastructure-as-Code, er det ikke?

Hvad er et æg?

Ofte er Infrastructure-as-Code (IaC) en deklarativ metode til at repræsentere infrastrukturen. Her beskriver vi den tilstand, vi ønsker at opnå, lige fra hardware til softwarekonfiguration. Derfor bruges IaC til:

  1. Ressourceoprettelse. Det er VMs, S3, VPC osv. De vigtigste værktøjer til arbejdet: Terraform og CloudFormation.
  2. Softwarekonfiguration. De vigtigste værktøjer: Ansible, Chef osv.

Al kode ligger i git-repositorier. Og før eller senere vil teamlederen beslutte, at det er tid til at få orden i dem. Og han vil refaktorere. Og han vil skabe en struktur. Og han vil opdage, at det er en god ting.

Det er også godt, at der allerede eksisterer GitLab og GitHub- en provider til Terraform (og det er Softwarekonfiguration). Med dem kan man styre hele projektet: teammedlemmer, CI/CD, git-flow osv.

Hvor kom ægget fra?

Her nærmer vi os gradvist det centrale spørgsmål.

Først og fremmest skal man starte med et repository, der beskriver strukturen af de andre repositories, inklusive sig selv. Og selvfølgelig, inden for GitOps, skal man tilføje CI, så ændringer automatisk kan udføres.

Hvis Git endnu ikke er oprettet?

  1. Hvordan opbevares det i Git?
  2. Hvordan tilføjer man CI?
  3. Hvis vi også opsætter Gitlab ved hjælp af IaC, og ovenikøbet i Kubernetes?
  4. Og GitLab Runner også i Kubernetes?
  5. Og Kubernetes i en cloud-udbyder?

Hvad kom først: GitLab, hvortil jeg uploader min kode, eller koden, der beskriver, hvilken GitLab jeg har brug for?

Kyllingen med æggene

«Oyakodon3 med dinosauren» [src]

Lad os prøve at lave en ret, ved at bruge som cloud-udbyder Managed Kubernetes Selectel.

TL;DR

Kan vi gøre det i én kommando?

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

Ingredienser:

  • Konto fra my.selectel.ru;
  • Token fra kontoen;
  • Færdigheder i Kubernetes;
  • Færdigheder i Helm;
  • Færdigheder i Terraform;
  • Helm chart GitLab;
  • Helm chart GitLab Runner.

Opskrift:

  1. Få MY_SELECTEL_TOKEN fra panelet my.selectel.ru.
  2. Opret et Kubernetes-cluster ved at sende token fra kontoen.
  3. Få KUBECONFIG fra det oprettede cluster.
  4. Installer GitLab i Kubernetes.
  5. Få GitLab-token fra den oprettede GitLab for brugeren root.
  6. Opret projektstrukturen i GitLab ved hjælp af GitLab-token.
  7. Push den eksisterende kode til GitLab.
  8. ???
  9. Profit!

Trin 1. Token kan fås i sektionen API-nøgler.

Kylling eller æg: splittelse af IaCTrin 2. Forbered vores Terraform til "bagning" af clusteren med 2 noder. Hvis du er sikker på, at du har nok ressourcer til alt, kan du aktivere automatiske 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 tilføjer en bruger til 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
}

Output:

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 starter:

$ 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

Kylling eller æg: splittelse af IaC
Trin 3. Vi får kubekonfigurationen.

For at downloade KUBECONFIG programmatisk, skal vi have et token fra OpenStack:

openstack token issue -c id -f value > token

Og med dette token kan vi lave en forespørgsel til Selectel Managed Kubernetes API. k8s_id returnerer terraform:

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

Kubekonfigurationen kan også fås via panelet.

Kylling eller æg: splittelse af IaC
Trin 4. Når klyngen er oprettet, og vi har adgang til den, kan vi tilsætte yaml ovenpå, som vi ønsker.

Jeg foretrækker at tilsætte:

  • namespace,
  • storage class,
  • pod security policy og andet.

Storage Class for Selectel kan tages fra den officielle repository.

Da jeg oprindeligt valgte klyngen i zonen ru-3a, så har jeg også brug for Storage Class fra denne zone.

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

Trin 5. Vi sætter en belastningsbalancer.

Vi vil bruge standarden for mange nginx-ingress. Der er allerede mange instruktioner til installation, så vi vil ikke dvæle ved 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

Vent på, at den får en offentlig IP i cirka 3-4 minutter:

Kylling eller æg: splittelse af IaC
Vi har fået en offentlig IP:

Kylling eller æg: splittelse af IaC
Trin 6. Installerer 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"

Vent igen, indtil alle pods er oppe.

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
Venter på gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
venter på pod...
venter på pod...
venter på pod...

Pods er oppe:

Kylling eller æg: splittelse af IaC
Trin 7. Henter GitLab-token.

Først finder vi adgangskoden til login:

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

Nu logger vi ind og får token:

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

Trin 8. Organiserer Git-repositories til den rigtige hierarki med Gitlab Provider.

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

Desværre er der problemer med GitLab-provider i terraform fejl i projektet Chromium. Så skal vi slette konfliktende projekter manuelt for at reparere tf.state. Derefter genstart kommandoen `$ make all`

Trin 9. Overfører lokale repositories til serveren.

$ make push

[master (root-commit) b61d977]  Initial commit
 3 files changed, 46 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 values.yml
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 770 bytes | 770.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)

Færdig:

Kylling eller æg: splittelse af IaC
Kylling eller æg: splittelse af IaC
Kylling eller æg: splittelse af IaC

Konklusion

Vi har opnået, at vi fra vores lokale maskine kan administrere alt deklarativt. Nu vil vi gerne overføre alle disse opgaver til CI, så vi kun skal trykke på knapperne. For at gøre dette skal vi overføre vores lokale tilstande (Terraform state) til CI. Hvordan dette gøres, vil blive beskrevet i den næste del.

Tilmeld dig vores blog, så du ikke går glip af nye artikler!

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster