
Was war zuerst da â das Huhn oder das Ei? Ein ziemlich seltsamer Auftakt fĂŒr einen Artikel ĂŒber Infrastructure-as-Code, oder?
Was ist ein Ei?
Meistens ist Infrastructure-as-Code (IaC) eine deklarative Methode zur Darstellung von Infrastruktur. Hier beschreiben wir den Zustand, den wir erreichen möchten, beginnend bei der Hardware bis hin zur Softwarekonfiguration. Daher wird IaC verwendet fĂŒr:
- Ressourcenzuteilung. Das sind VMs, S3, VPC usw. Die Hauptwerkzeuge sind: und .
- . Die Hauptwerkzeuge: , Chef usw.
Jeder Code befindet sich in Git-Repositorys. Irgendwann wird der Teamleiter entscheiden, dass es Zeit ist, Ordnung in diese zu bringen. Er wird refaktorisieren. Und er wird eine bestimmte Struktur erstellen. Und er wird feststellen, dass das gut ist.
Es ist auch gut, dass es bereits einen und -Provider fĂŒr Terraform (und das ist Softwarekonfiguration) gibt. Mit deren Hilfe kann man das gesamte Projekt verwalten: Teammitglieder, CI/CD, Git-Flow usw.
Woher stammt das Ei?
Hier nÀhern wir uns allmÀhlich der zentralen Frage.
Zuerst sollte man mit dem Repository beginnen, das die Struktur anderer Repositories, einschlieĂlich sich selbst, beschreibt. Und natĂŒrlich muss man im Rahmen von GitOps CI hinzufĂŒgen, damit Ănderungen automatisch ausgefĂŒhrt werden.
Wenn Git noch nicht erstellt ist?
- Wie speichert man es in Git?
- Wie fĂŒgt man CI hinzu?
- Wenn wir GitLab auch mit IaC bereitstellen und zusÀtzlich in Kubernetes?
- Und GitLab Runner ebenfalls in Kubernetes?
- Und Kubernetes bei einem Cloud-Anbieter?
Was war zuerst: GitLab, in das ich meinen Code hochlade, oder der Code, der beschreibt, welcher GitLab fĂŒr mich benötigt wird?
Das Huhn mit Eiern
«3 mit einem Dinosaurier» []
Lass uns versuchen, ein Gericht zuzubereiten, indem wir als Cloud-Anbieter .
TL;DR
Kann man das nicht gleich in ein Team zusammenfassen?
$ export MY_SELECTEL_TOKEN=
$ curl https://gitlab.com/chicken-or-egg/mks/make/-/snippets/2002106/raw | bashZutaten:
- Ein Konto von my.selectel.ru;
- Token vom Konto;
- Kubernetes-Kenntnisse;
- Helm-Kenntnisse;
- Terraform-Kenntnisse;
- Helm-Chart GitLab;
- Helm-Chart GitLab Runner.
Rezept:
- Erhalte MY_SELECTEL_TOKEN ĂŒber das Dashboard my.selectel.ru.
- Erstelle einen Kubernetes-Cluster, indem du das Token von deinem Konto ĂŒbergibst.
- Erhalte KUBECONFIG vom erstellten Cluster.
- Installiere GitLab in Kubernetes.
- Erhalte ein GitLab-Token von dem erstellten GitLab fĂŒr den Benutzer. root.
- Erstelle eine Projektstruktur in GitLab mit dem GitLab-Token.
- Pushe den vorhandenen Code in GitLab.
- ???
- Gewinn!
Schritt 1. Das Token kann im Abschnitt .
Schritt 2. Bereiten wir unser Terraform fĂŒr das "Backen" eines Clusters mit 2 Knoten vor. Wenn du dir sicher bist, dass du genĂŒgend Ressourcen hast, kannst du Auto-Quotas 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",
}
}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
}Ausgaben:
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=
terraform plan -out planfile
$ terraform apply -input=false -auto-approve planfile 
Schritt 3. Wir erhalten die kubectl-Konfiguration.
Um KUBECONFIG programmgesteuert herunterzuladen, muss ein Token von OpenStack erhalten werden:
openstack token issue -c id -f value > tokenUnd mit diesem Token eine Anfrage an die Managed Kubernetes Selectel API machen. k8s_id gibt aus terraform:
curl -XGET -H "x-auth-token: $(cat token)" "https://ru-3.mks.selcloud.ru/v1/clusters/$(cat k8s_id)/kubeconfig" -o kubeConfig.yamlDie kubectl-Konfiguration kann auch ĂŒber das Dashboard abgerufen werden.

Schritt 4. Nachdem der Cluster eingerichtet wurde und wir Zugang dazu haben, können wir dazu passende YAML hinzufĂŒgen.
Ich bevorzuge es, hinzuzufĂŒgen:
- Namespace,
- Speicherklasse,
- Pod-Sicherheitsrichtlinie und weiteres.
fĂŒr Selectel kann aus .
Entnommen werden, da ich ursprĂŒnglich einen Cluster in der Zone ru-3a, gewĂ€hlt habe, benötige ich auch die Speicherklasse 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:
Typ: fast.ru-3a
VerfĂŒgbarkeit: ru-3a
AllowVolumeExpansion: trueSchritt 5. Wir stellen den Lastenausgleich ein.
Wir werden den Standard fĂŒr viele verwenden nginx-ingress. Es gibt bereits genĂŒgend Anleitungen zu seiner Installation, also werden wir an dieser Stelle nicht verweilen.
$ 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.ymlWir warten, bis er in etwa 3-4 Minuten eine externe IP erhÀlt:

Externe IP erhalten:

Schritt 6. Wir installieren 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"Warten wir erneut, bis alle Pods hochgefahren sind.
kubectl get po -n gitlab
NAME READY STATUS RESTARTS ALTER
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
Warten auf gitlab
./wait_gitlab.sh ../internal/gitlab/gitlab/.pods
Warten auf Pod...
Warten auf Pod...
Warten auf Pod...Pods gestartet:

Schritt 7. Wir erhalten das GitLab-Token.
Zuerst erfahren wir das Passwort fĂŒr den Login:
kubectl get secret -n gitlab gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 --decodeJetzt authentifizieren wir uns und erhalten das Token:
python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.ioSchritt 8. Wir bringen die Git-Repositories in die richtige Hierarchie mit dem Gitlab Provider.
cd ../internal/gitlab/hierarchy && terraform apply -input=false -auto-approve planfileLeider gibt es im Terraform GitLab Provider ein schwankendes . Dann mĂŒssen wir die konfliktbehafteten Projekte manuell löschen, damit der tf.state repariert wird. Starten Sie dann den Befehl `$ make all` erneut.
Schritt 9. Wir ĂŒbertragen die lokalen Repositories auf den Server.
$ make push
[master (root-commit) b61d977] Erster Commit
3 Dateien geĂ€ndert, 46 EinfĂŒgungen(+)
Erstelle Modus 100644 .gitignore
Erstelle Modus 100644 values.yml
ZĂ€hle Objekte: 5, erledigt.
ZĂ€hle Objekte: 100% (5/5), erledigt.
Delta-Kompression mit bis zu 8 Threads
Komprimieren von Objekten: 100% (5/5), erledigt.
Schreibe Objekte: 100% (5/5), 770 Bytes | 770.00 KiB/s, erledigt.
Insgesamt 5 (Delta 0), wiederverwendet 0 (Delta 0)Fertig:


Fazit
Wir haben es geschafft, dass wir von unserem lokalen Rechner aus alles deklarativ steuern können. Jetzt möchten wir all diese Aufgaben in die CI ĂŒbertragen und nur noch auf Knöpfe drĂŒcken. DafĂŒr mĂŒssen wir unsere lokalen ZustĂ€nde (Terraform-Zustand) in die CI ĂŒbergeben. Wie das funktioniert, erlĂ€utern wir im nĂ€chsten Abschnitt.
Abonnieren Sie unseren , um die Veröffentlichungen neuer Artikel nicht zu verpassen!
Quelle: habr.com
