
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:
- Ressourceoprettelse. Det er VMs, S3, VPC osv. De vigtigste værktøjer til arbejdet: og .
- . De vigtigste værktøjer: , 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 og - 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?
- Hvordan opbevares det i Git?
- Hvordan tilføjer man CI?
- Hvis vi også opsætter Gitlab ved hjælp af IaC, og ovenikøbet i Kubernetes?
- Og GitLab Runner også i Kubernetes?
- 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
«3 med dinosauren» []
Lad os prøve at lave en ret, ved at bruge som cloud-udbyder .
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 | bashIngredienser:
- 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:
- Få MY_SELECTEL_TOKEN fra panelet my.selectel.ru.
- Opret et Kubernetes-cluster ved at sende token fra kontoen.
- Få KUBECONFIG fra det oprettede cluster.
- Installer GitLab i Kubernetes.
- Få GitLab-token fra den oprettede GitLab for brugeren root.
- Opret projektstrukturen i GitLab ved hjælp af GitLab-token.
- Push den eksisterende kode til GitLab.
- ???
- Profit!
Trin 1. Token kan fås i sektionen .
Trin 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 
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 > tokenOg 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.yamlKubekonfigurationen kan også fås via panelet.

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.
for Selectel kan tages fra .
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: trueTrin 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.ymlVent på, at den får en offentlig IP i cirka 3-4 minutter:

Vi har fået en offentlig IP:

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:

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 --decodeNu logger vi ind og får token:
python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.ioTrin 8. Organiserer Git-repositories til den rigtige hierarki med Gitlab Provider.
cd ../internal/gitlab/hierarchy && terraform apply -input=false -auto-approve planfileDesværre er der problemer med GitLab-provider i terraform . 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:


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 , så du ikke går glip af nye artikler!
Kilde: habr.com
