Huhn oder Ei: Cracking IaC

Huhn oder Ei: Cracking IaC
Was war zuerst da, das Huhn oder das Ei? Ziemlich seltsamer Anfang für einen Artikel über Infrastructure-as-Code, nicht wahr?

Was ist ein Ei?

In den meisten Fällen handelt es sich bei Infrastructure-as-Code (IaC) um eine deklarative Methode zur Darstellung der Infrastruktur. Darin beschreiben wir den Zustand, den wir erreichen wollen, angefangen beim Hardwareteil bis hin zur Softwarekonfiguration. Daher wird IaC verwendet für:

  1. Ressourcenbereitstellung. Dies sind VMs, S3, VPCs usw. Grundlegende Werkzeuge für die Arbeit: Terraform и Wolkenbildung.
  2. Software-Konfiguration. Hauptwerkzeuge: Ansible, Koch usw.

Jeder Code befindet sich in Git-Repositorys. Und früher oder später entscheidet der Teamleiter, dass es notwendig wäre, die Dinge in Ordnung zu bringen. Und er wird umgestalten. Und etwas Struktur schaffen. Und er wird sehen, dass es gut ist.

Gut ist auch, dass es das schon gibt Gitlab и GitHub-Anbieter für Terraform (und das ist Softwarekonfiguration). Mit ihrer Hilfe können Sie das gesamte Projekt verwalten: Teammitglieder, CI/CD, Git-Flow usw.

Woher kam das Ei?

Hier nähern wir uns allmählich der Hauptfrage.

Zunächst müssen Sie mit einem Repository beginnen, das die Struktur anderer Repositorys, einschließlich Ihres eigenen, beschreibt. Und natürlich müssen Sie innerhalb von GitOps CI hinzufügen, damit Änderungen automatisch implementiert werden.

Ist Git noch nicht erstellt?

  1. Wie speichere ich es in Git?
  2. Wie CI vermasseln?
  3. Wenn wir Gitlab auch mit IaC und sogar in Kubernetes bereitstellen?
  4. Und GitLab Runner auch in Kubernetes?
  5. Und Kubernetes bei einem Cloud-Anbieter?

Was war zuerst da: GitLab, wo ich meinen Code hochladen werde, oder Code, der beschreibt, welche Art von GitLab ich brauche?

Huhn mit Eiern

«Oyakodon3 mit Dinosaurier" [src]

Versuchen wir, ein Gericht mit einem Cloud-Anbieter zuzubereiten Verwalteter Kubernetes-Selektor.

TL; DR

Ist es möglich, sofort und in einem Team?

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

Zutaten:

  • Konto von my.selectel.ru;
  • Token vom Konto;
  • Kubernetes-Kenntnisse;
  • Helmfähigkeiten;
  • Terraform-Fähigkeiten;
  • Helmdiagramm GitLab;
  • Helmdiagramm GitLab Runner.

Rezept:

  1. Holen Sie sich MY_SELECTEL_TOKEN vom Panel my.selectel.ru.
  2. Erstellen Sie einen Kubernetes-Cluster, indem Sie das Token vom Konto an ihn übergeben.
  3. Holen Sie sich KUBECONFIG aus dem erstellten Cluster.
  4. Installieren Sie GitLab in Kubernetes.
  5. Holen Sie sich das für den Benutzer generierte GitLab-Token von GitLab Wurzel.
  6. Erstellen Sie eine Projektstruktur in GitLab mit dem GitLab-Token.
  7. Vorhandenen Code an GitLab übertragen.
  8. ???
  9. Gewinn!

Schritt 1. Der Token ist im Abschnitt erhältlich API-Schlüssel.

Huhn oder Ei: Cracking IaCSchritt 2. Wir bereiten unser Terraform für das „Backen“ eines Clusters aus 2 Knoten vor. Wenn Sie sicher sind, dass Sie über genügend Ressourcen für alle verfügen, können Sie automatische Kontingente aktivieren:

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

Einen Benutzer zum Projekt hinzufügen:

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
}

Ausgabe:

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
}

Wir starten:

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

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

Huhn oder Ei: Cracking IaC
Schritt 3. Wir erhalten die Cubeconfig.

Um KUBECONFIG programmgesteuert herunterzuladen, benötigen Sie ein Token von OpenStack:

openstack token issue -c id -f value > token

Stellen Sie mit diesem Token eine Anfrage an die Managed Kubernetes Selectel API. k8s_id Fragen Terraform:

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

Auf die Cubeconfig kann auch über das Panel zugegriffen werden.

Huhn oder Ei: Cracking IaC
Schritt 4. Nachdem der Cluster gebacken ist und wir Zugriff darauf haben, können wir nach Belieben Yaml darüber geben.

Ich füge lieber hinzu:

  • Namensraum,
  • Speicherklasse,
  • Pod-Sicherheitsrichtlinie und mehr.

Speicherklasse für Selectel kann entnommen werden offizielles Repository.

Da ich mich zunächst für einen Cluster in der Zone entschieden habe de-3a, dann benötige ich auch die Storage-Klasse aus dieser 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

Schritt 5. Installieren Sie einen Load Balancer.

Wir werden den Standard für viele verwenden Nginx-Ingress. Anleitungen zur Installation liegen bereits reichlich vor, daher gehen wir nicht näher darauf ein.

$ 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

Wir warten etwa 3-4 Minuten darauf, dass es eine externe IP erhält:

Huhn oder Ei: Cracking IaC
Holen Sie sich eine externe IP:

Huhn oder Ei: Cracking IaC
Schritt 6. Installieren Sie 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"

Wieder warten wir darauf, dass alle Schoten aufgehen.

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...

Die Schoten sind aufgegangen:

Huhn oder Ei: Cracking IaC
Schritt 7. Wir bekommen einen GitLab-Token.

Finden Sie zunächst das einzugebende Passwort heraus:

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

Jetzt loggen wir uns ein und holen uns ein Token:

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

Schritt 8. Wir bringen die Git-Repositories mithilfe des Gitlab-Providers in die richtige Hierarchie.

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

Leider verfügt der Terraform-GitLab-Anbieter über ein Floating ein Fehler. Anschließend müssen Sie die in Konflikt stehenden Projekte manuell löschen, damit tf.state behoben werden kann. Führen Sie dann den Befehl „$ make all“ erneut aus

Schritt 9. Wir übertragen lokale Repositories auf den 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)

Erledigt:

Huhn oder Ei: Cracking IaC
Huhn oder Ei: Cracking IaC
Huhn oder Ei: Cracking IaC

Abschluss

Wir haben erreicht, dass wir alles deklarativ von unserem lokalen Rechner aus verwalten können. Jetzt möchte ich all diese Aufgaben auf CI übertragen und nur noch Knöpfe drücken. Dazu müssen wir unsere lokalen Zustände (Terraform-Zustand) nach CI übertragen. Wie das geht, erfahren Sie im nächsten Teil.

Abonnieren Sie unseren Blogum die Veröffentlichung neuer Artikel nicht zu verpassen!

Source: habr.com

Kommentar hinzufügen