
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:
- Resource Provision. Dit zijn VMs, S3, VPC, enzovoorts. De belangrijkste tools om mee te werken zijn: en .
- . Belangrijke tools zijn: , 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 en -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?
- Hoe sla je het op in Git?
- Hoe sluit je CI aan?
- Als we GitLab ook met IaC implementeren, en nog in Kubernetes ook?
- En GitLab Runner ook in Kubernetes?
- 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
«3 met een dinosaurus» []
Laten we proberen een gerecht te bereiden met als cloudprovider .
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 | bashIngrediƫ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:
- Verkrijg MY_SELECTEL_TOKEN uit het dashboard. my.selectel.ru.
- Maak een Kubernetes-cluster aan door het token van het account door te geven.
- Verkrijg KUBECONFIG van het aangemaakte cluster.
- Installeer GitLab in Kubernetes.
- Verkrijg GitLab-token van de aangemaakte GitLab voor de gebruiker. root.
- Creƫer de projectstructuur in GitLab met behulp van het GitLab-token.
- Push de bestaande code naar GitLab.
- ???
- Winst!
Stap 1. Het token kan worden verkregen in de sectie .
Stap 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 
Stap 3. We verkrijgen kubconfig.
Om KUBECONFIG programmatisch te downloaden, moet je een token van OpenStack krijgen:
openstack token issue -c id -f value > tokenEn 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.yamlKubconfig kan ook via het paneel worden verkregen.

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.
Voor Selectel kan ik halen uit .
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: trueStap 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.ymlWe wachten totdat hij een extern IP ontvangt, ongeveer 3-4 minuten:

Extern IP ontvangen:

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:

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 --decodeWe authentiseren nu en krijgen de token:
python3 get_gitlab_token.py root $GITLAB_PASSWORD http://gitlab.gitlab.$EXTERNAL_IP.nip.ioStap 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 planfileHelaas is er een zwevende in de terraform GitLab provider . 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:


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 , so you donāt miss the release of new articles!
Bron: habr.com
