
Vad kom först â kycklingen eller Ă€gget? En ganska mĂ€rklig början pĂ„ en artikel om Infrastructure-as-Code, eller hur?
Vad Àr ett Àgg?
I de flesta fall Àr Infrastructure-as-Code (IaC) ett deklarativt sÀtt att representera infrastruktur. Vi beskriver det tillstÄnd vi vill uppnÄ, frÄn hÄrdvarudelen till mjukvarukonfigurationen. DÀrför anvÀnds IaC för:
- Resursbereddning. Det handlar om VMs, S3, VPC osv. De viktigaste verktygen att anvÀnda Àr: och .
- . De viktigaste verktygen: , Chef, etc.
All kod finns i git-repositorier. Och förr eller senare kommer teamledaren att besluta att det behövs stÀdning i dem. Och dÄ kommer han att refaktorera. Och han kommer att skapa en viss struktur. Och han kommer att se att detta Àr bra.
Det Àr ocksÄ bra att det redan finns och -en leverantör för Terraform (och detta Àr programvarukonfiguration). Med deras hjÀlp kan man hantera hela projektet: teammedlemmar, CI/CD, git-flow osv.
Var kom Àgget ifrÄn?
HÀr kommer vi gradvis till den stora frÄgan.
Först och frÀmst mÄste man börja med det repository som beskriver strukturen av andra repositories, inklusive sig sjÀlv. Och givetvis, inom ramen för GitOps, mÄste man lÀgga till CI sÄ att förÀndringar automatiskt genomförs.
Om Git Ànnu inte Àr skapat?
- Hur ska man lagra det i Git?
- Hur ska man ansluta CI?
- Om vi ocksÄ implementerar GitLab med hjÀlp av IaC, och dessutom i Kubernetes?
- Och GitLab Runner ocksÄ i Kubernetes?
- Och Kubernetes hos en molnleverantör?
Vad kom först: GitLab, dÀr jag ska ladda upp min kod, eller koden som beskriver vilken GitLab jag behöver?
Kyckling med Àgg
«3 med dinosaurien» []
LÄt oss försöka laga en rÀtt som anvÀnder som molnleverantör .
TL;DR
Kan vi fÄ allt i ett kommando?
$ export MY_SELECTEL_TOKEN=
$ curl https://gitlab.com/chicken-or-egg/mks/make/-/snippets/2002106/raw | bashIngredienser:
- Ett konto frÄn my.selectel.ru;
- Token frÄn kontot;
- Kubernetes fÀrdigheter;
- Helm fÀrdigheter;
- Terraform fÀrdigheter;
- Helm chart för GitLab;
- Helm chart för GitLab Runner.
Recept:
- FÄ MY_SELECTEL_TOKEN frÄn panelen my.selectel.ru.
- Skapa en Kubernetes-kluster och överföra token frÄn kontot.
- FÄ KUBECONFIG frÄn den skapade klustret.
- Installera GitLab i Kubernetes.
- FÄ GitLab-token frÄn den skapade GitLab för anvÀndaren. root.
- Skapa projektstrukturen i GitLab med hjÀlp av GitLab-token.
- Pusha existerande kod till GitLab.
- ???
- Vinst!
Steg 1. Token kan erhÄllas i avsnittet .
Steg 2Vi förbereder vÄr Terraform för att "baka" en kluster av 2 noder. Om du Àr sÀker pÄ att du har tillrÀckligt med resurser kan du aktivera auto-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 lÀgger till en anvÀndare i 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
}Utdata:
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 startar:
$ 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 
Steg 3. Vi fÄr kubkonfigureringen.
För att programmÀssigt ladda ner KUBECONFIG, mÄste du fÄ en token frÄn OpenStack:
openstack token issue -c id -f value > tokenOch med den hÀr tokenen gör du en förfrÄgan till Managed Kubernetes Selectel API. k8s_id utger terraform:
curl -XGET -H "x-auth-token: $(cat token)" "https://ru-3.mks.selcloud.ru/v1/clusters/$(cat k8s_id)/kubeconfig" -o kubeConfig.yamlKubkonfigurationen kan Àven fÄs via panelen.

Steg 4. NÀr klustret har bakats och vi har Ätkomst till det kan vi lÀgga till yaml efter smak.
Jag föredrar att lÀgga till:
- namespace,
- storage class,
- pod security policy och annat.
för Selectel kan tas frÄn .
Eftersom jag ursprungligen valde en kluster i zonen ru-3a, sÄ behöver jag Àven en Storage Class frÄn den hÀr zonen.
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: trueSteg 5. Vi installerar lastbalanseraren.
Vi kommer att anvÀnda den standard som mÄnga nginx-ingress. Det finns redan gott om instruktioner för installation, sÄ vi stannar inte vid 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.ymlVi vÀntar pÄ att den ska fÄ extern IP-adress, cirka 3-4 minuter:

Fick extern IP-adress:

Steg 6. Vi installerar 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"Vi vÀntar igen pÄ att alla pods ska starta.
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...Pods har startat:

Steg 7. Vi fÄr GitLab-token.
Först tar vi reda pÄ lösenordet för att logga in:
kubectl get secret -n gitlab gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 --decodeNu loggar vi in och fÄr token:
python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.ioSteg 8. Vi organiserar Git-repositorier i rÀtt hierarki med GitLab Provider.
cd ../internal/gitlab/hierarchy && terraform apply -input=false -auto-approve planfileTyvÀrr finns det en flytande . DÄ mÄste vi ta bort konfliktande projekt manuellt för att reparera tf.state. NÀr det Àr klart, kör kommandot `$ make all` igen.
Steg 9. Vi flyttar lokala repositorier till servern.
$ make push
[master (root-commit) b61d977] Första Ätagandet
3 filer Àndrade, 46 insÀttningar(+)
skapa lÀge 100644 .gitignore
skapa lÀge 100644 values.yml
UpprÀkning av objekt: 5, klart.
Objekt rÀknas: 100% (5/5), klart.
Delta-komprimering med upp till 8 trÄdar
Komprimerar objekt: 100% (5/5), klart.
Skriver objekt: 100% (5/5), 770 byte | 770.00 KiB/s, klart.
Totalsumma 5 (delta 0), ÄteranvÀnt 0 (delta 0)FÀrdigt:


Slutsats
Vi har uppnÄtt att vi frÄn vÄr lokala maskin kan deklarativt hantera allt. Nu vill vi flytta alla dessa uppgifter till CI och bara trycka pÄ knapparna. För detta behöver vi överföra vÄra lokala tillstÄnd (Terraform state) till CI. Om hur man gör detta, i nÀsta del.
Prenumerera pÄ vÄr , för att inte missa nya artiklar!
KĂ€lla: habr.com
