Kip of ei: we hacken IaC

Kip of ei: we hacken IaC
Wat kwam eerst - de kip of het ei? Een behoorlijk vreemde manier om een artikel over Infrastructure-as-Code te beginnen, nietwaar?

Wat is een ei?

Infrastructure-as-Code (IaC) is vaak een declaratieve manier om infrastructuur weer te geven. We beschrijven de staat die we willen bereiken, van de hardware tot de softwareconfiguratie. Daarom wordt IaC gebruikt voor:

  1. Resource Provision. Dit zijn VMs, S3, VPC, enzovoorts. De belangrijkste tools om mee te werken zijn: Terraform en CloudFormation.
  2. Softwareconfiguratie. Belangrijke tools zijn: Ansible, Chef, enzovoorts.

Elke code ligt in git-repositories. En vroeg of laat zal de teamleider besluiten dat er orde in moet worden gemaakt. En hij zal refactoren. En hij zal een bepaalde structuur creƫren. En hij zal zien dat dit goed is.

Het is ook goed dat er al een GitLab en GitHub-provider voor Terraform bestaat (en dit is Softwareconfiguratie). Hiermee kun je het hele project beheren: teamleden, CI/CD, git-flow, enzovoorts.

Waar kwam het ei vandaan?

Zo komen we geleidelijk aan de belangrijkste vraag.

We moeten eerst beginnen met de repository die de structuur van andere repositories beschrijft, inclusief die van zichzelf. En natuurlijk moet er binnen GitOps CI worden toegevoegd, zodat wijzigingen automatisch worden uitgevoerd.

Als Git nog niet is aangemaakt?

  1. Hoe sla je het op in Git?
  2. Hoe sluit je CI aan?
  3. Als we GitLab ook met IaC implementeren, en nog in Kubernetes ook?
  4. En GitLab Runner ook in Kubernetes?
  5. En Kubernetes bij een cloudprovider?

Wat kwam er eerst: GitLab, waar ik mijn code naartoe upload, of de code die beschrijft welke GitLab ik nodig heb?

Kip met eieren

«Oyakodon3 met een dinosaurus» [src]

Laten we proberen een gerecht te bereiden met als cloudprovider Managed Kubernetes Selectel.

TL;DR

Is het mogelijk om dit allemaal in ƩƩn commando te doen?

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

Ingrediƫnten:

  • Account van my.selectel.ru;
  • Token van het account;
  • Kennis van Kubernetes;
  • Kennis van Helm;
  • Kennis van Terraform;
  • Helm chart GitLab;
  • Helm chart GitLab Runner.

Recept:

  1. Verkrijg MY_SELECTEL_TOKEN uit het dashboard. my.selectel.ru.
  2. Maak een Kubernetes-cluster aan door het token van het account door te geven.
  3. Verkrijg KUBECONFIG van het aangemaakte cluster.
  4. Installeer GitLab in Kubernetes.
  5. Verkrijg GitLab-token van de aangemaakte GitLab voor de gebruiker. root.
  6. Creƫer de projectstructuur in GitLab met behulp van het GitLab-token.
  7. Push de bestaande code naar GitLab.
  8. ???
  9. Winst!

Stap 1. Het token kan worden verkregen in de sectie API-sleutels.

Kip of ei: we hacken IaCStap 2. Bereid onze Terraform voor om een cluster van 2 knooppunten te "bakken". Als je er zeker van bent dat je genoeg middelen voor alles hebt, kun je automatische quota inschakelen:

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

Toevoegen van een gebruiker aan het project:

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
}

Uitvoer:

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
}

Laten we starten:

$ 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

Kip of ei: we hacken IaC
Stap 3. We verkrijgen kubconfig.

Om KUBECONFIG programmatisch te downloaden, moet je een token van OpenStack krijgen:

openstack token issue -c id -f value > token

En met dit token een aanvraag indienen bij de Managed Kubernetes Selectel API. k8s_id geeft terug terraform:

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

Kubconfig kan ook via het paneel worden verkregen.

Kip of ei: we hacken IaC
Stap 4. Nadat de cluster is gebakken en we er toegang toe hebben, kunnen we YAML naar smaak bovenop toevoegen.

Ik geef er de voorkeur aan om toe te voegen:

  • namespace,
  • opslagklasse,
  • pod beveiligingsbeleid en meer.

Opslagklasse Voor Selectel kan ik halen uit de officiƫle repository.

Aangezien ik aanvankelijk een cluster in de zone ru-3a, moet mijn opslagklasse uit deze zone komen.

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

Stap 5. We plaatsen de load balancer.

We gaan de standaard gebruiken voor velen nginx-ingress. Er zijn al veel instructies voor de installatie, dus laten we daar niet te veel bij stilstaan.

$ 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

We wachten totdat hij een extern IP ontvangt, ongeveer 3-4 minuten:

Kip of ei: we hacken IaC
Extern IP ontvangen:

Kip of ei: we hacken IaC
Stap 6. We installeren 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"

We wachten opnieuw totdat alle pods zijn opgestart.

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
Wachtend op gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
wachten op pod...
wachten op pod...
wachten op pod...

De pods zijn opgestart:

Kip of ei: we hacken IaC
Stap 7. We ontvangen de GitLab-token.

Laten we eerst het wachtwoord voor inloggen verkrijgen:

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

We authentiseren nu en krijgen de token:

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

Stap 8. Breng de Git-repositories in de juiste hiƫrarchie met behulp van de GitLab Provider.

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

Helaas is er een zwevende in de terraform GitLab provider bug. Dan zullen we de conflicterende projecten handmatig moeten verwijderen zodat tf.state hersteld kan worden. Start vervolgens de opdracht `$ make all` opnieuw.

Stap 9. We verplaatsen lokale repositories naar de server.

$ 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)

Klaar:

Kip of ei: we hacken IaC
Kip of ei: we hacken IaC
Kip of ei: we hacken IaC

Conclusie

We have achieved the ability to declaratively manage everything from our local machine. Now we want to move all these tasks to CI and just press the buttons. To do this, we need to transfer our local states (Terraform state) to CI. How to do this will be covered in the next part.

Subscribe to our blog, so you don’t miss the release of new articles!

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster